如何在有约束的 scipy 中使用最小化函数

Posted

技术标签:

【中文标题】如何在有约束的 scipy 中使用最小化函数【英文标题】:How do I use a minimization function in scipy with constraints 【发布时间】:2013-09-17 00:57:39 【问题描述】:

我需要一些关于 python(scipy) 中优化函数的帮助 问题是优化f(x) 其中x=[a,b,c...n]。约束条件是 a、b 等的值应介于 0 和 1 之间,并且 sum(x)==1。 scipy.optimise.minimize 函数似乎最好,因为它不需要微分。我如何传递论点?

使用排列创建一个 ndarray 太长了。我现在的代码如下:-

import itertools as iter
all=iter.permutations([0.0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1.0],6) if sum==1
all_legal=[]
for i in all:
if np.sum(i)==1:
    #print np.sum(i)
    all_legal.append(i)
print len(all_legal)
lmax=0
sharpeMax=0
for i in all_legal:
    if sharpeMax<getSharpe(i):
        sharpeMax=getSharpe(i)
        lmax=i

【问题讨论】:

旁白:iter是一个内置函数的名称,所以它不是itertools的好缩写。 目前还不清楚您要优化什么。你能更详细地描述一下这个问题吗? 我强烈推荐阅读 Scipy 讲座中关于 Optimization 的章节。值得一读。 【参考方案1】:

您可以使用COBYLASLSQP 进行约束优化,如docs 中所述。

from scipy.optimize import minimize

start_pos = np.ones(6)*(1/6.) #or whatever

#Says one minus the sum of all variables must be zero
cons = ('type': 'eq', 'fun': lambda x:  1 - sum(x))

#Required to have non negative values
bnds = tuple((0,1) for x in start_pos)

将这些组合到最小化函数中。

res = minimize(getSharpe, start_pos, method='SLSQP', bounds=bnds ,constraints=cons)

【讨论】:

sum(k for k in x) 也称为sum(x)。 :) @Dougal 多年后,当我收到有关此答案的通知时,我仍然对此感到震惊。【参考方案2】:

检查.minimize 文档字符串:

scipy.optimize.minimize(fun, x0, args=(), method='BFGS', jac=None, hess=None, hessp=None, \
              bounds=None, constraints=(), tol=None, callback=None, options=None)

在您的情况下,最重要的是bounds。当你想将你的参数约束在[0,1](或(0,1)?)时你需要为每个变量定义它,例如:

bounds=((0,1), (0,1).....)

现在,另一部分,sum(x)==1。可能有更优雅的方法来做到这一点,但考虑一下:不是最小化f(x),而是最小化h=lambda x: f(x)+g(x),一个新的函数必不可少f(x)+g(x),其中g(x) 是一个函数在sum(x)=1 时达到最小值。如g=lambda x: (sum(x)-1)**2

f(x)g(x) 都处于最小值时,达到了h(x) 的最小值。拉格朗日乘数法的一个案例http://en.wikipedia.org/wiki/Lagrange_multiplier

【讨论】:

以上是关于如何在有约束的 scipy 中使用最小化函数的主要内容,如果未能解决你的问题,请参考以下文章

Python最小化函数:将附加参数传递给约束字典

Scipy 最小化约束函数

Scipy.optimize 不等式约束 - 考虑不等式的哪一侧?

scipy中的最小化,找到N维标量函数的所有局部最小值的算法

使用 Scipy 在 Python 中进行约束优化

如何对 SciPy 曲线拟合施加约束?