Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  Updating constraints in Java API

    Posted 02/21/20 01:04 PM

    Originally posted by: open_ball


    Hi, 

    I am creating a Benders framework in Java API and was wondering if the way that I plan to update the sub problem seems reasonable.

    I create two maps in which the constraints and their right hand sides are stored.

    HashMap<ArcTime, IloRange> constraintSet; 
    HashMap<IloConstraint, IloNumExpr> RHS; 
    

    Then, I fill both maps as;

    constraintSet.put(arcTime,  (IloRange) cplex.addLe(subVariable,0)); 
    RHS.put(constraintSet.get(arcTime) , cplex.prod(bound.get(arc), masterVariable));
    

    Is this a correct way to proceed to sub problem to avoid regenerating the LP model? Also, is there a more efficient way that would decrease the computation time of this operation?

     

    In addition to this, I have another question. After getting responded at here, I defined masterVariable as 

     IloNumVar masterVariable= cplex.numVar(0,bound.get(arc));        
     cplex.add(masterVariable);
     master.put(arc, masterVariable); \\HasMap<arc,IloNumVar> master = new HashMap<arc,IloNumVar>();
    

    Now, when I enter into the lazy call back function, I need to reach the values of all masterVariable. From the example provided by CPLEX, I can see that I should use 

    context.getCandidatePoint(master );   
    

    However, master is defined as a HashMap, not as an IloNumVar instance.  How can I solve this issue? Should I iterate thru the map and parse each variable one by one? or is there a more straight forward way?

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Updating constraints in Java API

    Posted 02/21/20 04:30 PM

    First, just to be clear, your RHS.put() line will not change the right-hand side of the constraint that CPLEX is using. The constraint in the model will remain subVariable <= 0 until you explicitly change it.

    Second, as far as whether there is a better way to do things, it is not clear whether you need the RHS map. Fetching the right-hand side could also be done via constraintSet.get(arcTime).getUB(), eliminating the need for RHS.

    Third, to get the solution, you can indeed loop through master.values() and look up the value of each one individually. Another possibility is to generate a vector of variables via IloNumVar[] vars = master.values().toArray(new IloNumVar[master.size()]) and then use double[] vals = context.getCandidatePoint(vars) to get the values. You will need to loop through the two vectors to associate each value with the correct master variable. (I'm assuming that you are using a reasonably recent version of Java, one that supports the Stream interface.)


    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: Updating constraints in Java API

    Posted 02/21/20 07:41 PM

    Originally posted by: open_ball


    "First, just to be clear, your RHS.put() line will not change the right-hand side of the constraint that CPLEX is using. The constraint in the model will remain subVariable <= 0 until you explicitly change it." 

    You're right. I do not plan to use the RHS map to change the right hand side of the constraint. I was planning to use RHS to generate the Benders cut since I plan to solve the primal rather than directly solving the dual. 

     

    "Second, as far as whether there is a better way to do things, it is not clear whether you need the RHS map. Fetching the right-hand side could also be done via constraintSet.get(arcTime).getUB(), eliminating the need for RHS." 

    Great! This constraintSet.get(arcTime).getUB() is what I was exactly planning to do. As I mentioned, I will use the RHS map for another purpose. 

     

    "Third, to get the solution, you can indeed loop through master.values() and look up the value of each one individually. Another possibility is to generate a vector of variables via IloNumVar[] vars = master.values().toArray(new IloNumVar[master.size()]) and then use double[] vals = context.getCandidatePoint(vars) to get the values. You will need to loop through the two vectors to associate each value with the correct master variable. (I'm assuming that you are using a reasonably recent version of Java, one that supports the Stream interface.)" 

    If I convert the map into an array through streaming, then wouldn't I lose the connection of the index and value? For instance, how can I know which arc that vars[0] corresponds to? 

     

    Other than that, thanks for your answer. I just wanted to clarify some points before completing my implementation. Your comments were once again really helpful!


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: Updating constraints in Java API

    Posted 02/21/20 07:53 PM

    On the last point: yes, if you need to associate the value of each master variable with the arc to which it corresponds, that will require additional work. One option is to iterate through the entry set for your "master" map, calling getCandidatePoint on each value. The other option is to add a HashMap<IloNumVar, arc> that contains the reverse mapping of what is in "master", use the array approach I mentioned to get the values, and then look up the variables in the reverse map to get the arcs. Iterating through the entry set is less work in programming terms, and I don't know that a single call to getCandidatePoint with a vector argument saves enough CPU time to compensate for the extra map you need. The difference in time between the two methods, regardless of which is faster, may well be negligible compared to the solution time for CPLEX.


    #CPLEXOptimizers
    #DecisionOptimization