Specificando i vincoli per fmin_cobyla in SciPy
-
20-09-2019 - |
Domanda
io uso Python 2.5.
sto passando limiti alla ottimizzazione cobyla:
import numpy
from numpy import asarray
Initial = numpy.asarray [2, 4, 5, 3] # Initial values to start with
#bounding limits (lower,upper) - for visualizing
#bounds = [(1, 5000), (1, 6000), (2, 100000), (1, 50000)]
# actual passed bounds
b1 = lambda x: 5000 - x[0] # lambda x: bounds[0][1] - Initial[0]
b2 = lambda x: x[0] - 2.0 # lambda x: Initial[0] - bounds[0][0]
b3 = lambda x: 6000 - x[1] # same as above
b4 = lambda x: x[1] - 4.0
b5 = lambda x: 100000 - x[2]
b6 = lambda x: x[2] - 5.0
b7 = lambda x: 50000 - x[3]
b8 = lambda x: x[3] - 3.0
b9 = lambda x: x[2] > x[3] # very important condition for my problem!
opt= optimize.fmin_cobyla(func,Initial,cons=[b1,b2,b3,b4,b5,b6,b7,b8,b9,b10],maxfun=1500000)
In base ai valori Initial
iniziale e come per / entro il limiti b1
per b10
i valori vengono passati al opt()
. Ma i valori stanno deviando, in particolare con b9
. Questo è molto importante condizione di delimitazione per il mio problema!
"Il valore della x[2]
passato alla mia funzione opt()
ad ogni iterazione deve essere sempre maggiore di x[3]
" -? Come è possibile per raggiungere questo obiettivo
C'è qualcosa di sbagliato nei miei limiti (b1
a b9
) definizione?
O c'è un modo migliore di definire dei miei limiti?
Per favore mi aiuti.
Soluzione
fmin_cobyla()
non è un metodo punto interno. Cioè, passerà punti che sono al di fuori dei limiti ( "punti irrealizzabili") alla funzione nel corso della corsa ottimizzazioni.
Su cosa che dovrete risolvere è che b9
e b10
non sono nella forma che si aspetta fmin_cobyla()
. Le funzioni legate devono restituire un numero positivo se si trovano entro il limite, 0.0 se sono esattamente sulla vincolato e un numero negativo se sono fuori dai limiti. Idealmente, queste funzioni devono essere lisce. fmin_cobyla()
cercherà di prendere derivate numeriche di queste funzioni, al fine di farle sapere come tornare alla regione ammissibile.
b9 = lambda x: x[2] - x[3]
Non sono sicuro di come implementare b10
in un modo che fmin_cobyla()
sarà in grado di utilizzare, però.
Altri suggerimenti
per b10, una possibile opzione potrebbe essere:
b10 = lambda x: min(abs(i-j)-d for i,j in itertools.combinations(x,2))
dove d è un delta maggiore della differenza minima che si desidera tra le variabili (per esempio 0.001)