【发布时间】:2014-11-23 20:10:27
【问题描述】:
我正在做一个优化项目,但遇到了一个小问题。对于我的项目,我使用 AMPL 和 CPLEX 作为求解器。在我的代码中,我有一些由 e1、e2、...、en 表示的元素。我还有一个集合,其中包含这些元素中的元组。我必须为每个元素分配一个介于 1 和 'n' 之间的数字,以便最大化 moveTuples 集中 1 个元组中每 2 个元素之间的距离(我需要对它们进行排序,但尽量保持同一个元组中元素之间的距离) .
每个元素必须只有 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) 从 e2 中移动 e1。运行前面的代码时,我收到错误:...包含非二次非线性约束(绝对是“moveApart”约束)。你能指导我如何解决这个问题吗?提前致谢。
【问题讨论】:
-
如果你使用平方差而不是绝对差,它会返回一个解决方案吗?我也不明白你为什么要使用约束,难道不能只使用“最大化 obj: sum {(A,B) in moveTuples} abs(sum{i in Numbers}(assign[A,i]*i ) - (sum{j in Numbers}x[B,j]*j));" (或对应的平方差目标函数)?
-
谢谢先生。使用建议的目标不起作用,所以我不得不对其进行一些修改才能工作。
maximize obj: sum {(A,B) in moveTuples, i in Numbers, j in Numbers: i != j} (assign[B,j]*assign[A,i]*num(i) - assign[A,i]*assign[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 是连续的。
标签: optimization constraints mathematical-optimization cplex ampl