Ограничение, которое вызывает предыдущий / следующий элемент набора в индексированном наборе

Этот пример каким-то образом также работает с (строковыми) индексированными наборами? В моем случае я получаю следующую ошибку:

Объект IndexedSet не имеет атрибута next

Рабочий пример с неиндексированными наборами:

m.s = Set(initialize=['A','B','C'], ordered=True)
m.v = Var(m.s)

def _c_rule(m, i):
    if i == 'A':
        return Constraint.Skip
    return m.v[i] <= m.v[m.s.prev(i)]
m.c = Constraint(m.s, rule=_c_rule)

# Or the opposite way
def _c2_rule(m, i):
    if i == 'C':
        return Constraint.Skip
    return m.v[m.s.next(i)] <= m.v[i]
m.c2 = Constraint(m.s, rule=_c2_rule)

src: Constraint that calls for the previous set member

Не работает:

model = ConcreteModel()


model.S = Set(("A", "B", "C"),initialize=("A", "B", "C"), ordered=True)

print(model.S.next(model.S["A"]))

Если нет, есть ли обходной путь?

Не могли бы вы показать код, который не работает, вместо кода, который работает?

Bethany Nicholson 13.09.2018 18:52

Отредактировано! и добавил

G. Maen 14.09.2018 13:13
0
2
366
1

Ответы 1

Я бы рекомендовал пересмотреть ваше использование проиндексированного Set. Хотя они разрешены в Pyomo, почти всегда есть лучший способ достичь вашей цели, используя неиндексированные компоненты Set или собственные списки Python.

При этом, вот решение вашего вопроса. Проблема в том, что вы: 1) нарушаете некоторую закулисную обработку, которая выполняется, когда вы объявляете компонент Pyomo, и 2) вы неправильно понимаете, для чего может быть вызвана функция next.

Чтобы начать с первой проблемы, ожидается, что компоненты Pyomo будут индексироваться компонентами Pyomo Set. Хотя мы позволяем вам объявлять наборы индексирования для компонентов Pyomo с использованием собственных наборов, списков и кортежей Python, внутренняя часть Pyomo создает для вас компонент Set, если вы его не передали. Это означает, что когда вы пишете следующий:

m.s = Set(('A','B','C'), initialize=['D','E','F'])

Фактически вы получаете два компонента Set в модели: тот, который вы объявили, и тот, который Pyomo неявно создал для хранения ['A','B','C']. Вы можете убедиться в этом, если у вас pprint модель:

>>> m.pprint()
2 Set Declarations
s : Dim=1, Dimen=1, Size=9, Domain=None, ArraySize=3, Ordered=Insertion, Bounds=None
    Key : Members
      A : ['D', 'E', 'F']
      B : ['D', 'E', 'F']
      C : ['D', 'E', 'F']
s_index : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=None
    ['A', 'B', 'C']

2 Declarations: s_index s

Проблема в том, что этот неявно созданный набор, s_index, не упорядочен, что означает, что методы next и prev не будут работать с ним. Итак, чтобы обойти это, вы должны явно объявить этот компонент Set:

m.a = Set(initialize=['A','B','C'], ordered=True)
m.s = Set(m.a, initialize=['D','E','F'], ordered=True)

Вторая часть проблемы заключается в том, что методы next и prev могут быть вызваны только на элементы компонента Set, но не на индексы. Это означает, что следующие строки будут работать:

print(m.s['A'].next('D'))
print(m.s[m.a.next('A')])

но этого не будет:

print(m.s.next('D'))

Другие вопросы по теме