2015-11-03 140 views
6

我正在使用SciPy进行优化,而SLSQP方法似乎忽略了我的约束。Scipy.optimize.minimize method ='SLSQP'忽略约束

具体而言,我想X [3]和X [4]是在范围[0-1]

我收到一条消息: '不等式约束不相容'

这里是执行随后的示例代码的结果(使用一个虚拟函数):

status: 4 
    success: False 
njev: 2 
nfev: 24 
fun: 0.11923608071680103 
    x: array([-10993.4278558 , -19570.77080806, -23495.15914299, -26531.4862831 , 
    4679.97660534]) 
message: 'Inequality constraints incompatible' 
jac: array([ 12548372.4766904 , 12967696.88362279, 39928956.72239509, 
    -9224613.99092537, 3954696.30747453,   0.  ]) 
nit: 2 

这是我的代码:

from random import random 
from scipy.optimize import minimize 

def func(x): 
    """ dummy function to optimize """ 
    print 'x'+str(x) 
    return random() 

my_constraints = ({'type':'ineq', 'fun':lambda(x):1-x[3]-x[4]}, 
        {'type':'ineq', 'fun':lambda(x):x[3]}, 
        {'type':'ineq', 'fun':lambda(x):x[4]}, 
        {'type':'ineq', 'fun':lambda(x):1-x[4]}, 
        {'type':'ineq', 'fun':lambda(x):1-x[3]}) 

minimize(func, [57.9499 ,-18.2736,1.1664,0.0000,0.0765], 
     method='SLSQP',constraints=my_constraints) 

编辑 - 即使删除第一个约束,问题仍然存在。

当我尝试使用变量的界限时,问题仍然存在。 即

bounds_pairs = [(None,None),(None,None),(None,None),(0,1),(0,1)] 
minimize(f,initial_guess,method=method_name,bounds=bounds_pairs,constraints=non_negative_prob) 
+3

为什么使用无意义函数进行优化?如果函数只是返回'random()'(特别是,甚至不会为同样的输入返回一致的结果),SciPy当然会感到困惑。 – user2357112

+0

为了举例。不管我使用的功能如何,都会发生此问题。我不认为这是问题@ user2357112 – Zahy

+0

至少在scipy文档中,当使用lambda时,他们会努力返回一个np.array(),如:'fun':lambda x:np.array([x [ 0] ** 3 - x [1]])。 –

回答

0

我知道这是一个非常古老的问题,但我很感兴趣。

这是什么时候发生的?

当优化函数不可靠可微时发生此问题。如果你使用这样的漂亮的平滑功能:

opt = numpy.array([2, 2, 2, 2, 2]) 

def func(x): 
    return sum((x - opt)**2) 

问题消失。

我该如何施加严格的约束?

请注意,中的约束算法都没有保证函数永远不会在约束条件之外被评估。如果这是你的要求,你应该使用转换。因此,例如为了确保x [3]没有使用负值,您可以使用转换x3_real = 10^x[3]。这样x [3]可以是任何值,但是你使用的变量永远不会是负数。

更深入的分析

调查对于slsqp的Fortran代码产生以下见解发生此错误时进入。该例程返回一个MODE变量,它可以取以下值:

C*  MODE = -1: GRADIENT EVALUATION, (G&A)      * 
C*    0: ON ENTRY: INITIALIZATION, (F,G,C&A)    * 
C*     ON EXIT : REQUIRED ACCURACY FOR SOLUTION OBTAINED * 
C*    1: FUNCTION EVALUATION, (F&C)      * 
C*                  * 
C*     FAILURE MODES:         * 
C*    2: NUMBER OF EQUALITY CONTRAINTS LARGER THAN N  * 
C*    3: MORE THAN 3*N ITERATIONS IN LSQ SUBPROBLEM  * 
C*    4: INEQUALITY CONSTRAINTS INCOMPATIBLE    * 
C*    5: SINGULAR MATRIX E IN LSQ SUBPROBLEM    * 
C*    6: SINGULAR MATRIX C IN LSQ SUBPROBLEM    * 

其中分配模式4(这是你所得到的误差)的部分如下:

C SEARCH DIRECTION AS SOLUTION OF QP - SUBPROBLEM 

     CALL dcopy_(n, xl, 1, u, 1) 
     CALL dcopy_(n, xu, 1, v, 1) 
     CALL daxpy_sl(n, -one, x, 1, u, 1) 
     CALL daxpy_sl(n, -one, x, 1, v, 1) 
     h4 = one 
     CALL lsq (m, meq, n , n3, la, l, g, a, c, u, v, s, r, w, iw, mode) 

C AUGMENTED PROBLEM FOR INCONSISTENT LINEARIZATION 

     IF (mode.EQ.6) THEN 
      IF (n.EQ.meq) THEN 
       mode = 4 
      ENDIF 
     ENDIF 

所以基本上你可以看到它试图找到下降方向,如果约束是活动的,它将尝试沿着约束进行导数评估,并且在lsq子问题(​​)中出现奇异矩阵失败,那么它会导致如果所有约束方程都被评估并且没有产生成功的下降方向,这必然是一个矛盾的缺点traints(mode = 4)。