优化 Pyomo Python - 'SumExpression is not iterable'
Optimization Pyomo Python - 'SumExpression is not iterable'
我是 Python 的新手,我似乎无法解决我遇到的问题,即使在经历了论坛上发布的类似问题之后也是如此。
我的问题是我的 objective 函数出现 ''SumExpression' object is not iterable' 错误。
我的代码:
import pyomo.environ as pyo
from pyomo.opt import SolverFactory
model=pyo.ConcreteModel()
#C = contract capacity
D = [5048,5144,4616,4296,3696,3392,5048,5144,4616,4296,3696,3392]
R = [166.9,166.9,166.9,166.9,166.9,166.9,166.9,166.9,223.6,223.6,223.6,223.6]
PF=[0.027 for i in range (12)]
E=[1319.25,1319.25,1319.25,1319.25,1319.25,1319.25,1319.25,1319.25,1759,1759,1759,1759]
model.M=pyo.RangeSet(0,11)
model.X = pyo.Var(model.M, domain=pyo.NonNegativeReals)
model.C = pyo.Var(model.M, domain=pyo.NonNegativeReals)
model.Y = pyo.Var(model.M, domain=pyo.NonNegativeReals)
def constraint_1(model,M):
return model.X[M]+model.C[M] >= D[M]
model.constraint_1 = pyo.Constraint(model.M, rule=constraint_1)
def constraint_2(model,M):
return model.Y[M]+1.1*model.C[M] >= D[M]
model.constraint_2 = pyo.Constraint(model.M, rule=constraint_2)
def constraint_3(model,M):
if M == 11:
return model.C[0] >= model.C[M]
else:
return model.C[M+1] >= model.C[M]
model.constraint_3 = pyo.Constraint(model.M, rule=constraint_3)
def mod_obj(model,M):
if M==11:
return sum((1-PF[M])*R[M]*model.C[M]+2*R[M]*model.X[M]+R[M]*model.Y[M]+E[M]*(model.C[0]-model.C[M]))
else:
return sum((1-PF[M])*R[M]*model.C[M]+2*R[M]*model.X[M]+R[M]*model.Y[M]+E[M]*(model.C[M+1]-model.C[M]))
model.mod_obj = pyo.Constraint(model.M, rule=mod_obj)
model.obj=pyo.Objective(rule=mod_obj, sense=pyo.minimize)
opt = SolverFactory('glpk')
opt.solve(model)
model.pprint()
我得到的错误来自 objective 函数的第二行:
return sum((1-PF[M])*R[M]*model.C[M]+2*R[M]*model.X[M]+R[M]*model.Y[M]+E[M]*(model.C[M+1]-model.C[M]))
我认为它必须与 M+1 做一些事情,因为第一行没有给出错误但我似乎无法解决这个错误并感谢您的 help/input.
提前致谢!
你有一些事情挂在这里...
首先,当你使用 sum()
表达式时,里面的东西需要是可迭代的。您只是为 M
传递了一个固定值。示例:
In [32]: A = [5,6,7]
In [33]: sum(A[0] + A[1])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-33-143c09ad32d9> in <module>
----> 1 sum(A[0] + A[1])
TypeError: 'int' object is not iterable
In [34]: sum(A[idx] for idx in range(3))
Out[34]: 18
因此您需要将 sum()
函数设置为具有该类型的结构,这导致第二件事挂起您,为 model.C 构建正确的索引,出现环绕。您可以使用模数以数学方式构建您正在寻找的“环绕”。考虑:
In [39]: import pyomo.environ as pyo
In [40]: M = pyo.RangeSet(0,11) # 0->11 inclusive
In [41]: M_prime = [(t+1)%12 for t in M]
In [42]: M_prime
Out[42]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0]
所以我们可以将它们拼接成一个表达式,而不是在您的模型中传入索引 M
,这对于 objective 函数来说是不正确的结构,因为传入 M
会在你的模型中生成 M 个表达式,对吗?所以,我认为您正在寻找这样的东西:
def mod_obj(model):
return sum((1-PF[m])*R[m]*model.C[m]+2*R[m]*model.X[m]+R[m]*model.Y[m]+E[m]*(model.C[(m+1)%12]-model.C[m]) for m in model.M)
#model.mod_obj = pyo.Constraint(model.M, rule=mod_obj)
model.obj=pyo.Objective(rule=mod_obj, sense=pyo.minimize)
另请注意:您正在通过使用大写 M
代表集合 model.M
的成员来为 confusion/disaster 做好准备。我觉得用小写字母来表示集合成员更清晰,读起来更清楚。
我是 Python 的新手,我似乎无法解决我遇到的问题,即使在经历了论坛上发布的类似问题之后也是如此。
我的问题是我的 objective 函数出现 ''SumExpression' object is not iterable' 错误。
我的代码:
import pyomo.environ as pyo
from pyomo.opt import SolverFactory
model=pyo.ConcreteModel()
#C = contract capacity
D = [5048,5144,4616,4296,3696,3392,5048,5144,4616,4296,3696,3392]
R = [166.9,166.9,166.9,166.9,166.9,166.9,166.9,166.9,223.6,223.6,223.6,223.6]
PF=[0.027 for i in range (12)]
E=[1319.25,1319.25,1319.25,1319.25,1319.25,1319.25,1319.25,1319.25,1759,1759,1759,1759]
model.M=pyo.RangeSet(0,11)
model.X = pyo.Var(model.M, domain=pyo.NonNegativeReals)
model.C = pyo.Var(model.M, domain=pyo.NonNegativeReals)
model.Y = pyo.Var(model.M, domain=pyo.NonNegativeReals)
def constraint_1(model,M):
return model.X[M]+model.C[M] >= D[M]
model.constraint_1 = pyo.Constraint(model.M, rule=constraint_1)
def constraint_2(model,M):
return model.Y[M]+1.1*model.C[M] >= D[M]
model.constraint_2 = pyo.Constraint(model.M, rule=constraint_2)
def constraint_3(model,M):
if M == 11:
return model.C[0] >= model.C[M]
else:
return model.C[M+1] >= model.C[M]
model.constraint_3 = pyo.Constraint(model.M, rule=constraint_3)
def mod_obj(model,M):
if M==11:
return sum((1-PF[M])*R[M]*model.C[M]+2*R[M]*model.X[M]+R[M]*model.Y[M]+E[M]*(model.C[0]-model.C[M]))
else:
return sum((1-PF[M])*R[M]*model.C[M]+2*R[M]*model.X[M]+R[M]*model.Y[M]+E[M]*(model.C[M+1]-model.C[M]))
model.mod_obj = pyo.Constraint(model.M, rule=mod_obj)
model.obj=pyo.Objective(rule=mod_obj, sense=pyo.minimize)
opt = SolverFactory('glpk')
opt.solve(model)
model.pprint()
我得到的错误来自 objective 函数的第二行:
return sum((1-PF[M])*R[M]*model.C[M]+2*R[M]*model.X[M]+R[M]*model.Y[M]+E[M]*(model.C[M+1]-model.C[M]))
我认为它必须与 M+1 做一些事情,因为第一行没有给出错误但我似乎无法解决这个错误并感谢您的 help/input.
提前致谢!
你有一些事情挂在这里...
首先,当你使用 sum()
表达式时,里面的东西需要是可迭代的。您只是为 M
传递了一个固定值。示例:
In [32]: A = [5,6,7]
In [33]: sum(A[0] + A[1])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-33-143c09ad32d9> in <module>
----> 1 sum(A[0] + A[1])
TypeError: 'int' object is not iterable
In [34]: sum(A[idx] for idx in range(3))
Out[34]: 18
因此您需要将 sum()
函数设置为具有该类型的结构,这导致第二件事挂起您,为 model.C 构建正确的索引,出现环绕。您可以使用模数以数学方式构建您正在寻找的“环绕”。考虑:
In [39]: import pyomo.environ as pyo
In [40]: M = pyo.RangeSet(0,11) # 0->11 inclusive
In [41]: M_prime = [(t+1)%12 for t in M]
In [42]: M_prime
Out[42]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0]
所以我们可以将它们拼接成一个表达式,而不是在您的模型中传入索引 M
,这对于 objective 函数来说是不正确的结构,因为传入 M
会在你的模型中生成 M 个表达式,对吗?所以,我认为您正在寻找这样的东西:
def mod_obj(model):
return sum((1-PF[m])*R[m]*model.C[m]+2*R[m]*model.X[m]+R[m]*model.Y[m]+E[m]*(model.C[(m+1)%12]-model.C[m]) for m in model.M)
#model.mod_obj = pyo.Constraint(model.M, rule=mod_obj)
model.obj=pyo.Objective(rule=mod_obj, sense=pyo.minimize)
另请注意:您正在通过使用大写 M
代表集合 model.M
的成员来为 confusion/disaster 做好准备。我觉得用小写字母来表示集合成员更清晰,读起来更清楚。