Optimization 如何区分正负变量?

Optimization 如何区分正负变量?,optimization,linear-programming,ampl,glpk,Optimization,Linear Programming,Ampl,Glpk,让我有一个变量UT[I,j,k,r],它定义为其他两个变量的和 UT[i,j,k,r]= U[i,j,k,r]+D[i,j,k,r] 现在我想为正UT[I,j,k,r]写一些约束!我能做什么 我尝试了很多方法:我定义了一个二进制变量,如果UT为正,则为1,否则为0,但这并没有解决我的问题,因为将它们相乘很复杂。有没有办法存储UT为正的索引?假设BT[i,j,k,r]是二进制变量。然后,如果您使用CPLEX、Gurobi或Xpress作为解算器,则可以编写如下“指示符约束”: BT[i,j,k,

让我有一个变量UT[I,j,k,r],它定义为其他两个变量的和

UT[i,j,k,r]= U[i,j,k,r]+D[i,j,k,r]
现在我想为正UT[I,j,k,r]写一些约束!我能做什么


我尝试了很多方法:我定义了一个二进制变量,如果UT为正,则为1,否则为0,但这并没有解决我的问题,因为将它们相乘很复杂。有没有办法存储UT为正的索引?

假设
BT[i,j,k,r]
是二进制变量。然后,如果您使用CPLEX、Gurobi或Xpress作为解算器,则可以编写如下“指示符约束”:

BT[i,j,k,r]=1==>*你的约束*


这是最简单的方法。或者,对于任何解算器,如果约束是线性的,则可以将指示器约束转换为等效的线性约束,而无需将二进制变量乘以任何其他变量。(如果您的约束是非线性的,那么也可能存在转换。)要了解这些转换是如何完成的,请参阅@LarrySnyder610 To的答案。

假设
BT[i,j,k,r]
是您的二进制变量。然后,如果您使用CPLEX、Gurobi或Xpress作为解算器,则可以编写如下“指示符约束”:

BT[i,j,k,r]=1==>*你的约束*


这是最简单的方法。或者,对于任何解算器,如果约束是线性的,则可以将指示器约束转换为等效的线性约束,而无需将二进制变量乘以任何其他变量。(如果您的约束是非线性的,那么也可能存在转换。)要了解此类转换是如何完成的,请参阅@LarrySnyder610 To的答案。

一个选项是将UT分为两部分:UTplus和UTminus,两者都>=0。然后定义UT=UTplus-UTminus

现在,您需要添加一个约束,该约束表示两个约束中最多有一个可以是非零的。有几个选项可供选择:


  • 您可以像您建议的和4er解释的那样使用指示符约束。使用二进制辅助变量指示,如果该变量为1,则ut减号必须为零;如果辅助变量为0,则UTplus必须为零。如果可以为UTplus和UTminus推导一个上界M,那么也可以添加一个约束
    UTplus一个选项是将UT分成两部分:UTplus和UTminus,两者都>=0。然后定义UT=UTplus-UTminus

    现在,您需要添加一个约束,该约束表示两个约束中最多有一个可以是非零的。有几个选项可供选择:


  • 您可以像您建议的和4er解释的那样使用指示符约束。使用二进制辅助变量指示,如果该变量为1,则ut减号必须为零;如果辅助变量为0,则UTplus必须为零。如果您可以为UTplus和UTminus推导一个上界M,那么您也可以只添加一个约束
    UTplus。关于如何基于另一个决策变量激活/停用约束,有一些讨论;4er关于如何在AMPL中轻松实现这一点的评论可能特别有用。我在AMPL用户论坛上回答了这个问题,因此我将以适合堆栈交换的形式在这里发布它。这里讨论了如何基于另一个决策变量激活/取消激活约束;4er关于如何在AMPL中轻松实现这一点的评论可能特别有用。我在AMPL用户论坛上回答了这个问题,所以我将以适合堆栈交换的形式在这里发布它。