【发布时间】:2014-07-16 06:13:36
【问题描述】:
我正在学习 AMPL,以便稍后在我的程序中使用它。我有一个小问题想解决。正如标题所述,我正在尝试使用一些迭代操作来最小化约束的数量。所以问题如下: 假设我有 2 套 A 和 B 并假设我有代码:
set A:= (1, 2, 3) (4, 5, 6);
set B:= a b c;
var x{A,B} binary;
**some_objective** ;
subject to constraint { (i,j,k) in A, b in B }: x[i,b] + x[j,b] + x[k,b] <= 1;
现在如果我们扩展之前的约束,将形成以下约束:
x[1,a] + x[2,a] + x[3,a] <=1;
x[1,b] + x[2,b] + x[3,b] <=1;
x[1,c] + x[2,c] + x[3,c] <=1;
x[4,a] + x[5,a] + x[6,a] <=1;
x[4,b] + x[5,b] + x[6,b] <=1;
x[4,c] + x[5,c] + x[6,c] <=1;
这意味着,对于 A 中的 y 子集和 B 中的 z 元素,我们将得到一个总数y*z 个约束(在我们的例子中是 2 x 3 = 6 个约束)。
现在如果我们将约束更改为:
subject to constraint { (i,j,k) in A }: prod { b in B } (x[i,b] + x[j,b] + x[k,b]) <= 1;
这将导致:
{(x[1,a] + x[2,a] + x[3,a]) * (x[1,b] + x[2,b] + x[3,b]) * (x[1,c] + x[2,c] + x[3,c])} <= 1;
{(x[4,a] + x[5,a] + x[6,a]) * (x[4,b] + x[5,b] + x[6,b]) * (x[4,c] + x[5,c] + x[6,c])} <= 1;
它应该与以前的形式具有相同的结果,但我们将约束的数量从 y*z 减少到 y,这是一个很好的改进! 另一个改进是在逻辑上和约束:
subject to constraint { (i,j,k) in A }: forall { b in B } ( (x[i,b] + x[j,b] + x[k,b]) <= 1 );
这将导致:
{(x[1,a] + x[2,a] + x[3,a]) <= 1} && {(x[1,b] + x[2,b] + x[3,b]) <= 1} && {(x[1,c] + x[2,c] + x[3,c]) <= 1};
{(x[4,a] + x[5,a] + x[6,a]) <= 1} && {(x[4,b] + x[5,b] + x[6,b]) <= 1} && {(x[4,c] + x[5,c] + x[6,c]) <= 1};
问题是,当我们这样做时,我们正在将问题从线性或二次方程变为非二次方程,而 cplex 无法再解决它:/
是否有任何变通方法或任何技巧可以让我在不将问题转换为非二次问题的情况下做到这一点(至少要使用 cplex 来解决)?
x[1,a] + x[1,b] + x[1,c] = 1 也很有用,对于 A 中的任何其他元素也是如此。感谢您的帮助,并提前感谢您。
【问题讨论】:
标签: optimization mathematical-optimization minimization ampl