I'm working on an optimization project and I faced a small problem. For my project, I'm using AMPL and CPLEX as a solver. In my code, I have some elements indicated by e1, e2, ..., en. I also have a set which contains tuples within these elements. I must assign a number between 1 and 'n' to each element such that I maximize the distance between every 2 elements in 1 tuple in the moveTuples set (I need to order them but try to keep a distance between elements in the same tuple).
Every element MUST have ONLY 1 assigned number and each number should be given to ONLY 1 element. For this purpose, I wrote the following code:
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;
Now the problem is clear and for the previous example, the output must be either:
e1 -> 1
e2 -> 3
e3 -> 2
or
e1 -> 3
e2 -> 1
e3 -> 2
since it is required to only move e1 from e2 using the tuple (e1,e2). When running the previous code, I get the error: ... contains a non-quadratic non-linear constraint (definitely the "moveApart" constraint). Can you please guide me on how to solve this problem? Thanks in advance.
The constraint
moveApart
is nonlinear (and non-quadratic) because it contains a call toabs
. However, since your problem is purely integer, you can solve it with CPLEX CP Optimizer (ilogcp).