2015-11-03 144 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)。