我想找到一个函数f(x)的局部最大值,其中x可以在两个固定值之间,因为如果x趋向+ inf,f(x)将倾向于+ inf。我一直在尝试使用scipy.optimize.fmin_l_bfgs_b
和scipy.optimize.fmin_tnc
等算法(来自scipy.ref指南),但我无法弄清楚如何正确设置边界。 (我知道,它一定是愚蠢的东西,但我对Python非常棒)。让我们举一个简单的例子:
>>>import scipy.optimize as opt
>>>import scipy
>>>from numpy import *
>>>def f (x): return x**(1/2.0)
>>>max_x = opt.fmin_l_bfgs_b(lambda x: -f(x), [0,0], bounds=([0,0],[9,0])) #I want x to range between 0 and 9 and fmax be 3
但输出很奇怪:我什么都没得到!甚至没有错误!我错过了什么?
答案 0 :(得分:4)
bounds参数为[(lower1,upper1),(lower2,upper2)],而不是[(lower1,lower2),(upper1,upper2)]。如果你查看你的结果(max_x),你会看到“错误:没有可用的解决方案”,我猜是因为你的边界指定了一个空集。
这是调用函数的正确方法。我假设平方根只是一个例子。我使用-x ** 2代替。
import scipy.optimize as opt
import scipy
from numpy import *
def f(x):
print x
return -x**(2)
max_x = opt.fmin_l_bfgs_b(lambda x: -f(x), 1.0, bounds=[(-9,9)],approx_grad=True)
因为您没有指定渐变功能,所以需要设置approx_grad = True。 1.0是我对最大值的初始猜测(尽管在这个例子中它显然为零)。我添加了一个print语句,所以每次调用函数时都可以看到,但通常没有必要。有关调用fmin_l_bfgs_b的不同方法的更多详细信息,请参阅here。
上面的代码导致:
[ 1.]
[ 1.]
[ 1.00000001]
[-0.99999999]
[-0.99999999]
[-0.99999998]
[ 0.001]
[ 0.001]
[ 0.00100001]
[ -5.01108742e-09]
[ -5.01108742e-09]
[ 4.98891258e-09]
而max_x看起来像这样:
(array([ -5.01108742e-09]),
array([ 2.51109971e-17]),
{'funcalls': 4,
'grad': array([ -2.21748344e-11]),
'task': 'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL',
'warnflag': 0})
答案 1 :(得分:2)
为什么使用多变量最小化器?试试scipy.optimize.fminbound
。
max_x = opt.fminbound(lambda x: -f(x), 0, 9)