繁体   English   中英

Pyomo 基于索引集创建约束

[英]Pyomo create a constraint based on an indexed set

我有一组约束,如下所示:

for all n in N, for all i in l(n): ...

N 是一组节点,在 Pyomo 的具体 model 中:

model.Nodes = pyo.Set(initialize = range(len(nodes)))

每个节点都有不同的长度。 对于从 0 到其各自范围的每个节点,我需要一个 RangeSet。 这个,我解决如下:

longest_node = max(map(len, nodes))
model.Lengths = pyo.Set(initialize = list(range(longest_node)))
model.NodeRangeSet = pyo.Set(model.nodes, within = model.Lengths, initialize = lambda model, node: list(range(len(nodes[node]))))

例如,它给出了长度为 1、3 和 2 的 3 个节点:

NodeRangeSet : Size=3, Index=Nodes, Ordered=Insertion
    Key : Dimen : Domain   : Size : Members
     0  :     1 : Lengths  :    1 : {0}
     1  :     1 : Lengths  :    3 : {0, 1, 2}
     2  :     1 : Lengths  :    2 : {0, 1}

但我似乎无法根据需要创建一个约束,例如

model.Constr = model.Constraint(model.Nodes, model.NodeRangeSet[model.Nodes]
    rule = lambda model, node, offset: some_condition)

如何正确替换此占位符model.NodeRangeSet[model.Nodes] 节点的数量以及它们的长度仅取决于给定的输入参数。 所以约束中的每个节点都有自己的 RangeSet。 我可以/必须采取完全不同的方法吗?

这是一个我认为很好地涵盖了该主题的示例以及一些变体。 你的问题的基本答案是,如果你想在约束中使用你的索引集,那么只需将它放在约束体(或规则)中并传入索引( node )以获得你想要的。 如果你想“展平它”并为所有组合产生一个约束(这会很奇怪,因为索引集中的值与主集的值相关联),你可以用一个集合制作 2 个集合的乘积理解之类的。

无论如何,下面显示了我将如何为类似问题设置密钥集,一个带有nodes ,另一个由node索引,这是连接,如果需要,可能还有所有合法组合的平面集。

还显示了使用这些约束的 3 styles,具体取决于求和的“数学”以及“每个”语句的含义。

代码

import pyomo.environ as pyo

# some data for nodes & connections for a directed graph
graph = {   1: [2, 3, 4],
            2: [3,],
            3: [1, 4],
            4: [2, 3]
        }
connections = [(s, t) for s in graph.keys() for t in graph[s]]

m = pyo.ConcreteModel('graph')

# SETS
m.N = pyo.Set(initialize=graph.keys())                      # the set of all nodes
m.C = pyo.Set(m.N, within=m.N, initialize=graph)            # set of all connections, indexed by node
m.NN = pyo.Set(within=m.N * m.N, initialize=connections)    # a flat set of all "legal", directed arcs

# VARS
# initializing with only the legal connections keeps this small (it is only 8 members vs. 16)
m.traffic = pyo.Var(m.NN, domain=pyo.NonNegativeReals)

# CONSTRAINTS

# an outbound "traffic" constraint *for each node*
def traffic(m, node):
    return sum(m.traffic[node, other] for other in m.C[node]) <= 4
m.C1 = pyo.Constraint(m.N, rule=traffic)

# a traffic restriction *for each arc*
def arc_traffic(m, node, other):
    return m.traffic[node, other] <= 3
m.C2 = pyo.Constraint(m.NN, rule=arc_traffic)

# flow balance at each node *for each node* using an internally generated set/list
def flow_balance(m, node):
    # we can make an "on the fly" list from model parts, as needed...
    inbound_arcs = [s for (s, other) in m.NN if other==node]
    return sum(m.traffic[s, node] for s in inbound_arcs) == sum(m.traffic[node, t] for t in m.C[node])
m.C3 = pyo.Constraint(m.N, rule=flow_balance)

m.pprint()

产量:

4 Set Declarations
    C : Size=4, Index=N, Ordered=Insertion
        Key : Dimen : Domain : Size : Members
          1 :     1 :      N :    3 : {2, 3, 4}
          2 :     1 :      N :    1 : {3,}
          3 :     1 :      N :    2 : {1, 4}
          4 :     1 :      N :    2 : {2, 3}
    N : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :    4 : {1, 2, 3, 4}
    NN : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain    : Size : Members
        None :     2 : NN_domain :    8 : {(1, 2), (1, 3), (1, 4), (2, 3), (3, 1), (3, 4), (4, 2), (4, 3)}
    NN_domain : Size=1, Index=None, Ordered=True
        Key  : Dimen : Domain : Size : Members
        None :     2 :    N*N :   16 : {(1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (2, 3), (2, 4), (3, 1), (3, 2), (3, 3), (3, 4), (4, 1), (4, 2), (4, 3), (4, 4)}

1 Var Declarations
    traffic : Size=8, Index=NN
        Key    : Lower : Value : Upper : Fixed : Stale : Domain
        (1, 2) :     0 :  None :  None : False :  True : NonNegativeReals
        (1, 3) :     0 :  None :  None : False :  True : NonNegativeReals
        (1, 4) :     0 :  None :  None : False :  True : NonNegativeReals
        (2, 3) :     0 :  None :  None : False :  True : NonNegativeReals
        (3, 1) :     0 :  None :  None : False :  True : NonNegativeReals
        (3, 4) :     0 :  None :  None : False :  True : NonNegativeReals
        (4, 2) :     0 :  None :  None : False :  True : NonNegativeReals
        (4, 3) :     0 :  None :  None : False :  True : NonNegativeReals

3 Constraint Declarations
    C1 : Size=4, Index=N, Active=True
        Key : Lower : Body                                       : Upper : Active
          1 :  -Inf : traffic[1,2] + traffic[1,3] + traffic[1,4] :   4.0 :   True
          2 :  -Inf :                               traffic[2,3] :   4.0 :   True
          3 :  -Inf :                traffic[3,1] + traffic[3,4] :   4.0 :   True
          4 :  -Inf :                traffic[4,2] + traffic[4,3] :   4.0 :   True
    C2 : Size=8, Index=NN, Active=True
        Key    : Lower : Body         : Upper : Active
        (1, 2) :  -Inf : traffic[1,2] :   3.0 :   True
        (1, 3) :  -Inf : traffic[1,3] :   3.0 :   True
        (1, 4) :  -Inf : traffic[1,4] :   3.0 :   True
        (2, 3) :  -Inf : traffic[2,3] :   3.0 :   True
        (3, 1) :  -Inf : traffic[3,1] :   3.0 :   True
        (3, 4) :  -Inf : traffic[3,4] :   3.0 :   True
        (4, 2) :  -Inf : traffic[4,2] :   3.0 :   True
        (4, 3) :  -Inf : traffic[4,3] :   3.0 :   True
    C3 : Size=4, Index=N, Active=True
        Key : Lower : Body                                                                       : Upper : Active
          1 :   0.0 :                traffic[3,1] - (traffic[1,2] + traffic[1,3] + traffic[1,4]) :   0.0 :   True
          2 :   0.0 :                                 traffic[1,2] + traffic[4,2] - traffic[2,3] :   0.0 :   True
          3 :   0.0 : traffic[1,3] + traffic[2,3] + traffic[4,3] - (traffic[3,1] + traffic[3,4]) :   0.0 :   True
          4 :   0.0 :                traffic[1,4] + traffic[3,4] - (traffic[4,2] + traffic[4,3]) :   0.0 :   True

8 Declarations: N C NN_domain NN traffic C1 C2 C3

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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