Especificación de restricciones para fmin_cobyla en scipy
-
20-09-2019 - |
Pregunta
utilizo Python 2.5.
Estoy pasando los límites para la optimización 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)
basado en los valores Initial
inicial y según / dentro de la b1
límites a b10
se pasan los valores a opt()
. Sin embargo, los valores se desvían, especialmente con b9
. Esta es una condición de limitación muy importante para mi problema!
"El valor de x[2]
pasado a mi función opt()
en cada iteración debe ser siempre mayor que x[3]
" -? ¿Cómo es posible alcanzar este
¿Hay algo malo en mis límites (b1
a b9
) definición?
O hay una mejor manera de definir de mis límites?
Por favor, ayúdame.
Solución
fmin_cobyla()
no es un método de punto interior. Es decir, se pasará puntos que están fuera de los límites ( "puntos factibles") a la función durante el transcurso de la carrera optmization.
En lo que se necesita para arreglar es que b9
y b10
no están en la forma que fmin_cobyla()
espera. Las funciones con destino tienen que devolver un número positivo si están dentro de la cota, 0,0 si son exactamente en el límite, y un número negativo si están fuera de los límites. Idealmente, estas funciones deben ser suaves. fmin_cobyla()
tratará de tomar derivadas numéricas de estas funciones con el fin de que éste sepa cómo volver a la región factible.
b9 = lambda x: x[2] - x[3]
No estoy seguro de cómo implementar b10
de una manera que fmin_cobyla()
será capaz de utilizar, sin embargo.
Otros consejos
para b10, una posible opción podría ser:
b10 = lambda x: min(abs(i-j)-d for i,j in itertools.combinations(x,2))
donde d es un delta mayor que la diferencia mínima que desea entre las variables (por ejemplo 0.001)