我希望n1 = x1 * x2 *x3
在 Gurobi 中添加一个约束,其中x1
和x2
是x3
0 或 1 的变量。不幸的是,找不到解决方案。
有人能帮我吗?
我希望n1 = x1 * x2 *x3
在 Gurobi 中添加一个约束,其中x1
和x2
是x3
0 或 1 的变量。不幸的是,找不到解决方案。
有人能帮我吗?
您正在尝试对二元变量创建看似非线性的约束。您可以将其建模为一系列线性约束,注意n
当且仅当 x1、x2 和 x3 都为 1 时,将具有值 1。
// only if part
model.addConstr(n, GRB.LESS_EQUAL, x1);
model.addConstr(n, GRB.LESS_EQUAL, x2);
model.addConstr(n, GRB.LESS_EQUAL, x3);
// if part
GRBLinExpr all_three;
all_three.addTerm(1.0, x1);
all_three.addTerm(1.0, x2);
all_three.addTerm(1.0, x3);
all_three.addConstrant(-2);
model.addConstr(n, GRB.GREATER_EQUAL, all_three);
这增加了约束
n >= x1 + x2 + x3 - 2
和n <= min(x1, x2, x3)
。
n1<=x1
n1<=x2
n1<=x3
2+n1>=x1+x2+x3
如果 x 中的任何一个为 0,则 n 将强制为零。如果全部为 1,则 n 被强制为 1。
编辑 由于 Gurobi 识别二进制变量,你可以只使用
3*n1<=x1+x2+x3
2+n1>=x1+x2+x3
第一个只允许 0 和 1,而如果不是二进制要求,这将允许小数值。
编辑 约束
n3 = x2 * (n1 + n2 - n1 * n2) + x1 * (n1 - n2) *(n1 - n2)
似乎试图强制执行逻辑
IF n1 AND n2:
n3 = x2
IF n1 XOR n2:
n3 = x1
IF (NOT n1) AND (NOT n2):
n3 = 0
由于在零一整数线性规划 (ILP) 中表示布尔逻辑运算的标准规则采用以下形式x1 AND x2 IMPLIES y1
,因此我将上述内容重构为
n1 AND n2 IMPLIES i1
n1 XOR n2 IMPLIES i2
(NOT n1) AND (NOT n2) IMPLIES i3
构造约束i1, i2, i3
如下
IF n1 AND n2, THEN i1
i1 ≥ n1 + n2 − 1
i1 ≤ n1
i1 ≤ n2
0 ≤ i1 ≤ 1
IF n1 XOR n2, THEN i2
i2 ≤ n1 + n2
i2 ≥ n1 − n2
i2 ≥ n2 − n1
i2 ≤ 2 − n1 − n2
0 ≤ i2 ≤ 1
IF NOT n1 AND NOT n2, THEN i3
i3 ≥ 1 - n1 - n2
i3 ≤ (1 - n1)
i3 ≤ (1 - n2)
0 ≤ i3 ≤ 1
这给出了使用三个互斥指标,原始问题可以重写为
-(1 - i1) ≤ n3 - x2 ≤ (1 - i1)
-(1 - i2) ≤ n3 - x1 ≤ (1 - i2)
-(1 - i3) ≤ n3 ≤ (1 - i3)
简化将二进制字符串转换为整数的方法。并且,乘以它。不好吗?
int x1 = Integer.parseInt("101011", 2);
int x2 = Integer.parseInt("00010", 2);
int x3 = Integer.parseInt("000101", 2);
int n1 = x1 * x2 * x3;
System.out.println(n1);
更新
我不知道Gurobi
,但是
GRBVar x1 = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "x1");
GRBVar x2 = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "x2");
GRBVar x3 = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "x3");