Разреженные множества в Pyomo для представления множеств дуг / ребер в моделях графа / сети - PullRequest
0 голосов
/ 26 сентября 2019

Понятия не имею, как определить набор ребер в 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 ожидает от меня.

1 Ответ

0 голосов
/ 26 сентября 2019

Итак, получается, что dim - это размерность самого набора.dimen - это количество элементов, которое должен содержать каждый элемент набора, а не размерность набора.Pyomo по умолчанию предполагает, что dimen=1, что означает, что Set не будет принимать кортеж в качестве элемента 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
...