0

I am trying to solve an MIP with a non-linear objective such as sum(a(i)*x(i))/sum(b(i)*x(i)) where a(i) and b(i) are parameters. Since CPLEX cannot extract this expression, I tried using CP.

However, I have constraint stating that the decision variable x(i) should be a multiplier of 2.5, therefore a float. Since CP cannot handle floats, I set x to be an integer, and implied to be multiplier of 25. In every other constraint and expression I divided x by 10, so that the calculations remained the same.

First, I solved the model with the multiplier 5, I got a solution with a very small gap, which is fine. When I changed the multiplier to 25, the model cannot terminated within 2 hours (stucked with a gap of 90%). I believe this happened due to scaling, but still cannot figure it out, since I am not familiar with the CP algorithm.

I am still working to linearize the oblective but, any suggestion on both CPLEX and CP engine solutions will be highly appreciated. Thanks in advance.

osygl
  • 13
  • 2
  • I have had some luck with [Dinkelbach's algorithm](https://yetanothermathprogrammingconsultant.blogspot.com/2012/01/dinkelbachs-algorithm.html) for these type of problems. – Erwin Kalvelagen Feb 19 '20 at 12:37

2 Answers2

0

have you tried to turn equalities into inequalities to allow some flexibility ?

For instance

using CP;

int scale=1000;
dvar int scalex in 0..2000;
dexpr float x=scalex/scale;

subject to
 {
   x*x==2;
 }

gives no solution whereas

using CP;

float epsilon=0.001;

int scale=1000;
dvar int scalex in 0..2000;
dexpr float x=scalex/scale;

subject to
 {
   abs(x*x-2)<=epsilon;
 }

gives

x=1.414

and

using CP;

{int} hm=asSet(1..4);
float epsilon=0.001;

dvar int scalex[1..card(hm)] in 0..20000;
int scale=10000;

dexpr float A[ i in 1..card(hm)]=scalex[i]/scale;
subject to
{
  forall(i in 1..card(hm))abs(A[i]*A[i]-2)<=epsilon;
}

works fine too

Alex Fleischer
  • 9,276
  • 2
  • 12
  • 15
  • Thank you @Alex Fleischer. I tried what you suggested. My decision variable's index is a tuple therefore I wrote a code like below: dvar int scalex[1..card(hm)] in 0..10000; int scale=100; dexpr float A[1..card(hm)]=[]; int max_range=card(hm); execute{ for (var i=1;i<=max_range;i++){ A[i]==scalex[i]/scale; } } I received Scripting runtime error: cannot convert to a number, "[a IloNumVar]" error. How can I fix this? Thank you. – osygl Feb 20 '20 at 10:36
0

Thank you @Alex Fleischer. I tried what you suggested. My decision variable's index is a tuple therefore I wrote a code like below:

dvar int scalex[1..card(hm)] in 0..10000;
int scale=100;

dexpr float A[1..card(hm)]=[];
int max_range=card(hm);

execute{
for (var i=1;i<=max_range;i++){
    A[i]==scalex[i]/scale;
}
}

I received Scripting runtime error: cannot convert to a number, "[a IloNumVar]" error. How can I fix this? Thank you.

osygl
  • 13
  • 2