Я использую scipy.optimize.minimize для решения сложной модели оптимизации коллектора (SQSLP и COBYLA, поскольку проблема ограничена как границами, так и уравнениями ограничений). Существует одна переменная решения в день (хранение), и выбросы из резервуара рассчитываются как функция изменения запасов в рамках целевой функции. Затем применяются штрафы, основанные на выпусках и штрафах за хранение, с целью минимизации штрафов (целевая функция - это сумма всех штрафов). Я добавил некоторые ограничения в эту модель, чтобы ограничить изменение хранилища до пределов физической системы, которые являются разницей между переменной решения x (t + 1) и x (t), а также зависят от притоков на этом временном шаге I ( т). Эти ограничения добавляются в список словарей ограничений с помощью цикла for. Ограничения, добавленные вне этой функции цикла for, как должны. Однако ограничений, связанных со временем, которые инициируются в цикле for, нет.
Очевидно, проблема сложна, поэтому я воссоздал более простую версию, чтобы проиллюстрировать проблему. Эта задача имеет четыре переменные решения и стремится минимизировать целевую функцию (которую я назвал функцией) с ограничениями устойчивого состояния (I = приток должен быть равен x = отток) и неотрицательности (т.е. отток x не может быть отрицательным):
import numpy as np
from scipy.optimize import minimize
def function(x):
return -1*(18*x[0]+16*x[1]+12*x[2]+11*x[3])
I=np.array((20,50,50,80))
x0=I
cons=[]
steadystate={'type':'eq', 'fun': lambda x: x.sum()-I.sum() }
cons.append(steadystate)
for t in range (4):
def const(x):
y=x[t]
return y
cons.append({'type':'ineq', 'fun': const})
out=minimize(function, x0, method="SLSQP", constraints=cons)
x=out["x"]
Ограничения, инициированные в цикле for, являются ограничениями неотрицательности, но оптимизация дает отрицательные значения для переменных решения. Тем не менее, он придерживается постоянного ограничения.
Когда я вычисляю проблему, используя следующий код, значения ограничиваются правильно:
import numpy as np
from scipy.optimize import minimize
def function(x):
return -1*(18*x[0]+16*x[1]+12*x[2]+11*x[3])
I=np.array((20,50,50,80))
x0=I
cons=[]
steadystate1={'type':'eq', 'fun': lambda x: x.sum()-I.sum() }
cons.append(steadystate1)
nonneg0 = {'type':'ineq', 'fun': lambda x: x[0]}
nonneg1= {'type':'ineq', 'fun': lambda x: x[1]}
nonneg2 = {'type':'ineq', 'fun': lambda x: x[2]}
nonneg3 = {'type':'ineq', 'fun': lambda x: x[3]}
cons.append(nonneg0)
cons.append(nonneg1)
cons.append(nonneg2)
cons.append(nonneg3)
out=minimize(function, x0, method="SLSQP", constraints=cons)
x=out["x"]
Есть идеи, где я ошибаюсь? Я видел аналогичные ограничения в других приложениях, поэтому не могу понять, но предполагаю, что это что-то простое. У меня есть сотни ограничений, которые нужно инициировать в моей полномасштабной версии этого кода, поэтому их написание, как во втором примере, не будет идеальным.
x
- просто передайте одну функцию ограничения, которая возвращает весь вектор параметров:nonneg = {'type':'ineq', 'fun': lambda x: x}
- person ali_m   schedule 11.03.2016