当约束表达式中包含的变量的值已知时,我想评估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
可以工作,但是我不能假设我将永远知道约束表达式的内容,因此我需要一种可靠的评估方式。
是否有实现此目标的聪明方法?例如,将表达式评估为布尔值并同时评估表达式的左手边和右手边?
答案 0 :(得分:0)
解决方案是使用value
函数。即使它说它对一个表达式求值是一个数值,但如果它是一个等式/不等式表达式(如约束规则),它也会将该表达式转换为布尔值。
要使其正常工作,需要在value
模块中导入numvalue
函数。假设以问题中的方式定义模型,那么其余代码应为:
from pyomo.core.kernel.numvalue import value
if value(expression) == True:
print("feasible")
else:
print("infeasible")
其中expression
的定义与问题中的定义相同。
但是,建议使用此方法的Python中的数字精度可能不同于求解器提供的精度。因此,这种方法有可能表明约束是不可行的,而只是数字不精确度低于1e-10的问题。因此,虽然有助于确定大多数约束是否可行,但也会产生一些误报。