AMPL难以使用“计数”从约束中编写目标

时间:2014-07-20 22:46:10

标签: mathematical-optimization linear-programming solver cplex ampl

我试图解决AMPL中的一个小问题,但我遇到了一个难以解决的问题,我无法将其转化为约束。问题是: 假设我有3组 A B C 。我想将 A 中的元素链接到 B 中的元素,以便 A 中不超过2个元素链接到 B 如果它们存在于 C 的1个子集中( C 的任何子集中3个元素中最多2个链接到中的1个元素乙)。 我已经完成了这部分

假设我写了这个约束:

subject to constr {(i,j,k) in C, b in B}: x[i,b] + x[j,b] + x[k,b] <= 2;

我希望代码的目标能够最大化{(i,j,k) in C, b in B}: x[i,b] + x[j,b] + x[k,b] <= 1;

的情况

或换句话说,最小化以下情况:

{(i,j,k) in C, b in B}: x[i,b] + x[j,b] + x[k,b] = 2;

我怎样才能写出这个目标?如果我希望(约束为 = 2 )&lt; =到一个常数(例如MAX)的次数,我该怎么办呢?下面是我到目前为止编写的代码。我使用的是学生版的AMPL和学生版的cplex。感谢您的帮助,并提前致谢。

set A;
set B;
set C within A cross A cross A;
param constant:= 5;
var x{A,B} binary;
subject to constr1 {(i,j,k) in C, b in B}: x[i,b]  + x[j,b] + x[k,b] <= 2;
subject to onlyOneLinkForEachElementInA {a in A}: sum{b in B} x[a,b] = 1;
data;
set A:= 0 a b c d e f;  #note that 0 is used only to pad the subsets and force them to have dimension of 3
set B:= 1 2 3;
set C: 0 a b c d e f:=
(a,b,c) (a,c,0) (c,d,0) (e,f,b) (a,b,0) (f,b,0);
solve;
for {i in A :i!=0} { printf "%s\t",i;for{c in B} {if x[i,c]=1 then printf "%s\n",c;}};

我尝试了这个,但它没有工作(工作数量也没有):

subject to constr2 {b in B}: count {(i,j,k) in C} ( (x[i,b] + x[j,b] + x[k,b]) = 2 ) <= MAX;其中MAX声明为:

param MAX:= 5;

1 个答案:

答案 0 :(得分:2)

您只能优化线性和(某些)二次表达式。因为您正在尝试最小化次数 x[i,b] + x[j,b] + x[k,b] == 2,您需要一个额外的指标变量。

var has_2{C} binary;
minimize has_2 sum((i,j,k) in C) not_2[i,j,k]
subject to constr1 {(i,j,k) in C, b in B}: x[i,b] + x[j,b] + x[k,b] - has_2[i,j,k] <= 1
如果两个x变量为1,则constr1强制has_2为1.如果0或1的x变量为1,则目标将强制has_2为0.如果x变量已经是二进制,然后你可能最好使has_2连续上限为1,特别是考虑到有更多的has_2变量而不是x变量。