Decision Optimization

Decision Optimization

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

 View Only
Expand all | Collapse all

slow column generation

  • 1.  slow column generation

    Posted Fri March 20, 2015 01:16 PM

    Originally posted by: pradeepram80


    I'm working on a column generation implementation using OPL scripting. I'm noticing that the original model (without decomposition) solves in 2 minutes for a test case but my decomposed model takes longer. Upon further investigation, I'm finding that the generate() function in master problem takes longer to execute with every successive iteration. Any ideas on how this can be sped up? I'm deleting and recreating the IIOoplModel object for the master problem every iteration. Hence I have to call the generate() function every iteration. Is there any other way I can add the new column without having to generate the model again?


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 2.  Re: slow column generation

    Posted Mon March 23, 2015 05:50 AM

    Hi,

    Indeed you may regenerate or you may also use setcoef in order to change the matrix.

    See

    https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014727055

    regards


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 3.  Re: slow column generation

    Posted Wed March 25, 2015 03:37 PM

    Originally posted by: pradeepram80


    Thanks a lot for the reply. Helps.

    Here is an example of a constraint whose coefficient I'm changing: (There are many such constraints)

    forall(<f,ws2,b2,sw2> in WBIndex)
    ctCapConstr[<f,ws2,b2,sw2>]:
    sum(<f,a,t,s1,s2,ws1,b1,ws2,b2,sw1,sw2,ow> in setSequence, p in Proposals)
      sum(<f,t,s2,ws2,sw2,ow,cc,yld> in setCapCoeff)cc*p.moves[<f,a,t,s1,s2,ws1,b1,ws2,b2,sw1,sw2,ow>]*lamda[p] == tr[<f,ws2,b2,sw2>];

    lamda[p] is my decision variable in the restricted master problem.  p.moves[] comes from my subproblem.

     I will have to calculate the sum of               cc*p.moves[<f,a,t,s1,s2,ws1,b1,ws2,b2,sw1,sw2,ow>]  for every constraint defined in WBIndex if my understanding is correct. In order to do that I'll have to write "for loops" to access the right elements for the various tuple sets like setSequence. My questions:

    a)    Is there a easier way to calculate the new coefficients other than using for loops?

    b)    Is OPL scripting suitable to handle decomposition problems of this complexity? Should I be looking at CPP or Java callable libraries instead?

     

    Regards,

    pr

     


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 4.  Re: slow column generation

    Posted Sun March 29, 2015 04:06 AM

    Hi,

    instead of loops you may use find in scripting.

    Some prefer OPL scripting, some prefer CPP or java. Depends.

    regards


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 5.  Re: slow column generation

    Posted Tue March 31, 2015 12:23 PM

    Originally posted by: pradeepram80


    Alex,

    Think I was probably not clear.

    Could you please point me to examples/documentation where OPL scripting recalculates the right set of coefficients and then uses "setcoeff()" to update the coefficients? Also, should I declare empty variables beforehand for the column generation and then update them?

     

    Regards,

    Pradeep


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 6.  Re: slow column generation



  • 7.  Re: slow column generation

    Posted Mon April 20, 2015 10:59 AM

    Originally posted by: pradeepram80


    Hi,

    Examples you provided do not show any recalculation of the coefficients. Let me share more  (Hoping to be very clear):

    I'm writing for loops in OPL scripting to iterate through the various tuples to calculate new coefficients in each iteration, as shown below. These for loops take forever. I dont seem to find an alternate way to implement this in OPL scripting. Reason why I've for loops is because I'm joining the different tuples until i get a match.

    Can you please let me know if there is a better way?

     

    for (var capConstr in masterOpl.ctCapConstr){
            var sumcoeff = 0.00;
            for (var coeff in masterOpl.setCapCoeff){
            if(capConstr.int1!=coeff.int1) continue;
            if(capConstr.str2!=coeff.str4) continue;
           
            for (var seq in masterOpl.setSequence) {
            if(capConstr.str3!=seq.str9) continue; //b2
            if(coeff.str3!=seq.str5) continue; //s2
            if(coeff.int1!=seq.int2) continue; //sw2
            if(coeff.str4!=seq.str8) continue; //ws2
            if(coeff.int2!=seq.int3) continue; //ow
            if(coeff.str2!=seq.str3) continue; //t   
           
            sumcoeff = sumcoeff + subOpl.moves[seq]*coeff.flt1;  
                }        
              } 
             
                masterOpl.ctCapConstr[capConstr].setCoef(masterOpl.lamda[count+1],sumcoeff);
            }

    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 8.  Re: slow column generation

    Posted Mon April 20, 2015 02:41 PM

    Hi,

    have you tried find ?

    http://www-01.ibm.com/support/knowledgecenter/#!/SSSA5P_12.4.0/ilog.odms.ide.help/refjsopl/html/IloTupleSet.html

    Or have you tried to use an array in order to directly reference items ?

    regards


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 9.  Re: slow column generation

    Posted Fri May 01, 2015 05:04 PM

    Originally posted by: pradeepram80


    Hi,

    Your idea worked. Thank you. Here is my new code. I was able to get everything done in a single for loop. Do you think there could be further improvements in runtimes possible?

     

    Regards,

    pr

    for (var seq in masterOpl.setSequence) {

    //<f,a,t,s1,s2,ws1,b1,ws2,b2,sw1,sw2,ow> in seq --> <str1,str2,str3,str4,str5,str6,str7,str8,str9,int1,int2,int3>

    //<f,ws2,b2,sw2> in capConstr --> <str1,str2,str3,int1>

    //<f,t,s2,ws2,sw2> in CCIndex --> <str1,str2,str3,str4,int1,int2,float1,float2>

    masterOpl.SumCoeff[masterOpl.WSBldngIndex.find(seq.str1,seq.str8,seq.str9,seq.int2)]

    = masterOpl.SumCoeff[masterOpl.WSBldngIndex.find(seq.str1,seq.str8,seq.str9,seq.int2)]

    + subOpl.moves[seq]*masterOpl.CC[masterOpl.CCIndex.find(seq.str1,seq.str3,seq.str5,seq.str8,seq.int2)];

     

    //<f,a,t,s1,s2,ws1,b1,ws2,b2,sw1,sw2,ow> in seq --> <str1,str2,str3,str4,str5,str6,str7,str8,str9,int1,int2,int3>

    //<f,b1,b2,sw2> in BldngIndex --> <str1,str2,str3,int1>

    //<f,ws1,b1,ws2,b2,sw2> in VehConstIndex2 --> <str1,str2,str3,str4,str5,int1>

    if(!masterOpl.VehConstIndex2.find(seq.str1,seq.str6,seq.str7,seq.str8,seq.str9,seq.int2))

    continue;

     

    masterOpl.SumCoeff2[masterOpl.BldngIndex.find(seq.str1,seq.str7,seq.str9,seq.int2)]

    = masterOpl.SumCoeff2[masterOpl.BldngIndex.find(seq.str1,seq.str7,seq.str9,seq.int2)]

    + subOpl.moves[seq]*masterOpl.VehConst[masterOpl.VehConstIndex2.find(seq.str1,seq.str6,seq.str7,seq.str8,seq.str9,seq.int2)];

     

    //update moves variable in master opl

    masterOpl.moves[count+1][seq]=subOpl.moves[seq];

    }


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 10.  Re: slow column generation

    Posted Fri May 01, 2015 05:16 PM

    Originally posted by: pradeepram80


    Also one more question:

    In your post : https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014839106#77777777-0000-0000-0000-000014839171

    You show how to change the UB.

    However when I try to change the UB of a similar constraint, I get the following error:

    Description Resource Path Location Type
    Scripting runtime error: cannot add properties to this value, "[a IloConstraint]". 

    Documentation for IloConstraint says:

    Caution:
    For technical reasons, the lower and upper bound properties LB and UB are currently accessible only during postprocessing and flow control in constraints assigned inside a forall declaration. The undefined value is returned instead. You can nevertheless modify the bounds.

    So I defined the constraint with a forall statement but I still see the same error. Ideas on getting around this problem will be greatly appreciated.

    Here is how I'm defining the constraint in my model:

    {ti} N={<1>};

    minimize something;

    subject to {

     some constraints

    forall(<n> in N) ctIter2[<n>]: lamda[1] == 1;

    }

    main {

    ....

    for (var nn in masterOpl.N)

    masterOpl.ctIter2[nn].UB=0.0;

     

    }

    Can you show how to make this work?
     

     

     

     


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 11.  Re: slow column generation

    Posted Sat May 02, 2015 03:19 AM

    Hi,

    have you done the masterOpl.generate();

    ?

    regards


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 12.  Re: slow column generation

    Posted Mon May 04, 2015 10:19 AM

    Originally posted by: pradeepram80


    Yes I did. That was my first attempt. However the generate function takes about 60-90seconds per iteration. Using the above for loop reduces it to ~30 seconds. Its good but not enough. So wondering if there is any other way I could write the for loop.

    Also need your thoughts on the previous post - how to change the UB of convexity constraint.

    Thanks,

    Pradeep


    #DecisionOptimization
    #OPLusingCPLEXOptimizer