Search code examples
integerdivisioncplexcpnonlinear-optimization

CPLEX vs Constraint Programming Solution for a linearly constrained MIP with a nonlinear objective(division)


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.


Solution

  • 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