Decision Optimization

Decision Optimization

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

 View Only
  • 1.  Decision variable as parameter

    Posted Wed April 17, 2019 04:29 AM

    Originally posted by: __foo_


    Hi all,

    I'm using CPLEX in Java to solve this variant of the bin packing problem, the description can be found in the attached Java source file.

    Basically, the optimization program has a decision variable, say y, which takes the value {0, 1, 2, 3}, representing one of the four possible options 0, 1, 2, or 3. Each option is associated with different pre-defined value, namely 0.9, 2.5, 4.1, and 4.8, respectively, which is stored in an array values[] = {0.9, 2.5, 4.1, 4.8}. Is it possible to have the decision variable y as a parameter of the pre-defined array values[], such as values[y]?

    I was using cplex.getValue(y) at the moment (line 46 and 63 in the attached sample code) but it turned out it can only be used after a solution is found. I'm trying to find an alternate. 

    Thanks very much.

    import java.io.IOException;
    import java.text.ParseException;
    import ilog.concert.IloException;
    import ilog.concert.IloIntVar;
    import ilog.concert.IloLinearNumExpr;
    import ilog.concert.IloNumVar;
    import ilog.opl.IloCplex;
    
    /**
     *  Given 10 adjustable-sized items, and 3 boxes with different capacity. 
     *  We can pick the size for each item from 4 given options. Each size is associated with a value gain. For
     *  example, there're 4 possible sizes, i.e. 1, 2, 3, and 4, valued 0.912, 2.5, 4.088, and 4.763, respectively.
     *  
     *  Constraint: total size of items in a box doesn't exceed the box's size.
     *  
     *  Problem: put items into those boxes so the total value gains is maximized.
     */
    public class BinPacking {
            public static void main(String[] args) throws IOException, ParseException {
                    
                    //dummy data
                    double[] itemSizes = {1, 2, 3, 4};
                    double[] gainsBySize = {0.912, 2.5, 4.088, 4.763};
                    double[] boxSizes = {5, 3, 8};
                    int nItems = 10; 
                    int nBoxes = boxSizes.length;
                    
                    try {
                            // Create the modeler/solver object
                            IloCplex cplex = new IloCplex();
                            
                            // Create decision variable itemSizeDecisions: deciding the size of each item. There're 4 possible options: 0, 1, 2, or 3
                            // e.g. option 1 represents size 2, value 2.5
                            IloIntVar[] itemSizeDecisions = cplex.intVarArray(nItems, 0, itemSizes.length-1);
                            // Create decision variable itemAllocations: saying if a box holds an items (1) or not (0)
                            IloNumVar[][] itemAllocations = new IloNumVar[nItems][];
                            for (int i = 0; i < nItems; i++) {
                                    itemAllocations[i] = cplex.intVarArray(nBoxes, 0, 1);
                    }
                            System.out.println("Decision variables have been created");
                            
                            // setup constraint: size constraint
                            for(int iBox = 0; iBox < nBoxes; iBox++) {
                                    IloLinearNumExpr totalItemSize = cplex.linearNumExpr();
                                    for(int iItem = 0; iItem < nItems; iItem++) {
                                            double itemSize = itemSizes[(int) cplex.getValue(itemSizeDecisions[iItem])];
                                            totalItemSize.addTerm(itemAllocations[nItems][iBox], itemSize);
                                    }
                                    cplex.addLe(totalItemSize, boxSizes[iBox]);
                            }
                            System.out.println("Size constraints have been set up");
                            
                            // setup constraint: each item can be put in one box maximum
                            for(int iItem = 0; iItem < nItems; iItem++) {
                                    cplex.addLe(cplex.sum(itemAllocations[iItem]), 1);
                            }
                            System.out.println("1 item - 1 box constraints have been set up");
                            
                            // setup objective: maximizing total value gains
                            IloLinearNumExpr totalValueGains = cplex.linearNumExpr();
                            for(int iBox = 0; iBox < nBoxes; iBox++) {
                                    for(int iItem = 0; iItem < nItems; iItem++) {
                                            totalValueGains.addTerm(itemAllocations[iItem][iBox], gainsBySize[(int) cplex.getValue(itemSizeDecisions[iItem])]);
                                    }
                            }
                            cplex.addMaximize(totalValueGains);
                    System.out.println("Objective has been set up");
                            
                            // write model to file
                    cplex.exportModel("maxValue.lp");
                    // solve it
                    if ( cplex.solve() ) {
                        cplex.output().println("Solution status = " + cplex.getStatus());
                        cplex.output().println("Solution value  = " + cplex.getObjValue());
                    }
                            
                    } catch (IloException e) {
                            e.printStackTrace();
                    }
                    
            }
    }
    

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Decision variable as parameter

    Posted Wed April 17, 2019 06:23 AM

    With CPLEX you cannot have a decision variable as an index into an array. This has been discussed several times in this forum. You can have this if you use the CP solver, though.

    In your case it seems there is a simple workaround: Instead of having a variable y in { 0, 1, 2, 3 }

    • have four binary variables y[0], y[1], y[2], y[3]
    • Add a constraint y[0] + y[1] + y[2] + y[3] == 1, that way each y[i] stands for one of the options and exactly one option will be chosen
    • Whenever you need the weight of an item use this expression: sum(i in {0, ..., 3}) values[i] * y[i]. This will give the correct value depending on which option is chosen.

    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  RE: Re: Decision variable as parameter

    Posted Thu May 08, 2025 09:45 AM

    Thanks for the clarification-makes total sense that CPLEX doesn't support using a decision variable as an array index directly. I ran into a similar issue while building a simple random decision maker tool and was exploring ways to model discrete choices more cleanly.


    Your workaround using binary variables and enforcing that only one can be active at a time is really helpful. It mimics the selection logic I used-except I wasn't optimizing anything, just simulating fair randomness. But the principle of isolating choices with constraints definitely applies.


    Appreciate the insight! This kind of modeling trick is useful way beyond just CPLEX.



    ------------------------------
    Jasson Adder
    ------------------------------