简体   繁体   English

如何遍历约束中的集合?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM