Указание ограничений для fmin_cobyla в scipy
-
20-09-2019 - |
Вопрос
Я использую Python 2.5.
Я передаю границы оптимизации 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)
На основе начальных значений Initial
и в соответствии с/в пределах b1
Для b10
значения передаются в opt()
.Но значения расходятся, особенно с b9
.Это очень важное ограничивающее условие для моей проблемы!
"Ценность x[2]
передано моей функции opt()
на каждой итерации всегда должно быть больше, чем x[3]
" - Как этого можно достичь?
Есть ли что-то неправильное в моих границах (b1
Для b9
) определение ?
Или есть лучший способ определения моих границ?
Пожалуйста, помогите мне.
Решение
fmin_cobyla()
это не метод внутренней точки.То есть, он будет передавать функции точки, которые находятся за пределами границ ("неосуществимые точки") в ходе выполнения оптимизации.
Единственное, что вам нужно будет исправить, это то, что b9
и b10
находятся не в той форме , которая fmin_cobyla()
ожидает.Связанные функции должны возвращать положительное число, если они находятся в пределах границы, 0.0, если они находятся точно на границе, и отрицательное число, если они находятся за пределами границ.В идеале эти функции должны быть плавными. fmin_cobyla()
попытаемся взять числовые производные от этих функций, чтобы сообщить ему, как вернуться в допустимую область.
b9 = lambda x: x[2] - x[3]
Я не уверен, как это реализовать b10
таким образом , что fmin_cobyla()
тем не менее, вы сможете использовать.
Другие советы
для b10 возможным вариантом может быть:
b10 = lambda x: min(abs(i-j)-d for i,j in itertools.combinations(x,2))
где d является ли дельта больше минимальной разницы, которую вы хотите получить между вашими переменными (например, 0.001)