我正在尝试使用 Gekko 跨时间(向量)进行优化,以根据多个约束生成时间表,即价格和事件可能发生的次数(假设我们将其限制为下面每 x7 5 次)。
我在 sum 调用中遇到以下错误:TypeError: x 必须是 GEKKO 参数、变量或表达式的 python 列表。
即使我删除总和,我也会收到以下错误:TypeError:@error:模型表达式 *** 函数字符串语法错误:无效元素:ame
以下变量是长度为42的向量: 斯普, 根据, 负_ln,
以下变量是缩放器值(长度1): 分钟, 最大限度, co_ln, 二氧化碳,
我可以通过一次仅查看 42 行中的 1 行来优化 x1 来实现此目的,但我无法弄清楚如何在限制频率的同时将其跨多行转换(x7) 。任何指导表示赞赏。
m = GEKKO(server='XXX', remote=False)
m.options.IMODE = 2
m.options.MAX_ITER = 1000
#initialize variables
x1, x2, x3, x4, x5, x6, x7 = [m.Var() for i in range(7)]
x1.value = 1
x2.value = 1
x3.value = 1
x4.value = 0
x5.value = 0
x6.value = 0
x7.value = 1
neg_ln = m.Intermediate(-m.log(x1/sp))
vol1 = m.Intermediate(co1+ base + (neg_ln*co_ln))
vol2 = m.Intermediate(co2+ base + (neg_ln*co_ln))
vol3 = m.Intermediate(co3+ base + (neg_ln*co_ln))
vol4 = m.Intermediate(base + (neg_ln*co_ln))
total_vol = m.Intermediate((
(m.max2(0,base*(m.exp(vol1)-1)) * x3 +
m.max2(0,base*(m.exp(vol2)-1)) * x4 +
m.max2(0,base*(m.exp(vol3)-1)) * x5 +
m.max2(0,base*(m.exp(vol4)-1)) * x6) + base) * x7)
m.Equation(x3+x4+x5+x6 == 1)
m.Equation(x3+x4+x5+x6 >= 0)
m.Equation(m.sum(x7)<= 5)
m.Equation(x1 >= min)
m.Equation(x1 <= max)
z1 = m.Var(lb = 3, ub = 15)
m.Equation(z1 == x1)
z2 = m.Var(lb = 3, ub = 15)
m.Equation(z2 == x2)
z3 = m.Var(lb = 0,ub = 1, integer=True)
m.Equation(z3 == x3)
z4 = m.Var(lb = 0,ub = 1, integer=True)
m.Equation(z4 == x4)
z5 = m.Var(lb = 0,ub = 1, integer=True)
m.Equation(z5 == x5)
z6 = m.Var(lb = 0,ub = 1, integer=True)
m.Equation(z6 == x6)
z7 = m.Var(lb = 0,ub = 1, integer=True)
m.Equation(z7 == x7)
m.Maximize(m.sum(simu_total_volume))
try:
m.solve(disp = True)
except:
"error"
尝试使用列表推导式来定义中间值。我插入了问题中未定义的常量的样本随机值:
sp = np.random.rand(42)
base = np.random.rand(42)
co_ln = 2; co1 = 5; co2=6; co3=7
尚不清楚
x
值是否应该是向量。这是通过 IMODE=3
来解决的,其中时间离散化是明确定义的,而 IMODE=6
则是时间离散化由 m.time
定义的。这是一个成功解决的示例问题。
import numpy as np
from gekko import GEKKO
m = GEKKO(remote=False)
sp = np.random.rand(42)
base = np.random.rand(42)
x1,x2 = m.Array(m.Var,2,lb=3,ub=15,value=1)
x3,x4,x5,x6,x7 = m.Array(m.Var,5,lb=0,ub=1,value=1,integer=True)
# change default values and upper bound
x3.value = 1; x7.value=1; x7.upper = 5
x = [x1,x2,x3,x4,x5,x6,x7]
n = 42
co_ln = 2; co1 = 5; co2=6; co3=7
neg_ln=[m.Intermediate(-m.log(x[0]/sp[i])) for i in range(n)]
vol1 =[m.Intermediate(co1+ base[i] + (neg_ln[i]*co_ln)) for i in range(n)]
vol2 =[m.Intermediate(co2+ base[i] + (neg_ln[i]*co_ln)) for i in range(n)]
vol3 =[m.Intermediate(co3+ base[i] + (neg_ln[i]*co_ln)) for i in range(n)]
vol4 =[m.Intermediate(base[i] + (neg_ln[i]*co_ln)) for i in range(n)]
total_vol = [m.Intermediate((
(m.max2(0,base[i]*(m.exp(vol1[i])-1)) * x[2] +
m.max2(0,base[i]*(m.exp(vol2[i])-1)) * x[3] +
m.max2(0,base[i]*(m.exp(vol3[i])-1)) * x[4] +
m.max2(0,base[i]*(m.exp(vol4[i])-1)) * x[5]) + base[i]) * x[6]) for i in range(n)]
m.Equation(sum(x[2:7])==1)
m.Equation(sum(x[2:7])>=0)
m.Equation(x7<=5)
m.Maximize(m.sum(total_vol))
m.options.SOLVER=1
m.solve(disp = True)
for i in range(7):
print(f'x[{i+1}]: {x[i].value[0]}')
这产生了一个解决方案:
Number of state variables: 892
Number of total equations: - 718
Number of slack variables: - 2
---------------------------------------
Degrees of freedom : 172
----------------------------------------------
Steady State Optimization with APOPT Solver
----------------------------------------------
Iter: 1 I: 0 Tm: 0.32 NLPi: 61 Dpth: 0 Lvs: 3 Obj: -4.87E+02 Gap: NaN
--Integer Solution: -2.10E+01 Lowest Leaf: -4.87E+02 Gap: 1.83E+00
Iter: 2 I: 0 Tm: 0.01 NLPi: 2 Dpth: 1 Lvs: 2 Obj: -2.10E+01 Gap: 1.83E+00
--Integer Solution: -2.10E+01 Lowest Leaf: -4.87E+02 Gap: 1.83E+00
Iter: 3 I: 0 Tm: 0.01 NLPi: 2 Dpth: 1 Lvs: 1 Obj: -2.10E+01 Gap: 1.83E+00
Iter: 4 I: 0 Tm: 0.01 NLPi: 2 Dpth: 1 Lvs: 0 Obj: 0.00E+00 Gap: 1.83E+00
No additional trial points, returning the best integer solution
Successful solution
---------------------------------------------------
Solver : APOPT (v1.0)
Solution time : 0.36019999999999985 sec
Objective : -20.951499798000548
Successful solution
---------------------------------------------------
x[1]: 3.0
x[2]: 3.0
x[3]: 0.0
x[4]: 0.0
x[5]: 0.0
x[6]: 0.0
x[7]: 1.0
一些建议:
z
变量来添加整数约束。在声明 x
变量时定义整数约束。m.Array()
高效创建变量数组。 x
值可以定义为向量 m.Array(m.Var,7)
或矩阵 m.Array(m.Var,(7,42))
。lb
和 ub
在初始化时定义边界,或使用 x[6].upper=5
在初始化后定义边界。使用 m.Equation(x[6]<=5)
的效率较低,因为不等式约束是隐式求解的。