2015-11-03 16 views
6

Używam SciPy do optymalizacji i metoda SLSQP wydaje się ignorować moje ograniczenia.Scipy.optimize.minimize method = 'SLSQP' ignoruje ograniczenie

szczególności chcę x [3] i X [4], aby być w przedziale [0-1]

Dostaję komunikat: 'nierównościowych niekompatybilne'

Oto wyniki realizacji następnie przykładowy kod wykorzystuje funkcję (obojętne):

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 

Oto mój kod:

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) 

EDYCJA - Problem występuje nadal, nawet podczas usuwania pierwszego wiązania.

Problem występuje, gdy próbuję użyć zmiennych bana. tj

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

Dlaczego używasz bezsensownej funkcji do optymalizacji? Jeśli funkcja po prostu zwraca 'random()' (aw szczególności nie zwraca nawet spójnych wyników dla tego samego wejścia), oczywiście SciPy będzie się mylić. – user2357112

+0

Dla dobra przykładu. Ten problem występuje niezależnie od funkcji, której używam. Nie sądzę, że to jest problem @ user2357112 – Zahy

+0

Przynajmniej w scipy docs, podczas korzystania z lambda podejmują bóle, aby zwrócić np.array(), jak: "zabawa": lambda x: np.array ([x [ 0] ** 3 - x [1]]). –

Odpowiedz

0

wiem, że to jest bardzo stare pytanie, ale jestem zaintrygowany.

Kiedy to się dzieje?

Ten problem występuje, gdy funkcja optymalizacji nie jest niezawodnie różniczkowalna. Jeśli używasz przyjemnej funkcji gładkiej, takiej jak ta:

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

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

Problem znika.

Jak nakładać ciężkie ograniczenia?

Należy zauważyć, że żaden z algorytmów z ograniczeniami w nie ma gwarancji, że funkcja nigdy nie zostanie oceniona poza ograniczeniami. Jeśli jest to wymagane, powinieneś raczej użyć transformacji. Aby na przykład upewnić się, że żadne wartości ujemne dla x [3] nie są kiedykolwiek używane, można użyć transformacji x3_real = 10^x[3]. W ten sposób x [3] może być dowolną wartością, ale zmienna, której używasz, nigdy nie będzie ujemna.

Głębsza analiza

Badając kod Fortran dla slsqp daje następujące wgląd kiedy występuje ten błąd. Rutynowe zwraca MODE zmienną, która może przyjmować następujące wartości:

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    * 

część, która tryb 4 (która jest błąd otrzymujesz) przypisuje się następująco:

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 

Więc w zasadzie może zobaczyć, że próbuje znaleźć kierunek zniżania, jeśli ograniczenia są aktywne, próbuje przeprowadzić analizę pochodną wzdłuż więzu i nie powiedzie się z pojedynczą macierzą w podpunkcie lsq (mode = 6), to powoduje, że jeśli wszystkie równania więzów zostały ocenione, a żadna nie ustaliła udane kierunki zniżania, musi to być sprzeczny zestaw wad Traints (mode = 4).