Pyomo 中的稀疏集用于表示 graph/network 模型中的弧/边集

Sparse sets in Pyomo for representing arc / edge sets in graph/network models

我不知道如何在 pyomo 中定义边集。

我有一个极低密度(稀疏)网络(又名图),其中的边数比完全连接的图少得多。

我想定义一个边集,这样我就可以构造与边有关的约束。然而,我无法全神贯注于 pyomo 期望我做什么,我所做的一切都会导致令人难以置信的无用错误消息。

import pyomo
import pyomo.environ as pe
edges = [(0,1),(0,2),(1,2),(2,3),(2,4),(3,4)]

model = pe.ConcreteModel()
model.E = pe.Set(initialize=lambda _,i : edges[i]) # Edge set

以上代码抛出错误

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Joey\Python37\lib\site-packages\pyomo\core\base\block.py", line 568, in __setattr__
    self.add_component(name, val)
  File "C:\Users\Joey\Python37\lib\site-packages\pyomo\core\base\block.py", line 1008, in add_component
    val.construct(data)
  File "C:\Users\Joey\Python37\lib\site-packages\pyomo\core\base\sets.py", line 1221, in construct
    self.add(val)
  File "C:\Users\Joey\Python37\lib\site-packages\pyomo\core\base\sets.py", line 821, in add
    self._verify(tmp)
  File "C:\Users\Joey\Python37\lib\site-packages\pyomo\core\base\sets.py", line 772, in _verify
    raise ValueError("The value="+str(element)+" is a tuple for set="+self.name+", which has dimen="+str(self.dimen))
ValueError: The value=(0, 2) is a tuple for set=E, which has dimen=1

给定的边完全由元组标识。连接节点0和节点1的边应该是(0,1)。该元组应该是它的标识符。此类标识符的列表具有维度 1。所以我不确定 pyomo 期望我做什么。

所以原来dim是集合本身的维度。 dimen是每个集合元素必须包含的元素个数,而不是集合的维数。 Pyomo 默认假定 dimen=1,这意味着 Set 不会接受元组作为集合元素,因为它有多个元素。设置 dimen=None 禁用此参数检查。

因此,一种方法是传递 initialize 的边列表,维度为 2 或 None

model.E = pe.Set(initialize=edges, dimen=2)

集合构造函数不知道元素的数量,所以这实际上不起作用:

model.E = pe.Set(initialize=lambda _,i: edges[i], dimen=2) # Edge set

错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Joey\Python37\lib\site-packages\pyomo\core\base\block.py", line 568, in __setattr__
    self.add_component(name, val)
  File "C:\Users\Joey\Python37\lib\site-packages\pyomo\core\base\block.py", line 1008, in add_component
    val.construct(data)
  File "C:\Users\Joey\Python37\lib\site-packages\pyomo\core\base\sets.py", line 1223, in construct
    val = apply_indexed_rule(self, self.initialize, self._parent(), ctr)
  File "C:\Users\Joey\Python37\lib\site-packages\pyomo\core\base\misc.py", line 61, in apply_indexed_rule
    return rule(model, index)
  File "<stdin>", line 1, in <lambda>
IndexError: list index out of range

所以你必须使用

model.E = pe.Set(initialize=
    (edges[i] for i in range(len(edges))), dimen=2) # Edge set