Decision Optimization

Decision Optimization

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

 View Only
Expand all | Collapse all

Different notation

  • 1.  Different notation

    Posted Tue May 07, 2019 06:53 AM

    Originally posted by: A.Omidi


    Hello everyone,

    I'm working on the LP model that has assignment constraints (using Java API). I have used two types of CPLEX notation for Assignment constraints. Type-1 by using:

    for (int i = 0; i < m; i++) {
        cplex.addEq(cplex.sum(x[i]),1,"assign_" + i + "_once");
        }
    

    And type-2 by using:

    for (int i = 0; i < m; i++) {
        IloLinearNumExpr expr = cplex.linearNumExpr();
        for (int j = 0; j < n; j++) {
            expr.addTerm(1, x[i][j]);
            }
        cplex.addEq(expr, 1);
    }
    

    Based on these two types of notation the model solves optimally with the same objective value.

    My first question is, what is different between these two types of notation?

    I try to write a TSP problem using type-1 notation. While I run the model it has an error and does not work.
    I was wondering if, you could tell me is there any way to write the TSP model using type-1 notation or only possible way is using type-2?

     

    Regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Different notation

    Posted Tue May 07, 2019 09:13 AM

    The two notations you showed are equivalent. Both of them build up an expression that represents the some of all variables in x[i] and then add an equation that requires this sum to be 1.

    If you want us to guess what is wrong with your TSP code then can you please show the code that does not work? And probably also the code that does work so that we can see what is supposed to happen.


    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: Different notation

    Posted Tue May 07, 2019 11:52 AM

    Originally posted by: A.Omidi


    Dear Daniel,

    Thanks for your attention. As per your comment, please, see the attached file (TSP.java).
    In the first case, the type-1 notation applies and the model does not a feasible solution but, in the second case, (type-2) it works fine.
    Could you tell me please, how type-1 notation can extract multi indices variables? (in my case, I have two-dimensional variable x[i][j] but, in the constraint, it uses one- dimensional variable).

     

    Regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: Different notation

    Posted Tue May 07, 2019 05:24 PM

    This has nothing to do with CPLEX. The Java code

          for (int i = 0; i < n; i++) {
               if (i != i++)
                   // do something here
          }

    will never execute commented line because it reads the conditional as "test whether i does not equal i, then increment i". So the test will always return false, and the post-increment means that you will only execute the loop for i = 0, 2, 4, ...

    Assuming that x[i][i] is required to be zero, to use what you call the "Type-1" approach you could do the following:

    • define x[i][j] to be boolean variables for all i, j including i = j;
    • set the upper bound of x[i][i] to be 0 for all i;
    • remove the "if (i != i++) line from your "Type-1" code.

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 5.  Re: Different notation

    Posted Wed May 08, 2019 06:45 AM

    Originally posted by: A.Omidi


    Dear Prof. Rubin,

    Thanks for your useful advise. It works fine.

    I was wondering if, you could advise me how can I implement multi-dimensional arrays (such as x[i][j][k]) using type-1 notation?

     

    Regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 6.  Re: Different notation

    Posted Wed May 08, 2019 03:16 PM

    Add an extra loop both places. When you define x[i][j][k], it's in a k-loop nested in a j-loop nested in an i-loop. When you create the constraint, you sum x[i][j] (which is a one-dimensional array), nested in a j-loop that is nested in an i-loop.


    #CPLEXOptimizers
    #DecisionOptimization


  • 7.  Re: Different notation

    Posted Fri May 10, 2019 07:37 AM

    Originally posted by: A.Omidi


    Dear Prof. Rubin,

    Thanks for your comment. I need to write a specific constraint using type-1 notation. The type-2 notation of constraint is:

                            for (int i = 0; i < stage.length; i++) {
                                    for (int k = 0; k < parts.length; k++) {
                                            IloLinearNumExpr Machine_Assignment = model.linearNumExpr();
                                            for (int n = 0; n < map.get(stage[i]).length; n++) {
                                                    Machine_Assignment.addTerm(1, x[i][n][k]);
                                            }
                                            model.addEq(Machine_Assignment, 1);
                                    }
                            }
    

    I try to write this using type-1 such as below:

                            for (int i = 0; i < stage.length; i++) {
                                    for (int k = 0; k < parts.length; k++) {
                                            model.addEq(model.sum(x[i][k]), 1.0);
                                    }
                                    }
    

    I was trying to write the specific filter on the "n" index but, when I solved the model the result didn't correct.

    Would you please, say that is there any specific way to show filter on "n"? if so, how can I fix it?

     

    Regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 8.  Re: Different notation

    Posted Fri May 10, 2019 03:39 PM

    No, you cannot use "type-1" notation here. This is a Java issue, not a CPLEX issue. Given a three dimensional array x[][][] of any type, x[i] is a pointer to a 2-D array of the same type and x[i][j] is a pointer to a 1-D array, but there is simple way (other than looping) to get a "slice" x[i][][k].


    #CPLEXOptimizers
    #DecisionOptimization


  • 9.  Re: Different notation

    Posted Mon May 13, 2019 03:34 AM

    Actually, with Java 8 you can do slicing. Or at least something that is very similar to slicing. It is however pretty obscure and in this case I would advise against using that just so that you can build a sum.

    In any case, here is a code that creates a 3-dimension variable indexed by I, J, K and then creates an array with all variables x[1][*][2]:

    import ilog.cplex.IloCplex;
    import ilog.concert.IloException;
    import ilog.concert.IloNumVar;
    import java.util.stream.IntStream;

    public final class Slice {
       public static void main(String[] args) throws IloException {
          final IloCplex cplex = new IloCplex();
          try {
             final int I = 3;
             final int J = 4;
             final int K = 5;
             final IloNumVar[][][] x = new IloNumVar[I][][];
             for (int i = 0; i < I; ++i) {
                x[i] = new IloNumVar[J][];
                for (int j = 0; j < J; ++j) {
                   x[i][j] = new IloNumVar[K];
                   for (int k = 0; k < K; ++k)
                      x[i][j][k] = cplex.numVar(0, 1, i + "." + j + "." + k);
                }
             }
          
             IloNumVar[] collect = IntStream
                .range(0, J)
                .mapToObj(j -> x[1][j][2])
                .toArray(IloNumVar[]::new);
             System.out.println(java.util.Arrays.toString(collect));
          }
          finally {
             cplex.end();
          }
       }
    }

    Like I said, I would not use it but I provide it for sake of completeness.


    #CPLEXOptimizers
    #DecisionOptimization


  • 10.  Re: Different notation

    Posted Tue May 14, 2019 02:38 PM

    Originally posted by: A.Omidi


    Dear Prof. Rubin,

    Dear Daniel,

    Thanks for your useful advice.

    First, I apologized, because I don't understand Prof. Rubin idea about using the "slice" method. I was trying  to use some slice method such as:

    if (Arrays.asList(map.get(stage[i]).length).subList(...).contains(machi.lenth));
    Or 
    Arrays.copyOfRange(myArray, startIndex, endIndex);
    

    But, they didn't work correct.

    According to Daniel's email, I have defined variable x once in the first and might I can't use it once again in the constraint. I think I can't use type-1 notation to express such specific filtering (as Prof. Rubin mentioned too).

    I was wondering if, you could say does CPLEX has any way to express my specific filtering without using type-2 notation?

     

    Regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 11.  Re: Different notation

    Posted Tue May 14, 2019 03:47 PM

    I can't understand the three lines of code in your latest post. The first line is an if statement that does nothing even if the condition is true. Line 2 has the symbol "Or", which I don't recognize as a Java keyword. Line 3 seems to make a copy of part of an array but then does not assign it to anything.

    At any rate, the methods CPLEX provides in its Java API for constructing linear expressions (such as IloCplexModeler.sum() IloCplexModeler.scalProd()) typically have two variants. One takes a single variable (such as x[i][j][k] in your case). The other takes a one-dimensional array of variables. The key here is that the variables are stored in consecutive locations within that array. For any three-dimensional array x[][][], regardless of type (IloNumVar or String or int ...), x[i][j] is a one-dimensional array of consecutive entries of that type. Similarly, x[i] is a one-dimensional array of two-dimensional arrays.

    So if you want to work with x[i][j][0], x[i][j][1], ..., you can use the vector version of a modeling function and feed it x[i][j]. If you want to work with x[i][0][k], x[i][1][k], x[i][2][k], ...., you have to create a new vector with those entries scored consecutively. Daniel showed you how to do that using streams. You can also do it by declaring a new IloNumVar[] array and then filling it with a loop. So your code would have a shape like this:

    for i= ...

      for k = ...

        declare IloNumVar[] vector xx

        for j = ...

          put x[i][j][k] in j-th slot of xxx

        end for j

        use xx in a modeling expression

      end for k

    end for i

    Because x[i][0][k], x[i][1][k] ... are not stored in consecutive locations of the x matrix, you have to do some reshaping if you want to use "type 1" notation.

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 12.  Re: Different notation

    Posted Wed May 15, 2019 04:59 AM

    Originally posted by: A.Omidi


    Dear Prof. Rubin,


    I appreciate your taking the time to explain. Things that I mentioned are snippet code that, however,  they didn't work.

    I was trying Daniel's suggestion code but, it did not work on my specific filter. My problem with notation type-1 is, I can not depict model specific filter on it. In the type-2 notation, it is easy but, in the type-1 it's complicated. As your suggestion, I will try to use vector. I don't use it up to now to my problem.


    Thanks once again.

    Regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 13.  Re: Different notation

    Posted Wed May 15, 2019 11:47 AM

    Can you elaborate why the slicing did not work?

    Also, is there a reason you want to use notation 1 although it ls harder to write and less efficient? Whatever you do to create the input array for cplex.sum(), you will end up doing exactly the loop you do for notation 2. So what is the benefit of forcing notation 1 here?


    #CPLEXOptimizers
    #DecisionOptimization


  • 14.  Re: Different notation

    Posted Thu May 16, 2019 08:47 AM

    Originally posted by: A.Omidi


    Dear Daniel,

    Thanks for your attention. The slice method you mentioned, has worked on the specific range of the sets. As following:

                            for (int i = 0; i < stage.length; i++) {
                                    for (int k = 0; k < parts.length; k++) {
                                            final IloNumVar[] collect = IntStream.range(0, machi.length).mapToObj(j -> x[1][j][2]).toArray(IloNumVar[]::new);
                                            model.addEq(model.sum(collect), 1.0);
                                    }
                            }
    


    While using the method, I have to determine some variables and add them to it but, I need to add the variables through the model constraint. It should be capable of doing my specific filter too. It doesn't work through the loops (might, I don't have enough knowledge to use it, then any help is appreciated).

    My reasons to use type-1 are, I want to compare two types of notation together. In the instance TSP problem, the notation type-1 has been the same performance as notation type-2. Then I was trying carried out them on the scheduling model and compare the results. Indeed, it's interesting to me that I can write the model using two notations.

    As the previous email, I will try to use vector. I will hope I can do it.

     

    Regards


    #CPLEXOptimizers
    #DecisionOptimization