Pyomo ValueError: недопустимое выражение ограничения

Я пишу целочисленную программу pyomo с ограничением в форме:

def example_rule(model, j, t):
    value = sum(model.x[j,i]*(util[i][t]) for i in model.F)
    return 0 <= value <= 1
model.onelateral = Constraint(model.L, model.T, rule=example_rule)

util[i][t] - это словарь, содержащий значения, которые всегда равны 0 или 1. model.x[j,i] - это двоичная переменная решения.

Иногда, когда я запускаю свою модель, она работает нормально. Однако иногда, когда я изменяю размеры / значения в util[i][t], возникает такая ошибка:

ERROR: Constructing component 'example' from data=None failed:
    ValueError: Invalid constraint expression. The constraint expression resolved to a trivial Boolean (True) instead of a Pyomo object. Please modify your rule to return Constraint.Feasible instead of True.

Error thrown for Constraint 'example[L01]'

Я не могу найти никакой последовательности в том, почему он решает, что ему не нравятся входные значения для util[i][t]. Там никогда не бывает нулевых значений.

Если я запустил модель без этого ограничения, она все время будет работать нормально.

Я также попытался написать ограничение в форме:

def example_rule(model,j):
    a = 0
    for t in model.T:
        n = 0
        for i in model.F:
            if model.x[j,i].value == 1:
                a = model.x[j,i] * util[i][t]
            if a == 1:
                n = n + a
    return 0 <= n <= 1
model.example = Constraint(model.L, rule=example_rule)

Но я получаю то же сообщение об ошибке.

Я посмотрел здесь: https://groups.google.com/forum/#!msg/pyomo-forum/hZXDf7xGnTI/_aiAUN5IwgQJ Но это мне не помогло.

Я пробовал это с помощью решателей cbc и glpk. Я использую Pyomo V5.2, Python V3.6.1.

Заранее благодарю за вашу помощь.


person fishy321    schedule 10.08.2017    source источник


Ответы (2)


Есть ли у вас случаи, когда util [i] [t] равен нулю по всем i для определенного t? Термины, умноженные на ноль, автоматически удаляются из выражения, поэтому я предполагаю, что ваша ошибка вызвана случаем, когда 'value' заканчивается равным нулю, и в этом случае 0 ‹= value‹ = 1 вернет тривиальное логическое значение.

Самый простой способ исправить это - официально объявить util как компонент Param и добавить mutable=True в объявление. Это сигнализирует Pyomo о том, что вы можете изменить значение параметра util и, следовательно, позволяет избежать автоматического упрощения нулевых значений.

m.util = Param(m.F, m.T, initialize=util_init, mutable=True)

Другой способ - проверить значения util и пропустить ограничение, если весь столбец равен нулю.

def example_rule(model, j, t):
    if not any(util[i][t] for i in model.F):
        return Constraint.Skip
    temp = sum(model.x[j,i]*(util[i][t]) for i in model.F)
    return 0 <= temp <= 1
model.onelateral = Constraint(model.L, model.T, rule=example_rule)
person Bethany Nicholson    schedule 10.08.2017
comment
Спасибо, @ Bethany-Nicholson, похоже, это проблема. Я не знаю, как это обойти ... есть идеи? Я попытался установить значение 1, если суммирование было решено до 0, но это не понравилось. - person fishy321; 11.08.2017
comment
Для меня это все еще не имеет смысла :-( После устранения этой конкретной ошибки (используя метод из моего ответа ниже ... который я не знаю, почему это сработало), я получаю ту же проблему с другим из моих ограничений. Однако на этот раз мой ответ ниже не решает проблему. Я не могу понять, почему 0 ограничений автоматически удаляется? Есть ли способ отключить эту опцию? - person fishy321; 15.08.2017
comment
@ fishy321 Я отредактировал свой ответ, чтобы показать два возможных исправления. - person Bethany Nicholson; 16.08.2017

Я заставил его работать, изменив объявление ограничения на это:

def example_rule(model,j,t):
    return (0,sum(model.x[j,i]*(util1[i][t]) for i in model.F),1)
model.example = Constraint(model.L, model.T, rule=example_rule)

К сожалению, я не знаю, почему это сработало, а предыдущее - нет!

person fishy321    schedule 11.08.2017