Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  Multiple Lazy Constraints?

    Posted 10/25/18 10:13 AM

    Originally posted by: LaylaM


    Hi!
    I've got a rather general question: How does CPLEX handle multiple lazy constraint callbacks?

    model.use(new WorkerRestriction());
    model.use(new VehicleCapacity());
    model.use(new SchedulingConstraints());
    

    I want all three constraints to be checked, but currently it seems as if everything but the last constraint is ignored?

    Should this happen? Is there a work around? How would I implement this? 

    Thank you!


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Multiple Lazy Constraints?

    Posted 10/25/18 03:15 PM

    Yes, this is intentional. You can only have one callback of each type, so when you attach a second one the first one is dropped.

    The workaround is simple. Convert the three callbacks to ordinary functions, then create a single callback that calls each of the original ones in turn and sticks any constraints they would add into a local memory structure (such as ArrayList<IloRange> in the Java API). After the third of the original functions returns, convert the accumulated constraints into an array and add them to the problem.


    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: Multiple Lazy Constraints?

    Posted 10/25/18 04:41 PM

    Like Paul said, this is intended behavior and is even explicitly stated in the reference documentation here.

    When I am in your situation I usually do something slightly different than what Paul suggested:

    1. I create a subclass of the LazyConstraintCallback that has a public API that allows querying the current values and adding lazy constraints (basically provide public access to the protected functions getValues() and add()).
    2. I register an instance of this class with the IloCplex instance.
    3. In the callback's main() I invoke the separation algorithm of the three other classes, passing 'this' as argument.

    This way it is pretty simple to write your callbacks in a way so that they can either be used individually or can be combined as a list.

    If you want to do that and have trouble implementing it, I can dig out an example from my old code.


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  RE: Re: Multiple Lazy Constraints?

    Posted 06/22/20 04:59 PM
    Hi Daniel, good afternoon.
    Could you post a simple example of what you have proposed?

    Thanks for the help.

    ------------------------------
    Pedro Henrique González Silva
    ------------------------------



  • 5.  RE: Re: Multiple Lazy Constraints?

    Posted 06/23/20 01:13 AM
    Here you go:
    import ilog.cplex.IloCplex;
    import ilog.concert.IloException;
    import ilog.concert.IloNumVar;
    import ilog.concert.IloRange;
    import java.util.Collection;
    
    /** Interface that represents a solution.
     * This could be the current solution at a callback as well as the solution
     * returned after solve().
     */
    interface Solution {
       /** Get the value of a variable.
        * @param var The variable to query.
        * @return The current value for <code>var</code>.
        */
       public double getVariableValue(IloNumVar var) throws IloException;
    }
    
    /** Interface for separators.
     * Separators implement this interface in order to be invoked from the
     * callback's <code>main()</code> method.
     */
    interface Separator {
       /** Separate constraints for the current solution represented by
        * <code>sol</code>.
        * @param sol The current solution.
        * @return A (potentially empty) list of violated constraints.
        */
       public Collection<IloRange> separate(Solution sol) throws IloException;
    }
    
    
    public class PublicLazyConstraintCallback extends IloCplex.LazyConstraintCallback implements Solution {
    
    
       private Collection<Separator> separators = new java.util.Vector<Separator>();
    
       public PublicLazyConstraintCallback(Collection<Separator> separators) {
          this.separators.addAll(separators);
       }
    
       @Override
       public double getVariableValue(IloNumVar var) throws IloException {
          return getValue(var);
       }
    
       public void main() throws IloException {
          for (Separator s : separators)
             for (IloRange r : s.separate(this))
                add(r);
       }
    }

    A separator would have to implement the Separator interface. Then you create an instance of PublicLazyConstraintCallback, register the separators with it and finally register the callback with CPLEX.

    ------------------------------
    Daniel Junglas
    ------------------------------



  • 6.  RE: Re: Multiple Lazy Constraints?

    Posted 06/23/20 09:23 AM

    Dear Daniel.

    Thanks for the quick reply.

    Best regards



    ------------------------------
    Pedro Henrique González Silva
    ------------------------------



  • 7.  Re: Multiple Lazy Constraints?

    Posted 10/26/18 02:47 AM

    Originally posted by: LaylaM


    Thanks Paul and Daniel, 

    it also worked to simply put all three "former main method" into one private class (renamed, obviously) and to call them from the (new) main 


    #CPLEXOptimizers
    #DecisionOptimization