Reputation: 75
I have this function:
import numpy as np ### imports numpy
import matplotlib.pyplot as plt ### imports plotting
def cokeArea(Volume, radius):
Area = 2 * (Volume / radius + np.pi * np.power(radius,2)) ### re-arranged formula
return Area
r = np.linspace(1,15,100)
plt.plot(r,cokeArea(350,r))
print("The optimal Solution is:")
print("Area:", min(cokeArea(350,r)))
It outputs the minimum surface area of a can give it holds 350ml, my question is: can I find the r value which is used in
min(cokeArea(350,r))
I need it to output the radius of the can at the minimum surface area. Thank you :)
Upvotes: 2
Views: 1053
Reputation: 127
@Han Wang's answer is amazing. It's fast and easy to understand, but I just wanted to quantify it and offer a few more answers.
Here's Han's answer's output when timed.
r = np.linspace(1,15,100)
%timeit r[np.argmin(cokeArea(350,r))]
6.56 µs ± 106 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Since you're only interested in determining the radius, you can use Scipy's function called minimize scalar. This method is bounded because if I leave it unbounded it gives me a divide by zero answer.
from scipy import optimize
def cokeArea(radius):
Volume = 350
Area = 2 * (Volume / radius + np.pi * np.power(radius,2)) ### re-arranged formula
return Area
%timeit result = optimize.minimize_scalar(cokeArea, bracket=(1, 15), method = "brent")
543 µs ± 22.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
This method is clearly significantly slower, but it does offer some advantages, it should be more accurate, which might be important based on your requirement for precision.
Since you do have these bounds, you can use the bounded function in minimize_scalar
This is a bit faster, but as you can see if still an order of magnitude behind Han's answer.
from scipy import optimize
def cokeArea(radius):
Volume = 350
Area = 2 * (Volume / radius + np.pi * np.power(radius,2)) ### re-arranged formula
return Area
%timeit result = optimize.minimize_scalar(cokeArea, bounds=(1, 15), method = "bounded")
259 µs ± 13.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Lastly in case you would run a multivariable optimization which would include volume and r for any reason, you can use Scipy's fmin
.
from scipy import optimize
def cokeArea(radius):
Volume = 350
Area = 2 * (Volume / radius + np.pi * np.power(radius,2)) ### re-arranged formula
return Area
%timeit result = optimize.fmin(cokeArea, 1,disp=False)
718 µs ± 11.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
While this is the slowest, as previously mentioned you can try to find the minima of multiple variables for a function. For example the cost of can of coke including the materials, shape, and such.
Upvotes: 0
Reputation: 162
One close-to-optimal solution is
r[np.argmin(cokeArea(350, r))]
depends on you interval resolution of r
.
Upvotes: 4