在Python中找到带边界的函数的最大值

时间:2013-05-27 22:05:27

标签: python python-3.x scipy max

我想找到一个函数f(x)的局部最大值,其中x可以在两个固定值之间,因为如果x趋向+ inf,f(x)将倾向于+ inf。我一直在尝试使用scipy.optimize.fmin_l_bfgs_bscipy.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

但输出很奇怪:我什么都没得到!甚至没有错误!我错过了什么?

2 个答案:

答案 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)