Я хочу оценить, соблюдается ли ограничение в Pyomo или нет, когда известны значения переменных, содержащихся в выражении ограничения.
Вариант использования: мы знаем, что одно конкретное ограничение иногда делает проблему невыполнимой, в зависимости от значения переменной. Вместо того, чтобы отправлять проблему в решатель, чтобы проверить, разрешима ли проблема, преобразования выражения ограничения в логический тип было бы достаточно, чтобы определить, является ли ограничение виновником.
Ради предоставления возможного примера, вот код:
from pyomo.environ import ConcreteModel, Var, Constraint
model = ConcreteModel()
model.X = Var()
def constraint_rule(model):
return model.X <= 1
model.a_constraint = Constraint(rule=constraint_rule)
Теперь давайте попробуем работать с выражением для оценки:
# Let's define the expression in this way:
expression = constraint_rule(model)
# Let's show that the expression is what we expected:
print(str(expression))
Предыдущий оператор должен вывести X <= 1.0
.
Теперь сложная часть заключается в том, как вычислить выражение.
if expression == True:
print("feasible")
else:
print("infeasible")
создает исключение TypeError (TypeError: Cannot create an EqualityExpression where one of the sub-expressions is a relational expression: X <= 1.0
).
Последний пример не работает, потому что constraint_rule
возвращает не логическое значение, а выражение Pyomo.
Наконец, я знаю, что что-то вроде
def evaluate_constraint_a_expression(model):
return value(model.X) <= 1
будет работать, но я не могу предположить, что всегда буду знать содержание моего выражения ограничения, поэтому мне нужен надежный способ его оценки.
Есть ли умный способ добиться этого? Например, вычисление выражения как логического значения и одновременное вычисление левой и правой частей выражения?
Ну, может быть, мой пример был слишком минимален. Я написал model.X<=3
, думая, что это было достаточно коротко, чтобы избежать недоразумений, но ограничение может быть буквально любым, от наличия нескольких переменных как слева, так и справа, до наличия другого знака (>=, ==) и так далее. . Я не могу предположить, что знаю выражение ограничения, иначе я бы уже попробовал value(model.X) <= 3
, что я не хочу реализовывать для всех ограничений.
завтра выложу mcve
Хорошо, после более внимательного прочтения я попробовал numvalue.value(constraint_rule(model))
, как вы предложили, и он работает даже если выражение не возвращает числовое значение, и даже если value()
применяется как к левой, так и к правой стороне одновременно. Это означает, что numvalue.value(model.X <= 1)
возвращает True
или False
, в зависимости от значения model.X
.
Рад слышать это. Не забывайте, что вы можете ответить на свой вопрос (и принять свой ответ).
Решение состоит в том, чтобы использовать функцию value
. Даже если он говорит, что оценивает выражение в числовое значение, он также преобразует выражение в логическое значение, если оно является выражением равенства/неравенства, как правило ограничения.
Чтобы заставить его работать, ему нужно импортировать функцию value
в модуль numvalue
. Предположим, что модель определена так, как в вопросе, тогда остальная часть кода должна быть:
from pyomo.core.kernel.numvalue import value
if value(expression) == True:
print("feasible")
else:
print("infeasible")
где expression
определяется так, как написано в вопросе.
Однако имейте в виду, что числовая точность в Python, использующая этот метод, может отличаться от точности, предоставляемой решателем. Поэтому вполне возможно, что этот метод покажет, что ограничение невыполнимо, хотя это всего лишь вопрос числовой неточности менее 1e-10. Таким образом, хотя это полезно для определения того, выполнимо ли большинство ограничений, оно также приводит к некоторым ложным срабатываниям.
Вы пытаетесь оценить значение левой части ограничения для фиксированных значений переменных, верно? Помогает ли функция
pyomo
value()
? Может быть, вы могли бы опубликовать Макви?