[英]How to iterate through a set in a constraint?
I would like to iterate through a set in a constraint.我想遍历约束中的集合。 I have built an abstract model.我已经建立了一个抽象的 model。 Let's assume the following dictionaries for the instance:让我们假设该实例有以下字典:
dict_Nodes = {None: ['N1', 'N2']}
dict_Nodes_ArcsOut = {'N1': ['N1N4', 'N1N3'], 'N2': ['N2N5', 'N2N7']}
dict_Time = {None: [0, 1, 2]}
dict_Arcs = {None: ['N1N4', 'N1N3', 'N2N5', 'N2N7']}
However, as I am constructing an abstract model the data should not really matter.但是,由于我正在构建一个抽象的 model,因此数据并不重要。 I want to say that the variable in node N1 is the same value as in the arcs N1N4 and N1N3.我想说节点 N1 中的变量与弧 N1N4 和 N1N3 中的值相同。 For the abstract model I created several sets:对于抽象 model 我创建了几个集合:
from pyomo.environ import AbstractModel, Param, minimize, Var, Constraint,\
SolverFactory, Set, Objective, NonNegativeReals, Reals, Binary, ConstraintList
model = AbstractModel()
model.Set_Nodes = Set()
model.Set_Arcs = Set()
model.Set_Time = Set()
model.Set_Nodes_ArcsOut = Set(model.Set_Nodes)
model.Var_Arc = Var(model.Set_Arcs, model.Set_Time, within=NonNegativeReals)
model.Var_Node = Var(model.Set_Nodes, model.Set_Time, within=NonNegativeReals)
Looking at the data I would like to say that:看数据我想说:
Var_Arc['N1N4'] = Var_Node['N1']
Var_Arc['N1N3'] = Var_Node['N1']
Var_Arc['N2N5'] = Var_Node['N2']
Var_Arc['N2N7'] = Var_Node['N2']
To implement the constraint I tried the following two options:为了实现约束,我尝试了以下两个选项:
def Arc_rule(model, node, t):
for arc in model.Set_Nodes_ArcsOut[node]:
return model.Var_Arc[arc, t] == model.Var_Node[node, t]
model.ArcInTemp_rule = Constraint(model.Set_Nodes, model.Set_Time, rule=ArcInTemp_rule)
This option only takes the first position of the list.此选项仅采用列表的第一个 position。 This is probably caused by the return which stops the iteration.这可能是由停止迭代的返回引起的。 Option 2:选项 2:
def _init(model):
for t in model.Set_Time:
for node in model.Set_Nodes_ArcsOut:
yield model.Var_Arcs_TempIn[model.Set_Nodes_ArcsOut[node], t] == model.Var_Nodes_TempMix[node, t]
model.init_conditions = ConstraintList(rule=_init)
This does not work and I get the following error: TypeError: unhashable type: '_InsertionOrderSetData'.这不起作用,我收到以下错误:TypeError: unhashable type: '_InsertionOrderSetData'。 I do not understand because I can do this operation if I do a summation.我不明白,因为如果我做一个求和,我可以做这个操作。 However, iteration seems to be impossible with an abstract model.但是,使用抽象 model 似乎不可能进行迭代。
I rephrased the problem and illustrated it based on the pyomo example.我重新表述了这个问题,并根据 pyomo 示例对其进行了说明。 The tryRule is what I needed: tryRule 是我需要的:
import pyomo.environ as pyo
model = pyo.AbstractModel()
model.Nodes = pyo.Set()
model.Arcs = pyo.Set(dimen=2)
def NodesOut_init(m, node):
for i, j in m.Arcs:
if i == node:
yield j
model.NodesOut = pyo.Set(model.Nodes, initialize=NodesOut_init)
def NodesIn_init(m, node):
for i, j in m.Arcs:
if j == node:
yield i
model.NodesIn = pyo.Set(model.Nodes, initialize=NodesIn_init)
model.Flow = pyo.Var(model.Arcs, domain=pyo.NonNegativeReals)
model.NodeFlow = pyo.Var(model.Nodes, domain=pyo.NonNegativeReals)
model.FlowCost = pyo.Param(model.Arcs)
model.Demand = pyo.Param(model.Nodes)
model.Supply = pyo.Param(model.Nodes)
def Obj_rule(m):
return pyo.summation(m.FlowCost, m.Flow)
model.Obj = pyo.Objective(rule=Obj_rule, sense=pyo.minimize)
def tryRule(m, i, j):
return m.Flow[i, j] == m.NodeFlow[i]
model.tryRule = pyo.Constraint(model.Arcs, rule=tryRule)
def FlowBalance_rule(m, node):
return m.Supply[node] \
+ sum(m.Flow[i, node] for i in m.NodesIn[node]) \
- m.Demand[node] \
- sum(m.Flow[node, j] for j in m.NodesOut[node]) \
== 0
model.FlowBalance = pyo.Constraint(model.Nodes, rule=FlowBalance_rule)
dict_data = {
None: {
'Nodes': {None: ['CityA', 'CityB', 'CityC']},
'Arcs': {None: [('CityA', 'CityB'), ('CityA', 'CityC'), ('CityC', 'CityB')]},
'FlowCost': {
('CityA', 'CityB'): 1.4,
('CityA', 'CityC'): 2.7,
('CityC', 'CityB'): 1.6,
},
'Demand': {
'CityA': 0,
'CityB': 1,
'CityC': 1,
},
'Supply': {
'CityA': 2,
'CityB': 0,
'CityC': 0,
}
}
}
# create instance
instance = model.create_instance(dict_data)
instance.pprint()
The result for the rule is:规则的结果是:
tryRule : Size=3, Index=Arcs, Active=True
Key : Lower : Body : Upper : Active
('CityA', 'CityB') : 0.0 : Flow[CityA,CityB] - NodeFlow[CityA] : 0.0 : True
('CityA', 'CityC') : 0.0 : Flow[CityA,CityC] - NodeFlow[CityA] : 0.0 : True
('CityC', 'CityB') : 0.0 : Flow[CityC,CityB] - NodeFlow[CityC] : 0.0 : True
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.