1

我正在研究一个优化项目,并遇到一个小问题。对于我的项目,我使用AMPL和CPLEX作为求解器。在我的代码中,我有一些由e1,e2,...,en表示的元素。我也有一个包含这些元素内的元组的集合。我必须给每个元素分配一个1到'n'之间的数字,这样我可以最大化moveTuples集中1个元组中每2个元素之间的距离(我需要对它们进行排序,但试图保持同一元组中元素之间的距离) 。使用cplex的AMPL非二次非线性约束

每个元素必须只有1个分配号码,每个号码只能给1个元素。为此,我写了下面的代码:

set Elements; 
set moveTuples dimen 2; 
set Numbers; 

var assign {Elements,Numbers} binary; 
var maximizer{moveTuples} integer >= 0; 

maximize obj: sum {(A,B) in moveTuples} maximizer[A,B]; 

subject to assign1NumberPerElement {i in Element}: sum {c in Numbers} assign[i,c] = 1; 
subject to assign1ElementPerNumber {c in Numbers}: sum {i in Element} assign[i,c] = 1; 


subject to moveApart {(A,B) in moveTuples}: abs(sum{i in Numbers}(assign[A,i]*i) - (sum{j in Numbers}x[B,j]*j)) - maximizer[A,B] = 0 ; 

data; 

set Elements:= e1 e2 e3; 
set Numbers:= 1 2 3; 
set moveTuples: e1 e2 e3:= 
(e1, e2); 


solve; 

display assign; 

现在的问题是明确的,对于前面的例子中,输出必须是:

E1 - > 1

E2 - > 3

E3 - > 2

E1 - > 3

E2 - > 1

E3 - > 2

,因为它需要仅E1 E2从使用所述元组移动(E1,E2)。运行前面的代码时,我得到错误:...包含非二次非线性约束(绝对是“moveApart”约束)。你能指导我如何解决这个问题吗?提前致谢。

+0

如果使用平方差而不是绝对差值,它会返回一个解决方案吗?我也不明白为什么你打扰使用约束,是不可能仅仅使用“在MoveTuples中使用”最大化obj:sum {(A,B)} abs(sum {数组中的我}(assign [A,i] * i ) - (sum {j in Numbers} x [B,j] * j));“ (或相应的平方差目标函数)? – 2014-11-23 21:34:06

+0

谢谢先生。使用建议的目标不起作用,所以我必须稍微修改它才能工作。在移动时,最大化obj:sum {(A,B),Numbers中的i,i中的数字:i!= j}(assign [B,j] * assign [A,i] * num(i) - assign [A ,I] *分配[B,J] * NUM(J));'。唯一的问题是假设元组是(e1,e2),(e3,e4),(e2,e5)。现在的目标是6,它是正确的,但正确的顺序必须是(e1,e3,e2,e4,e5),所以同一元组中没有2个元素会相互跟随,目标将保持为6. AMPL生成序列(e5,e4,e2,e1,e3)==> obj = 6,但e1和e2是连续的。 – user3787524 2014-11-23 22:01:16

回答

0

约束moveApart是非线性的(和非二次的),因为它包含对abs的调用。但是,由于你的问题是纯粹的整数,你可以用CPLEX CP Optimizer (ilogcp)来解决它。