Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  Evaluating an IloConstraint throws a NullPointerException

    Posted 03/30/10 10:48 AM

    Originally posted by: SystemAdmin


    I am trying to use CPLEX to model a particular problem and then test for a series of conditions after I have solved my model. For some reason I am getting a NullPointerException. I have created a test example that demonstrates this problem (see below). When I run the same example using CP Optimizer it does not throw any Exception and I get the correct answer.

    Is this a issue with the CPLEX solver or are there some configuration parameters I am not setting?

    Respectfully,

    Alex

    CPLEX 12.1

    Code:
    import ilog.concert.IloException;
    import ilog.concert.IloIntVar;
    import ilog.cplex.IloCplex;
     
    public class Test {
     
            public static void main(String[] _args) throws IloException {
                    IloCplex cplex=new IloCplex();
                    IloIntVar a=cplex.intVar(1,Integer.MAX_VALUE);
                    cplex.add(a);
                    if (cplex.solve()) {
                            System.out.println("a="+cplex.getValue(a));
                            System.out.println("t="+cplex.getValue(cplex.ge(a,0)));
                    }
     
            }
     
    };
    


    Output:
    Tried aggregator 1 time.
    MIP Presolve eliminated 0 rows and 1 columns.
    All rows and columns eliminated.
    Presolve time =    0.00 sec.
    a=1.0
    Exception in thread "main" java.lang.NullPointerException
            at ilog.cplex.CpxNumVar.getVarIndexValue(CpxNumVar.java:268)
            at ilog.cplex.EvalVisitor.visitNumVar(EvalVisitor.java:32)
            at ilog.cplex.CpxNumVar.accept(CpxNumVar.java:68)
            at ilog.cplex.IloCplex.getValue(IloCplex.java:6083)
            at Test.main(Test.java:13)
    IBM ILOG CPLEX Teaching Edition.
    


    CP Optimizer 2.3

    Code:
    import ilog.concert.IloException;
    import ilog.concert.IloIntVar;
    import ilog.cp.IloCP;
     
    public class Test {
     
            public static void main(String[] _args) throws IloException {
                    IloCP cp=new IloCP();
                    IloIntVar a=cp.intVar(1,Integer.MAX_VALUE);
                    cp.add(a);
                    if (cp.solve()) {
                            System.out.println("a="+cp.getValue(a));
                            System.out.println("t="+cp.getValue(cp.ge(a,0)));
                    }
            }
     
    };
    


    Output:
    ! ----------------------------------------------------------------------------
     ! Satisfiability problem - 1 variable, 0 constraints
     ! Initial process time : 0.00s (0.00s extraction + 0.00s propagation)
     !  . Log search space  : 31.0 (before), 31.0 (after)
     !  . Memory usage      : 315.4 Kb (before), 315.4 Kb (after)
     ! ----------------------------------------------------------------------------
     !   Branches  Non-fixed                Branch decision                       
     *          1      0.00s                  _int0  =    1    
     ! ----------------------------------------------------------------------------
     ! Solution status        : Terminated normally, solution found
     ! Number of branches     : 1
     ! Number of fails        : 0
     ! Total memory usage     : 348.2 Kb (331.4 Kb CP Optimizer + 16.8 Kb Concert)
     ! Time spent in solve    : 0.00s (0.00s engine + 0.00s extraction)
     ! Search speed (br. / s) : 100.0
     ! ----------------------------------------------------------------------------
    a=1.0
    t=1.0
    

    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Evaluating an IloConstraint throws a NullPointerException

    Posted 03/30/10 11:49 AM

    Originally posted by: SystemAdmin


    What you are trying to do runs contrary to the way math programming solvers work. The null pointer exception occurs in part, I think, because the constraint you are testing is not part of the model that CPLEX solved. I'm also not sure whether the getValue method works on constraints, even though the documentation suggests it should (according to the docs, getValue can take an IloNumExpr argument, and IloConstraint and IloRange are both subinterfaces of IloNumExpr). You can use getSlack to get the slack/surplus of a constraint IF the constraint is part of the model.

    So one possibility is to use IloCplex.addGe rather than IloCplex.ge, which adds the constraint to the model prior to solution. In that case the constraint will be satisfied (or the solver will declare the problem infeasible), so there's nothing to test if the solve() method finds a solution. The other possibility is to omit the constraint from the model, solve, then test it outside of CPLEX:

    double aval = cplex.getValue(a);
    boolean t = aval >= 0;

    /Paul

    Mathematicians are like Frenchmen: whenever you say something to them, they translate it into their own language, and at once it is something entirely different. (Goethe)
    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: Evaluating an IloConstraint throws a NullPointerException

    Posted 03/30/10 12:09 PM

    Originally posted by: SystemAdmin


    Paul,

    Thank you for your response. It would seem that CPLEX does evaluate expressions that are outside of the model that was solved. For example, consider the test program:

    Code:
    public static void main(String[] _args) throws IloException {
            IloCplex cplex=new IloCplex();
            IloIntVar a=cplex.intVar(2,Integer.MAX_VALUE);
            cplex.add(a);
            IloRange r=cplex.addGe(a,0);
            if (cplex.solve()) {
                    System.out.println("a="+cplex.getValue(a));
                    System.out.println("e="+cplex.getValue(cplex.prod(cplex.sum(a,1),a)));
                    System.out.println("r="+cplex.getValue(r));
            }
    }
    


    Output:
    Tried aggregator 1 time.
    MIP Presolve eliminated 1 rows and 1 columns.
    All rows and columns eliminated.
    Presolve time =    0.00 sec.
    a=2.0
    e=6.0
    Exception in thread "main" java.lang.NullPointerException
            at ilog.cplex.CpxNumVar.getVarIndexValue(CpxNumVar.java:268)
            at ilog.cplex.EvalVisitor.visitNumVar(EvalVisitor.java:32)
            at ilog.cplex.CpxNumVar.accept(CpxNumVar.java:68)
            at ilog.cplex.IloCplex.getValue(IloCplex.java:6083)
            at org.dgql.opt.Test.main(Test.java:50)
    IBM ILOG CPLEX Teaching Edition.
    


    I do agree that the documentation would seem to imply that you can do what I am attempting (IloConstraint does extend IloIntExpr). What's more, the same example using the Concert API and CP Optimizer does work. I could write my own evaluator for this however the IloConstraint objects generally are opaque (the reference an object in native code) and don't allow you to inspect their attributes.

    Alex
    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: Evaluating an IloConstraint throws a NullPointerException

    Posted 03/30/10 12:19 PM

    Originally posted by: SystemAdmin


    It's true that the documentation implies that what you do is possible.
    And it is a bit unfortunate that the class hierarchy actually allows you to do that.
    But it is still not meaningful :-) What does the value of 1.0 returned by CP mean?
    You could interpret it as the slack of the range but what if the range is bounded
    from above and below?
    So just check your constraint in a different way (see my other post in this thread).
    Note that it is perfectly legal to evaluate expressions that are not part of the
    model. Just don't invoke getValue() on something for which it is not meaningful.
    #CPLEXOptimizers
    #DecisionOptimization


  • 5.  Re: Evaluating an IloConstraint throws a NullPointerException

    Posted 03/30/10 12:38 PM

    Originally posted by: SystemAdmin


    I am would expect that getValue(IloConstraint) would return either 1.0 (true) or 0.0 (false), exactly the same as if I passed in the object returned by boolVar() since both extend IloIntExpr. I agree, it is a shame there is no
    int getValue(IloIntExpr)
    int getValue(IloIntVar)
    
    or even a
    boolean getValue(IloBoolExpr)
    boolean getValue(IloBoolVar)
    
    which would make considerably more sense.

    Post solving the model, I build a series of conditions I need to test for that are dependent on what sort of solution is produced by CPLEX. It would be very convenient if I could reuse the large mathematical model I created when extracting the problem to do this, rather than create my own intermediate representation just to handle these queries.

    Thank you for your suggestions though.

    Alex
    #CPLEXOptimizers
    #DecisionOptimization


  • 6.  Re: Evaluating an IloConstraint throws a NullPointerException

    Posted 03/30/10 12:45 PM

    Originally posted by: SystemAdmin


    This 1=true and 0=false is not quite java. You can't even do
    if (1) {
     
    }
    

    without getting a compiler error. But what you want to do can still be done quite easily.
    Just write a function like this
    boolean checkRange(IloCplex cplex, IloRange rng) {
        double value = cplex.getValue(rng.getExpr());
        return value >= rng.getLB() && value <= rng.getUB();
    }
    

    Then you can replace 'cplex.getValue(cplex.ge(a, 0))' by 'checkRange(cplex, cplex.ge(a, 0))'.
    I think it is not that more inconvenient.
    #CPLEXOptimizers
    #DecisionOptimization


  • 7.  Re: Evaluating an IloConstraint throws a NullPointerException

    Posted 03/30/10 03:22 PM

    Originally posted by: SystemAdmin


    The problem with your solution is that most of my test conditions are not simple range constraints.

    I had considered writing my own evaluator for IloConstraint objects, which would simply recursively go through the expression until it reached subclasses of IloNumVar, then look up the values directly using IloCplex and return some computed value. However, the Java API does not expose all subclasses of IloConstraint in any useful fashion. For example, consider the constraint in the problem below:

    public static void main(String[] _args) throws IloException {
            IloCplex cplex=new IloCplex();
            IloIntVar a=cplex.intVar(2,Integer.MAX_VALUE);
            cplex.add(a);
            if (cplex.solve()) {
                    System.out.println("a="+cplex.getValue(a));
                    System.out.println("t="+cplex.getValue(cplex.not(cplex.ge(cplex.min(a,5),4))));
            }
    }
    


    Both cplex.not() and cplex.min() return interfaces (IloConstraint and IloIntExpr respectively) and while I could cast them to their concrete classes (CpxNot and CpxMinExpr) I still cannot access the private fields that allow me to walk the constraint expression and compute its truth value.

    Do you know if there are any plans to either (1) support evaluating IloConstraint expressions via getValue() or (2) expose enough structure to allow users of this API to do so themselves?

    Respectfully,

    Alex
    #CPLEXOptimizers
    #DecisionOptimization


  • 8.  Re: Evaluating an IloConstraint throws a NullPointerException

    Posted 03/30/10 04:34 PM

    Originally posted by: SystemAdmin


    I see. Have you tried cplex.getInfeasibility(). This function accepts IloConstraint arguments but I fear it will only work for stuff that is part of the model.
    #CPLEXOptimizers
    #DecisionOptimization


  • 9.  Re: Evaluating an IloConstraint throws a NullPointerException

    Posted 03/30/10 12:13 PM

    Originally posted by: SystemAdmin


    I think what you do is neither meaningful nor supported by cplex.
    What do you expect that getValue(range) returns for a constraint such as "a >= 0"?
    A meaningful result could be true or false but the function returns a double.
    What you should do instead is
    getValue(range.getExpr()) >= range.getLB() && getValue(range.getExpr()) <= range.getUB()
    or, in your particular case,
    getValue(a) >= 0
    #CPLEXOptimizers
    #DecisionOptimization