Skip to main content
 首页 » 编程设计

Python SciPy : optimization issue fmin_cobyla : one constraint is not respected

2025年05月04日13pengyingh

我有以下优化问题:

目标函数非常简单:给定一个向量 SPREAD ,我尝试找到向量 W最大化 sum(W.SPREAD) .

例如,在维度 3 中,这意味着我尝试最大化 w1 x spread1 + w2 x spread2 + w3 x spread3 .

另外,我有三个约束 c1, c2 & c3不在 W , 但在 POS向量在哪里 POS = W2POS(W) .

例如,在维度 3 中,约束是:

  1. |pos1 + pos2 + pos3| < 5
  2. |pos1| + |pos2| + |pos3| < 500
  3. Max(pos1, pos2, pos3) < 5

我写了下面的代码来执行一些优化,但是,约束 3 没有得到遵守。我怎样才能根据我的约束解决这个问题?

我写了下面的代码:

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

请您参考如下方法:

阅读原始 Fortran 77 文件 cobyla2.f(在 this 包中可用)中的文档,第 38 和 39 行指出:

C1,C2,...,CM denote the constraint functions that should become nonnegative eventually, at least to the precision of RHOEND

如果我解释 fmin_cobyla 的 scipy API 文档正确地,RHOEND 默认设置为 1.0E-4。

如果观察到的约束违规确实小于 RHOEND 但仍然大得无法接受,解决该问题的一个简单方法是将 RHOEND 的值合并到约束公式中,即

C[i] + RHOEND >= 0 

在这种特殊情况下,它确实看起来像约束违反大于RHOEND,这已由new test case in the scipy repository 充分说明。 ,由 Pauli Virtanen 构建,对应于上述问题。

为了避免在这种特殊情况下违反约束,解决方案似乎是在 RHOBEG 上以较小的值开始优化,例如 0.01。