寻找函数的最小值?
Finding the minimum of a 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)))
它输出一个罐子的最小表面积可以容纳 350ml,我的问题是:
我能找到
中使用的 r 值吗
min(cokeArea(350,r))
我需要它来输出罐子在最小表面积处的半径。
谢谢
:)
一个接近最优的解决方案是
r[np.argmin(cokeArea(350, r))]
取决于您 r
的间隔分辨率。
@王涵的回答太棒了。它快速且易于理解,但我只是想对其进行量化并提供更多答案。
这是 Han 的回答在计时时的输出。
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)
由于您只对确定半径感兴趣,因此可以使用 Scipy 的称为最小化标量的函数。这种方法是有界的,因为如果我让它不受限制,它会给我除以零的答案。
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)
这种方法显然要慢得多,但它确实提供了一些优势,它应该更准确,根据您对精度的要求,这可能很重要。
因为你确实有这些边界,你可以使用 minimize_scalar
中的有界函数这会快一点,但正如你所看到的,是否仍然比 Han 的答案落后一个数量级。
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)
最后,如果您出于任何原因要 运行 包含体积和 r 的多变量优化,您可以使用 Scipy 的 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)
虽然这是最慢的,但如前所述,您可以尝试找到一个函数的多个变量的最小值。例如,一罐可乐的成本,包括材料、形状等。
我有这个功能:
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)))
它输出一个罐子的最小表面积可以容纳 350ml,我的问题是: 我能找到
中使用的 r 值吗min(cokeArea(350,r))
我需要它来输出罐子在最小表面积处的半径。 谢谢 :)
一个接近最优的解决方案是
r[np.argmin(cokeArea(350, r))]
取决于您 r
的间隔分辨率。
@王涵的回答太棒了。它快速且易于理解,但我只是想对其进行量化并提供更多答案。
这是 Han 的回答在计时时的输出。
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)
由于您只对确定半径感兴趣,因此可以使用 Scipy 的称为最小化标量的函数。这种方法是有界的,因为如果我让它不受限制,它会给我除以零的答案。
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)
这种方法显然要慢得多,但它确实提供了一些优势,它应该更准确,根据您对精度的要求,这可能很重要。
因为你确实有这些边界,你可以使用 minimize_scalar
中的有界函数这会快一点,但正如你所看到的,是否仍然比 Han 的答案落后一个数量级。
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)
最后,如果您出于任何原因要 运行 包含体积和 r 的多变量优化,您可以使用 Scipy 的 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)
虽然这是最慢的,但如前所述,您可以尝试找到一个函数的多个变量的最小值。例如,一罐可乐的成本,包括材料、形状等。