我把它翻译成一个约束 . 问题是:假设我有3套 A , B 和 C . 我想将 A 中的元素链接到 B 中的元素,以便 A 中的不超过2个元素链接到 B 中的单个元素(如果它们存在于 C 的1个子集中)( C 的任何子集中3个元素中最多2个是链接到 B )中的1个元素 . I already did this part
假设我写了这个约束:
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 )<=的次数设为常数(例如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 回答
您只能优化线性和(某些)二次表达式 . 由于您试图最小化次数
x[i,b] + x[j,b] + x[k,b] == 2
,因此您需要一个额外的指示变量 .如果两个x变量为1,则constr1 force has_2为1.如果0或1的x变量为1,则目标将强制has_2为0.如果你的
x
变量已经是二进制,那么你可能会更好has_2连续,上限为1,特别是考虑到有多于2个变量而不是x
变量 .