Я выполняю ограниченную оптимизацию с помощью scipy.optimize.minimize(method='COBYLA')
.
. Чтобы оценить функцию стоимости, мне нужно выполнить относительно дорогие вычисления для вычисления набора данных из входных переменных и функции стоимости. является одним (дешевым для вычисления) свойством этого набора данных. Однако два моих ограничения также зависят от этих дорогих данных. До сих пор единственный способ ограничить оптимизацию, который я нашел, состоит в том, чтобы каждая из функций ограничения повторно вычисляла тот же набор данных, который уже имеется у функции стоимости.
Упрощенный квазикод:
# universal cost function evaluator
def criterion_from_x(x, cfun):
data = expensive_fun(x)
return(cfun(data))
def costfun(data):
return(cheap_fun1(data))
def constr1(data):
return(cheap_fun2(data))
def constr2(data):
return(cheap_fun3(data))
constraints = [{'type':'ineq', 'fun':criterion_from_x, 'args':(constr1,)},
{'type':'ineq', 'fun':criterion_from_x, 'args':(constr2,)}
# initial guess
x0 = np.ones((6,))
opt_result = minimize(criterion_from_x, x0, method='COBYLA',
args=(costfun,), constraints=constraints)
Итак, у меня есть универсальная функция «оценить некоторую стоимость», которая выполняет дорогостоящие вычисления, а затем оценивает любой критерий, который ей был дан. Но он должен запускаться три раза для каждой итерации оптимизатора.
Мне не удалось найти какой-либо способ установить что-то, где x
используется для генерации data
, который затем передается в целевая функция, а также функции ограничения.
Существует ли что-то подобное? Я заметил аргумент callback
для minimize()
, но это функция, которая вызывается после каждого шага. Мне нужен какой-то препроцессор, который вызывается на x
перед каждым шагом, результат которого затем используется вместо x
. Может быть, есть способ как-то проникнуть в него? Я бы не хотел писать свой собственный оптимизатор.
Один из традиционных способов решения этой проблемы - добавить функцию штрафа за нарушение ограничений в функцию main cost и запустить оптимизатор без явных ограничений, но я Я пробовал это раньше и обнаружил, что основная функция стоимости может стать несколько хаотичной c в случаях, когда ограничения нарушаются, поэтому оптимизатор может застрять в каком-то месте, которое нарушает ограничения и не обнаруживает снова.
Код должен работать на машинах с Python v2.7.6 до 2.7.13 и scipy от 0,13 до 0,17.