Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 消除pyomo模型中的等式约束_Python_Mathematical Optimization_Pyomo - Fatal编程技术网

Python 消除pyomo模型中的等式约束

Python 消除pyomo模型中的等式约束,python,mathematical-optimization,pyomo,Python,Mathematical Optimization,Pyomo,我想通过替换消除pyomo模型中积分变量的线性等式约束。例如,我希望转换模型 通过替换 (*) 到 有没有办法在pyomo模型中执行这种替换?我将能够通过计算相应的线性丢番图方程组的解空间来获得(*),其形式为y=const_vec+susbtitution_matrix*eta,其中在我们的示例中 const_vec = np.array([1,0,0]) substitution_matrix = np.array([[-1,0],

我想通过替换消除pyomo模型中积分变量的线性等式约束。例如,我希望转换模型

通过替换

(*)

有没有办法在pyomo模型中执行这种替换?我将能够通过计算相应的线性丢番图方程组的解空间来获得(*),其形式为
y=const_vec+susbtitution_matrix*eta
,其中在我们的示例中

const_vec = np.array([1,0,0])
substitution_matrix = np.array([[-1,0],
                                [1,0],
                                [0,1]])

您所描述的内容通常被称为“变量聚合”。正如您所指出的,有四个基本步骤:

  • 确定要删除的线性等式
  • 计算替换映射
  • 停用要删除的相等约束
  • 替换所有剩余约束上的变量
  • 听起来好像你控制了1和2。对于3,假设您确定了要停用的约束
    m.c
    ,只需调用
    m.c.deactivate()

    对于4,您将希望为剩余的约束“
    body
    ”表达式生成新表达式(变量仅显示在body中,而不显示在下限/上限中)。对于当前的Pyomo版本(通过5.4.x),可以通过利用
    clone\u expression()
    执行变量替换。您需要生成一个“替换映射”:一个dict,它将您想要的变量的
    id()
    映射到您想要使用的新表达式。例如:

    from pyomo.core.base.expr import clone_expression
    
    m = ConcreteModel()
    m.y = Var([1,2,3])
    m.eta = Var([1,2])
    # ...
    m.c = Constraint(expr=m.y[1]**2 + m.y[3]**2 <= 4)
    # ...
    
    substitution_map = {
        id(m.y[1]): 1 - m.eta[1],
        id(m.y[2]): m.eta[1],
        id(m.y[3]): m.eta[2],
    }
    m.c = (m.c.lower, clone_expression(m.c.body, substitute=substitution_map), m.c.upper)
    
    从pyomo.core.base.expr导入克隆\表达式
    m=混凝土模型()
    m、 y=Var([1,2,3])
    m、 eta=Var([1,2])
    # ...
    
    m、 c=约束(expr=m.y[1]**2+m.y[3]**2最好由解算器来解决。如果我关心的是解决模型,你肯定是对的。但是,我正在测试一种高级算法,用于解决混合整数优化问题,该算法仅在从模型中消除积分变量的等式约束时才有效。简短回答是的。有一个
    替代表达式的功能,以及检测线性等式约束的方法,但据我所知,还没有任何方法能够完全满足您的要求。我知道如何检测线性等式约束,因此如果您能演示如何使用
    替换
    表达式的功能,我将非常高兴。无论如何,感谢您的评论。Thanks对此解释不敢苟同!我仍在努力“自动化”第3步和第4步(事实上,只有示例的最后一行会引起麻烦)。我认为我失败的主要原因是我操纵了一个引用,而不是模型对象本身。我使用了一些行,如
    constraints=list(m.component\u objects(Constraint,active=True))
    然后操作此列表中的约束。您能指出如何正确操作模型中的约束吗?另外,实际删除相应的已消除约束(即使用
    del m.c
    )也会有好处。没有理由删除约束,只需禁用它们将阻止它们发送到解算器。至于以常规方式操纵所有约束,类似于m.componsnt_数据_对象(约束,活动=真)中c的
    :c.set_值((c.lower,clone_表达式(c.body),c.upper))
    可能会接近您想要的效果。诀窍是使用
    组件\u数据\u对象
    ,因为这会处理“展开”问题标量约束和索引约束。再次感谢。对我来说,停用约束有一定的意义。不深入讨论-我们做了一些类似于凸MINLPs的扩展剖切面方法的事情:停用非线性约束,将线性模型传递给解算器,然后检查非线性约束在某些情况下是否得到满足线性模型的最小值。如果不是,我们添加一个切割平面。但是,显式使用非线性,停用等式约束就足够了。因为我需要计算违反约束函数的梯度,删除删除的变量似乎是有益的。这可能吗?是:您应该能够使用
    del
    block.del_component()
    。您需要小心使用索引约束,因为删除组件会删除所有约束。如果您只想删除一个约束,则可以执行类似于
    block.c[i]=Constraint.Skip的操作(但这仅适用于Pyomo的最新版本)。当我执行类似操作时,我经常克隆整个模型,而不是在适当的位置执行所有操作,例如GDP切割平面,而不是停用NL约束