问题描述
我遇到以下优化问题:
目标函数非常简单:给定向量SPREAD
,我尝试找到向量W
以最大化sum(W.SPREAD)
.
The objective function is quite simple: given a vector SPREAD
, I try to find the vector W
to maximize sum(W.SPREAD)
.
例如,在第3维中,这意味着我尝试最大化w1 x spread1 + w2 x spread2 + w3 x spread3
.
As an example, in dimension 3, this mean I try to maximize w1 x spread1 + w2 x spread2 + w3 x spread3
.
另外,我有三个约束c1, c2 & c3
不在W
上,而是在POS
向量上,其中POS = W2POS(W)
.
Plus, I have three constraints c1, c2 & c3
not on W
, but on a POS
vector where POS = W2POS(W)
.
例如,在第3维中,约束为:
As an example, in dimension 3, contraints are:
-
|pos1 + pos2 + pos3| < 5
-
|pos1| + |pos2| + |pos3| < 500
-
Max(pos1, pos2, pos3) < 5
|pos1 + pos2 + pos3| < 5
|pos1| + |pos2| + |pos3| < 500
Max(pos1, pos2, pos3) < 5
我写了下面的代码,它们进行了一些优化,但是没有遵守约束3.我该如何遵守我的约束条件解决这个问题?
I wrote the below code which perform some optimization, however, constraints 3 is not respected. How can I solve this problem respecting my constraints?
我写了下面的代码:
from scipy.optimize import fmin_cobyla
import numpy as np
import pandas as pd
def W2POS(W, PRICE, BETA):
POS = (PRICE * BETA).T.dot(W)
return POS
def objective(W, SPREAD, sign = 1):
er = sum((W * SPREAD.T).sum())
return sign * er
def c1(x, *args):
""" abs(sum(c)) < 500 """
POS = W2POS(x,args[0], args[1])
return POS.apply(abs).sum()
def c2(x, *args):
""" abs(sum()) < 5 """
POS = W2POS(x,args[0], args[1])
return 5. - abs(POS.sum())
def c3(x, *args):
""" abs(max(pos)) < 5 """
POS = W2POS(x,args[0], args[1])
return 5. - POS.apply(abs).max()
# optim
W0 = np.zeros(shape=(len(BETA), 1))
sign = -1
W = fmin_cobyla(objective, W0, cons = [c1, c2, c3], args=(SPREAD,sign),
consargs=(PRICE, BETA), maxfun=100, rhobeg = 0.02).T
print 'Solution:', W
args = [PRICE, BETA]
pos = W2POS(W.T,args[0], args[1])
print 'c1 < 5:', abs(pos.sum())[0]
print 'c2 < 500:', pos.apply(abs).sum()[0]
print 'c3 < 5:', pos.apply(abs).apply(max)[0]
您可以使用一些虚拟数据来说明此代码不尊重c3: http://pastebin.com/gjbeePgt
You can play with some dummy data that will illustrate c3 being not respected with this code : http://pastebin.com/gjbeePgt
推荐答案
阅读原始Fortran 77文件 cobyla2.f 中的文档(可在此包),在第38和39行中指出:
Reading the documentation in the original Fortran 77 file cobyla2.f (available in this package), lines 38 and 39, it is stated:
如果我为scipy API文档, ="nofollow"> fmin_cobyla 正确,默认情况下RHOEND
设置为 1.0E-4 .
If I interpret the scipy API documentation for fmin_cobyla correctly, RHOEND
is by default set to 1.0E-4.
如果观察到的约束违规确实小于RHOEND
,但仍然不可接受,那么,解决此问题的简单方法是将RHOEND
的值并入约束公式中,即
If the observed constraint violations are indeed less than RHOEND
but still unacceptably large, a simple solution to the issue would be to incorporate the value of RHOEND
in the constraint formulations, i.e.
C[i] + RHOEND >= 0
在这种特殊情况下,它看起来像确实,违反约束大于RHOEND
,这已经由由Pauli Virtanen构建的 scipy 存储库中的新测试用例,以及对应于上述问题.
In this particular case, it does appear like the constraint violation is larger than RHOEND
, which has been thoroughly illustrated by a new test case in the scipy repository, constructed by Pauli Virtanen, and corresponding to the above question.
为避免在这种特殊情况下违反约束,解决方案似乎是在RHOBEG
上以较小的值(例如 0.01 )开始优化.
To avoid constraint violation in this particular case, the solution appears to be to start the optimization with a smaller value on RHOBEG
, for example 0.01.
这篇关于Python SciPy:优化问题fmin_cobyla:不遵守一个约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!