我正在使用 scipy.optimize.minimize 来求解复杂的油藏优化模型(SQSLP 和 COBYLA,因为问题受到边界和约束方程的约束)。每天有一个决策变量(蓄水量),水库的释放量是根据目标函数内蓄水量变化的函数来计算的。然后应用基于释放和存储惩罚的惩罚,以最小化惩罚为目标(目标函数是所有惩罚的总和)。我在此模型中添加了一些约束,以将存储的变化限制为物理系统限制,这是决策变量 x(t+1) 和 x(t) 之间的差异,并且还取决于该时间步骤 I( t)。使用 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"]
有什么想法我哪里出错了吗?我在其他应用程序中看到过类似的约束,所以我无法弄清楚,但假设它很简单。我在该代码的完整版本中需要启动数百个约束,因此像第二个示例中那样将它们写出来并不理想。