Decision Optimization

Decision Optimization

Delivers prescriptive analytics capabilities and decision intelligence to improve decision-making.


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  speed-up column generation with updating CP objective function

    Posted 04/16/11 08:23 AM

    Originally posted by: davidoff


    Hello

    It is possible to run cp.solve() once the model has been notified through x.setLB() or x.setUB() without extracting the whole model.
    However, this seems impossible while setting new coefficients for the objective function, which is often the case in a column generation scheme.

    
    Exception from IBM ILOG Concert: You can not change the coefficient of a nonlinear expression
    


    One workaround would be to define dual infos as additional variables and updating these variables with setBounds. This is also impossible since only discrete variables are authorized while dual values are float.

    The only acceptable workaround I found is to remove the objective from the model and add a modified one. Is that the best way ? Is it possible also with OPL ?

    David
    #DecisionOptimization
    #OPLusingCPOptimizer


  • 2.  Re: speed-up column generation with updating CP objective function

    Posted 04/18/11 12:14 PM

    Originally posted by: rdumeur


    Dear David,

    Thank you for reporting this problem. Could you please tell me what API do you use to set new objective coefficients?
    Is it the IloObjective::setLinearCoeff(...) method used in the documented example about column generation?
    Regarding OPL, we are asking the question to the relevant team and will be back to you as soon as we know more.

    Cheers,

    Renaud
    #DecisionOptimization
    #OPLusingCPOptimizer


  • 3.  Re: speed-up column generation with updating CP objective function

    Posted 04/18/11 01:27 PM

    Originally posted by: davidoff


    Hello

    i tried first in OPL to modify the objective this way :
    
    main 
    {   var m = thisOplModel; ... m.generate(); 
    
    if (cp.solve()) 
    { 
    
    for(var itv in m.couvertes)
    { m.lock[itv].UB = 0;
    //OK : change bounds of a variable m.getObjective().setCoef(m.presenceCover[itv],2);
    //ERROR Exception from IBM ILOG Concert: You can not change the coefficient of a nonlinear expression   
    } 
    }
    


    However, adapting the C++ documentation sample facility.cpp (provided in cpoptimizer samples), it is there possible to update the objective function with

    
    objective.setLinearCoef( myvar, mycoeff)
    


    I haven't tried so far to test this approach to my original OPL model

    Thanks

    David
    #DecisionOptimization
    #OPLusingCPOptimizer


  • 4.  Re: speed-up column generation with updating CP objective function

    Posted 04/19/11 04:25 AM
    Hello,

    what you could do is add artificial decision variables in order to modify the objective function as you like.

    let me give you an example:

    
    using CP;   dvar int+ x in 0..10; dvar int+ y in 0..10; dvar 
    
    int c1; dvar 
    
    int c2;     dvar 
    
    int z;   maximize z ;   subject to 
    {   z==c1*x+c2*y; x+y==10; 
    }   main 
    { thisOplModel.generate(); thisOplModel.c1.UB=2; thisOplModel.c1.LB=2; thisOplModel.c2.UB=1; thisOplModel.c2.LB=1; cp.solve(); writeln(
    "x=",thisOplModel.x); writeln(
    "y=",thisOplModel.y); writeln(cp.getObjValue()); thisOplModel.c1.UB=1; thisOplModel.c1.LB=1; thisOplModel.c2.UB=3; thisOplModel.c2.LB=3;   cp.solve(); writeln(
    "x=",thisOplModel.x); writeln(
    "y=",thisOplModel.y);   writeln(cp.getObjValue()); 
    }
    


    which gives

    
    x=10 y=0 20 x=0 y=10 30
    


    NB:

    if you need c1 and c2 to be decimal you may replace c1 and c2 by c1/100000 and c2/100000

    Regards
    #DecisionOptimization
    #OPLusingCPOptimizer


  • 5.  Re: speed-up column generation with updating CP objective function

    Posted 04/19/11 06:51 AM

    Originally posted by: davidoff


    Excellent !
    Thanks for the workaround

    In order to avoid loosing precision with rounding float values, I consider multiplying and dividing by 100000 the fractional part of the coefficients (see code below)

    
    using CP;   
    
    int dig = 6;
    //how many digits do we keep range r = 1..2; 
    
    float dual[r] = [1567.2389,  3.000678]; 
    
    int ent[i in r] = ftoi(round(dual[i])); 
    
    float res[i in r] = dual[i]- round(dual[i]); 
    
    int resd[i in r] = ftoi(round(pow(10,dig)*res[i]));   dvar 
    
    int coeffEnt[i in r] in ent[i]..ent[i]; dvar 
    
    int coeffRest[i in r] in resd[i]..resd[i]; dexpr 
    
    float coeff[i in r] = coeffEnt[i] + pow(10,-dig)*coeffRest[i];   dvar int+ x[r];   minimize sum(i in r) coeff[i]* x[i];   subject to 
    { sum(i in r) x[i] >=1; 
    }   execute
    {
    //postprocess writeln(x); 
    }   main
    { thisOplModel.generate(); 
    
    if (cp.solve()) 
    { writeln(
    "RUN 1 objvalue = ",cp.getObjValue()); thisOplModel.postProcess(); 
    } writeln(
    "update bounds"); thisOplModel.coeffEnt[1].LB= 2;
    //change dual[1] to 2.2389 thisOplModel.coeffEnt[1].UB= 2;
    //change dual[1] to 2.2389 
    
    if (cp.solve())
    { writeln(
    "RUN 1 objvalue = ",cp.getObjValue()); thisOplModel.postProcess(); 
    } 
    }
    


    This code simply picks up the item with the smallest coefficient. The first coefficients are 1567.2389, 3.000678 and later I change them in 2.2389, 3.000678 . The result is correct :

    
    RUN 1 objvalue = 3.000678 [0 1] update bounds RUN 1 objvalue = 2.2389 [1 0]
    

    #DecisionOptimization
    #OPLusingCPOptimizer