Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
Expand all | Collapse all

implementation objective function - C++, CPLEX, XCode

  • 1.  implementation objective function - C++, CPLEX, XCode

    Posted 08/19/17 02:45 PM

    Originally posted by: JodokusQuak


    Hey guys,

    first of all a brief summary of my programs:

     

    • Apple Xcode Version 8.3.3 (8E3004b)
    • cplex_studio1263.osx

    Please, find the objective function I'm trying to implement attached. I've got problems with the fourth/fifth sums. Actually I don't know how to handle that one. I tried this one but it is wrong because the position of the fourth/fifth sums (indices j)  has to be like in the mathematical formulation. Anyone who can help me?

     

            IloExpr OF1(env);

            for (int v = 1; v < s+1; v++){

                

                for (int i = 1; i < n+1; i++){

                    

                    for (int t = 1; t < u+1; t++){

                                               

                        for (int j = 1; j < (2*n)+m+1; j++){

                         

                            OF1 += c_down[i][t] * ((z[v][i+n][t] + t_transfer) * x[v][i][j][t]);

                            

                            OF1 += c_down[i][t] * x[v][i][j][t] * (24 * (t - 1));

                        }

                    }

                }

            }

     

            IloObjective MyObj1(env, OF1, IloObjective::Minimize);

            RouteGen.add(MyObj1);

     

    Beste Grüße


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/19/17 07:24 PM

    Originally posted by: EdKlotz


    What exactly are the problems you encounter?   Stack overflow?   Exception being thrown?   If the latter, what is the exception.

     

    I'd recommend you try to simplify the above loop as much as possible and find out the point at which the problem stops occurring.    For example, start by fixing the outermost loop to a single value, i.e. change

    for (int v = 1; v < s+1; v++){

    to

     

    for (int v = 1; v < 2; v++){

     

    Does the problem still occur?   If so, you got something simpler to work with and can try the same thing with the next loop.   If the problem goes away, the fact that it no longer occurs provides some useful info.

     

     

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/20/17 04:50 AM

    Originally posted by: JodokusQuak


    Hi,

    Sorry, maybe I described the problem not that clear. The implementation runs fine but I implemented the formulation wrong - the sums with the indices [j] have to be at the position before the variable x[v][i][j][t]. In my implementation above they are like the others at the beginning. That's not right.


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/20/17 06:09 PM

    Originally posted by: EdKlotz


    OK, thanks for the clarification; I think I understand now.   After looking at your attachment of the mathematical description, I think you need to create a separate IloExpr to handle the summation over j.   In other words, instead of the nested loop of depth 4 in the code segment you previously posted, have a nested loop of depth 3 followed by a separate IloExpr to handle the summation over j.   Try something like

     

    IloExpr OF1(env);

    IloExpr OF2(env);      // This is to handle the summation over j expression

     

            for (int v = 1; v < s+1; v++){

                

                for (int i = 1; i < n+1; i++){

                    

                    for (int t = 1; t < u+1; t++){

                         OF2.clear();

                                               

                        for (int j = 1; j < (2*n)+m+1; j++){

                            OF2 += x[v][i][j][t];

                        }

                         

                        OF1 += c_down[i][t] * ((z[v][i+n][t] + t_transfer) * OF2;

                            

                        OF1 += c_down[i][t] *OF2 * (24 * (t - 1));

                    }

                }

            }

     

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 5.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/21/17 03:15 AM

    Originally posted by: JodokusQuak


    Yes, I already tried something like that as well but without the command 

     

    OF2.clear();

     

    At which position do I have to close the OF2 expression? 

     

            IloExpr OF2(env);

            for (int v = 1; v < s+1; v++){

             

                for (int i = 1; i < n+1; i++){

             

                    for (int t = 1; t < u+1; t++){

             

                        OF2.clear();

                        for (int j = 1; j < (2*n)+m+1; j++){

                            

                            OF2 += x[v][i][j][t];

                        }

                        

                        OF1 += c_down[i][t] * ((z[v][i+n][t] + t_transfer) * OF2);

                        

                        OF1 += c_down[i][t] * (1 - OF2) * 24;

                    }

                }

            }

            

            OF2.end();


    #CPLEXOptimizers
    #DecisionOptimization


  • 6.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/21/17 03:48 AM

    I think it is easier to keep the scope of OF2 as small as possible. Here is a more or less literal translation of the objective function in your screenshot:

       IloExpr obj(env);
       for (int v = 1; v <= s; ++v) {
          for (int i = 1; i <= n; ++i) {
             for (int t = 1; t <= u; ++t) {
                IloExpr xvijt(env);
                for (int j = 1; j <= 2*n + m + 1; ++j)
                   xvijt += x[v][i][j][t];
    
                obj += c_down[i] * (((z[v][i][t] + t_transfer + t_work[i]) * xvijt) +
                                    ((24 * (t - 1)) * xvijt));
    
                xvijt.end();
             }
          }
       }
    

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 7.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/21/17 06:49 AM

    Originally posted by: JodokusQuak


    Great, thanks a lot!

     

    Just to understand your formulation when I don't use braces for the FOR loop it's running vom j = 1 until 2*n+m anyway?

     

    Best regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 8.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/21/17 07:27 AM

    Sorry, I don't understand your question. I am not sure how braces would change the range of a for loop. Can you please be more precise?


    #CPLEXOptimizers
    #DecisionOptimization


  • 9.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/21/17 07:34 AM

    Originally posted by: JodokusQuak


    When I use braces it is like: 

     

    v=1,i=1,t=1 ---> j =1 ---> j = 2, ..., ---> j =2n+m.

     

    If I don't use braces the for loop will start with j = 1 and will run until the end brace of the for loop with indices t. So I thought it would change t = t + 1 without running through all j. But it's working - I just didn't know that it would work that way.

     

    Sorry, I hope it is more clear now. 


    #CPLEXOptimizers
    #DecisionOptimization


  • 10.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/21/17 05:16 PM

    Originally posted by: EdKlotz


    I consider this approach as well, but wondered if constructing and destructing the additional IloExpr three levels down in the nested loop would impose more overhead then the clear() call I used.   But, as long as you don't see any noticeable decline in performance, minimizing the scope is a good idea.


    #CPLEXOptimizers
    #DecisionOptimization


  • 11.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/21/17 05:13 PM

    Originally posted by: EdKlotz


    Yes, if you still want to use this code after the subsequent discussion about scope, you have put the OF2.end() call in the right place.


    #CPLEXOptimizers
    #DecisionOptimization


  • 12.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/21/17 07:19 AM

    Originally posted by: JodokusQuak


    I've got one more question with regard to another part of the objective function. I would like to implement the following part on another way: I don't want that the program is saving every ( q * c_tech). I only want the highest q in period [t] of all periods (but still every [v][b][j]). I hope my explanation is understandable. So I just tried something like IloMax but actually I don't know what to do with it.

     

            /// OF1 secound part ///

            for (int v = 1; v < s+1; v++){

                

                for (long int b = (2*n)+1; b < (2*n)+3; b++){

                    

                    for (int j = 1; j < (2*n)+m+1; j++){

                        

                        for (int t = 1; t < u+1; t++){

                            

                            OF1 += q[v][b][j][t] * c_tech;

                        }

                    }

                }

            }

    ...


    #CPLEXOptimizers
    #DecisionOptimization


  • 13.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/21/17 07:31 AM

    I am not sure I understood correctly. Do you mean, you only want the term 'q[v][b][j][t] * c_tech' for one particular value of one of the indices? Or do you want max(t=1..u) q[v][b][j][t]*c_tech instead of sum(t=1..u) q[v][b][j][t]*c_tech?


    #CPLEXOptimizers
    #DecisionOptimization


  • 14.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/21/17 07:45 AM

    Originally posted by: JodokusQuak


    I want that the program checks the sum of all q[v][b][j] for every period [t]. And then I want that it multiplies the highest value with c_tech.

     

    An example:

    t = 1

    q[1][1][2][1] = 4

    q[2][1][2][1] = 3

    t = 2

    q[1][1][2][2] = 5

    q[2][1][2][2] = 4

    So for t = 1 it is 7 and for t = 2 the sum is 9. So now the program should multiplies 9 * c_tech. 

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 15.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/21/17 09:13 AM

    This (untested) code might do the trick:

    IloNumExprArray sums(env); // sums[t] is sum(v,b,j)q[v][b][j][t]
    for (int t = 1; t <= u; ++t) {
       // Create the sum of q[*][*][*][t]
       IloExpr sum(env);
       for (int v = 1; v <= ...; ++v)
          for (int b = 1; b <= ...; ++b)
             for (int j = 1; j <= ...; ++j)
                sum += q[v][b][j][t];
       sums.add(sum);
       sum.end();
    }
    obj += c_tech * IloMax(sums); // IloMax() yields the maximum of all elements
                                  // in sums
    sums.end();
    

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 16.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/21/17 10:44 AM

    Originally posted by: JodokusQuak


    The program runs but there is no difference in the obj value if I implement your variant or not although the maximum value should be 9 (that was the highest value over all t).


    #CPLEXOptimizers
    #DecisionOptimization


  • 17.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/21/17 05:45 PM

    Originally posted by: EdKlotz


    When you get an unexpected result like this, use IloCplex.exportModel to write out an LP file of the model.    Do it on a small instance of the model that you can understand fully.   The LP file should help you identify which part of the objective is unexpected, and you work back from there to identify how you need to change the code.

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 18.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 03:19 AM

    Originally posted by: JodokusQuak


    Yes, that is what I always do but that's the point. Doesn't matter if I implement the obj part above or not the obj value doesn't change. (u+1, ... is not the problem - I checked <= u and so on as well)

     

           IloNumExprArray sums(env); // sums[t] is sum(v,b,j)q[v][b][j][t]

            

           for (int t = 1; t < u+1; t++) {

                

                // Create the sum of q[*][*][*][t]

                

                IloExpr sum(env);

                

                for (int v = 1; v < s+1; v++)

                    

                    for (long int b = (2*n)+1; b < (2*n)+3; b++)

                        

                        for (int j = 1; j < (2*n)+m+1; j++)

                            

                sum += q[v][b][j][t];

                sums.add(sum);

                sum.end();

            }

            

            OF1 += c_tech * IloMax(sums); // IloMax() yields the maximum of all elements

            // in sums

            sums.end();


    #CPLEXOptimizers
    #DecisionOptimization


  • 19.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 06:53 AM

    Originally posted by: JodokusQuak


    Is it possible to read out the IloMax(sums)? So I could check if the value is right.


    #CPLEXOptimizers
    #DecisionOptimization


  • 20.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 07:35 AM

    What do you get by just printing out 'sums', IloMax(sums), and OF1?


    #CPLEXOptimizers
    #DecisionOptimization


  • 21.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 07:40 AM

    Originally posted by: JodokusQuak


    How do I print "sums" and "IloMax(sums) out? I get my obj value like this:

     

    cout << cplex.getValue(OF1) << endl;

     

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 22.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 07:54 AM

    Have you tried

    cout << OF1 << " " << sums << " " << IloMax(sums) << endl;
    

    ? Of course you have to do that before end()ing the stuff.


    #CPLEXOptimizers
    #DecisionOptimization


  • 23.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 09:12 AM

    Originally posted by: JodokusQuak


    I tried it this way (screenshot attached) but then I get an error. Sorry, for sure it is pretty simple for you guys - I'm trying my best. 

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 24.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 09:25 AM

    Originally posted by: JodokusQuak


    At another position only with IloMax(sums) I get this output (screenshot attached).


    #CPLEXOptimizers
    #DecisionOptimization


  • 25.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 09:29 AM

    Can you try to remove the sum.end() statement? Does this work any better?


    #CPLEXOptimizers
    #DecisionOptimization


  • 26.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 09:43 AM

    Originally posted by: JodokusQuak


    Wow, it's working - you're right when I remove sum.end() it is calculating (9 * c_tech). Great! But do I have anywhere to end() "sum"? 

    The strange thing is that it's working as well when I write "cout ..." in front of sum.end() like in the last screenshot. 

     

    cout << IloMax(sums) << " " << endl;

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 27.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 10:22 AM

    Originally posted by: EdKlotz


    The first word to remember any time you get something unexpected is: simplify.    So, you got something weird in
    cout << OF1 << " " << sums << " " << IloMax(sums) << endl;

     

    Then rewrite it as:

     

    cout << OF1 << endl;

    cout << sums << endl;

    cout << IloMax(sums) << endl;

     

    so you can see exactly which of the 3 expressions you are printing is the source of the error.

    As far as the output displayed goes, most of the variables printed out (presumably in OF1 have bounds of [0..1], then suddenly the bounds become quite large with a rather strange looking value.   Is that expected?   If not, maybe the issue lies in the creation or dimensioning of the variables in the OF1 expression.


    #CPLEXOptimizers
    #DecisionOptimization


  • 28.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 11:13 AM

    Originally posted by: JodokusQuak


    Thanks for the advice. I don't know why the bounds are suddenly that high but by removing "sum.end()" it's working now.


    #CPLEXOptimizers
    #DecisionOptimization


  • 29.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 12:46 PM

    Originally posted by: EdKlotz


    What do you mean when you say "it's working"?   If you are getting the correct results but you still have those mysterious big bounds, I would say that you are getting the correct results, but I would not say "it's working".   You still need to address those bug bounds, or they will cause some other problem later.    Or did the removal of the sum.end() call also address the big bound problem?


    #CPLEXOptimizers
    #DecisionOptimization


  • 30.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 01:10 PM

    Originally posted by: JodokusQuak


    I get the right results but I think the big bounds are still there. Sorry, I don't really know what to do with it or why it could be wrong. Maybe it's because of the printout:

    cout << IloMax(sums) << endl; 

     

    If I remove that I dont get any of these:

    t = 1

    max([IloIntVar(8694)[0..9007199254740991]  + IloIntVar(8699)[0..9007199254740991]  + IloIntVar(8704)[0..9007199254740991]  + IloIntVar(8709)[0..9007199254740991]  + IloIntVar(8714)[0..9007199254740991]  + IloIntVar(8719)[0..9007199254740991]  + IloIntVar(8724)[0..9007199254740991]  + IloIntVar(8729)[0..9007199254740991]  + IloIntVar(8734)[0..9007199254740991]  + IloIntVar(8739)[0..9007199254740991]  + IloIntVar(8744)[0..9007199254740991]  + IloIntVar(8749)[0..9007199254740991]  + IloIntVar(8754)[0..9007199254740991]  + IloIntVar(8759)[0..9007199254740991]  + IloIntVar(8764)[0..9007199254740991]  + IloIntVar(8769)[0..9007199254740991]  + IloIntVar(8779)[0..9007199254740991]  + IloIntVar(8784)[0..9007199254740991]  + IloIntVar(8789)[0..9007199254740991]  + IloIntVar(8794)[0..9007199254740991]  + IloIntVar(8799)[0..9007199254740991]  + IloIntVar(8804)[0..9007199254740991]  + IloIntVar(8809)[0..9007199254740991]  + IloIntVar(8814)[0..9007199254740991]  + IloIntVar(8819)[0..9007199254740991]  + IloIntVar(8824)[0..9007199254740991]  + IloIntVar(8829)[0..9007199254740991]  + IloIntVar(8834)[0..9007199254740991]  + IloIntVar(8839)[0..9007199254740991]  + IloIntVar(8844)[0..9007199254740991]  + IloIntVar(8849)[0..9007199254740991]  + IloIntVar(8854)[0..9007199254740991]  + IloIntVar(10139)[0..9007199254740991]  + IloIntVar(10144)[0..9007199254740991]  + IloIntVar(10149)[0..9007199254740991]  + IloIntVar(10154)[0..9007199254740991]  + IloIntVar(10159)[0..9007199254740991]  + IloIntVar(10164)[0..9007199254740991]  + IloIntVar(10169)[0..9007199254740991]  + IloIntVar(10174)[0..9007199254740991]  + IloIntVar(10179)[0..9007199254740991]  + IloIntVar(10184)[0..9007199254740991]  + IloIntVar(10189)[0..9007199254740991]  + IloIntVar(10194)[0..9007199254740991]  + IloIntVar(10199)[0..9007199254740991]  + IloIntVar(10204)[0..9007199254740991]  + IloIntVar(10209)[0..9007199254740991]  + IloIntVar(10214)[0..9007199254740991]  + IloIntVar(10224)[0..9007199254740991]  + IloIntVar(10229)[0..9007199254740991]  + IloIntVar(10234)[0..9007199254740991]  + IloIntVar(10239)[0..9007199254740991]  + IloIntVar(10244)[0..9007199254740991]  + IloIntVar(10249)[0..9007199254740991]  + IloIntVar(10254)[0..9007199254740991]  + IloIntVar(10259)[0..9007199254740991]  + IloIntVar(10264)[0..9007199254740991]  + IloIntVar(10269)[0..9007199254740991]  + IloIntVar(10274)[0..9007199254740991]  + IloIntVar(10279)[0..9007199254740991]  + IloIntVar(10284)[0..9007199254740991]  + IloIntVar(10289)[0..9007199254740991]  + IloIntVar(10294)[0..9007199254740991]  + IloIntVar(10299)[0..9007199254740991]  + IloIntVar(11584)[0..9007199254740991]  + IloIntVar(11589)[0..9007199254740991]  + IloIntVar(11594)[0..9007199254740991]  + IloIntVar(11599)[0..9007199254740991]  + IloIntVar(11604)[0..9007199254740991]  + IloIntVar(11609)[0..9007199254740991]  + IloIntVar(11614)[0..9007199254740991]  + IloIntVar(11619)[0..9007199254740991]  + IloIntVar(11624)[0..9007199254740991]  + IloIntVar(11629)[0..9007199254740991]  + IloIntVar(11634)[0..9007199254740991]  + IloIntVar(11639)[0..9007199254740991]  + IloIntVar(11644)[0..9007199254740991]  + IloIntVar(11649)[0..9007199254740991]  + IloIntVar(11654)[0..9007199254740991]  + IloIntVar(11659)[0..9007199254740991]  + IloIntVar(11669)[0..9007199254740991]  + IloIntVar(11674)[0..9007199254740991]  + IloIntVar(11679)[0..9007199254740991]  + IloIntVar(11684)[0..9007199254740991]  + IloIntVar(11689)[0..9007199254740991]  + IloIntVar(11694)[0..9007199254740991]  + IloIntVar(11699)[0..9007199254740991]  + IloIntVar(11704)[0..9007199254740991]  + IloIntVar(11709)[0..9007199254740991]  + IloIntVar(11714)[0..9007199254740991]  + IloIntVar(11719)[0..9007199254740991]  + IloIntVar(11724)[0..9007199254740991]  + IloIntVar(11729)[0..9007199254740991]  + IloIntVar(11734)[0..9007199254740991]  + IloIntVar(11739)[0..9007199254740991]  + IloIntVar(11744)[0..9007199254740991] ])


    #CPLEXOptimizers
    #DecisionOptimization


  • 31.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 05:55 PM

    Originally posted by: EdKlotz


    Googling 9007199254740991, I get

     

    >>>>>>

    9007199254740991 is a positive integer equal to 2531. It is notable in computer science for being the largest odd number which can be represented exactly in the double floating-point format (which has a 53-bit significand).

    Its prime factorization is 9007199254740991 = 6361 × 69431 × 20394401.

    >>>>>>

     

    So this doesn't look like any sort of uninitialized memory access issue with your program..   Does you program declare some integer variables with infinite upper bounds?   That might explain it, although if your IloMax involves finding maximums of numerical values rather than linear expressions, I don't see why your print statement for IloMax should generate all sorts of IloIntVars.

     

     

     

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 32.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/23/17 02:23 AM

    Originally posted by: JodokusQuak


    Yes, I declared all my variables with infinite upper bounds - sounds like it would be better to minimise these bounds to reduce the running time?


    #CPLEXOptimizers
    #DecisionOptimization


  • 33.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/23/17 11:04 AM

    Originally posted by: EdKlotz


    If you have model knowledge that allows you to use smaller upper bounds, by all means use them.   While in general smaller bounds are conceptually a good idea, I don't know whether smaller bounds will help performance on your model or not.   That depends on whether the larger bounds were contributing to slower performance or not.


    #CPLEXOptimizers
    #DecisionOptimization


  • 34.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 11:23 AM

    Originally posted by: JodokusQuak


    I've got another issue which is pretty similar to that one before.

    Now I've got the variable x[v][i][j][t] (instead of q) which is binary. Further I've got the parameter array c_vessel[v] (instead of c_tech) which I have to multiplies with the IloMax value. Now, the problem is that it isn't anymore that simple to multiplies the highest value with c_vessel[v]. 

     

    An example: 

    t = 1 

    x[1][1][2][1] = 1

    x[2][1][3][1] = 1

    x[3][1][2][1] = 0

    t = 2

    x[1][1][2][2] = 0

    x[2][1][3][2] = 0

    x[3][1][2][2] = 0

     

    So for t = 1 it is 2 and for t = 2 the sum is 0. But now it is not that simple to multiplies "2*c_vessel" because now it is like "c_vessel[1] = 5" and "c_vessel[2] = 3" so it has to be at the end like "1*5 + 1*3". 

    Any idea? (Screenshot attached)


    #CPLEXOptimizers
    #DecisionOptimization


  • 35.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 12:25 PM

    Sorry, I don't see the problem or I am missing something. What is wrong if you write

    sum += c_vessel[v] * x[v][i][j][t]

    instead of

    sum += x[v][i][j][t]

    ?


    #CPLEXOptimizers
    #DecisionOptimization


  • 36.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/22/17 01:00 PM

    Originally posted by: JodokusQuak


    I think I have to describe the problem on another way. 

     

    [v] = a vessel which cost something.

     

    If [v]=1 is used in any period [t] you have to pay like 500 MU once. It can be used in more than one period and still you just have to pay the 500 MU one time. The same rule applies for any other vessel [v]. 

    So if I implement the problem like the formulation above I've got the following problem:

     

    t = 1  

    x[1][1][2][1] = 1 * c_vessel[1] = 500 MU

    x[2][1][3][1] = 1 * c_vessel[2] = 500 MU

    x[3][1][2][1] = 0 * c_vessel[3] = 0 MU

    x[6][1][3][1] = 1 * c_vessel[6] = 500 MU

    t = 2 

    x[2][1][4][2] = 1 * c_vessel[2] = 500 MU --> dont have to pay again 

    x[3][1][4][2] = 1 * c_vessel[3] = 250 MU

    x[4][1][5][2] = 1 * c_vessel[4] = 250 MU

    x[5][1][6][2] = 1 * c_vessel[5] = 250 MU

     

    So IloMax would now add 1500 MU to OF1. But given the fact that in period t=2 there were three other vessels used (v=3, v=4, v=5) they have to be paid as well. So actually the value should be 1750 MU for all vessels. Vessel v=2 was used in both periods but still you just have to pay one time (500 MU).

     

    Sorry, the other explanation wasn't that right.

     

     

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 37.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/23/17 02:41 AM

    Originally posted by: JodokusQuak


    So when the sum of all x[v][b][j][t] for a particular vessel [v] over all periods [t] is higher then 0 (x could be 1 in every period for a vessel v) than I want to add OF1 += c_vessel[v] (but just once). In the following implementation the problem is that c_vessel will be add more than one time to OF1 if the vessel was used in several periods.

     

            for (int v = 1; v < s+1; v++){

                

                for (long int b = (2*n)+1; b < (2*n)+3; b++)

                    

                    for (int j = 1; j < (2*n)+m+1; j++)

                

                        for (int t = 1; t < u+1; t++)

                

                OF1 += c_vessel[v] * x[v][b][j][t];

            }


    #CPLEXOptimizers
    #DecisionOptimization


  • 38.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/23/17 03:40 AM

    Originally posted by: JodokusQuak


    Should be something like this I think:

     

            IloNumExprArray sums(env); // sums[v] is sum(b,j,t)x[v][b][j][t]

            

            for (int v = 1; v < s+1; v++){

                

                IloExpr sum(env);

                

                for (long int b = (2*n)+1; b < (2*n)+3; b++)

                    

                    for (int j = 1; j < (2*n)+m+1; j++)

                

                        for (int t = 1; t < u+1; t++)

                

                sum += x[v][b][j][t];

                sums.add(sum);

                //(...)

            }

            

            // sums is like sum of all x over all periods for each v [v=1,v=2,v=3,v=4] = [2, 0, 1, 4]

            // so if the sum of all x over all periods for a v is >0 than add once OF1 += c_vessel[v]

            // so in this example := OF1 += c_vessel[1]; OF1 += c_vessel[3]; OF1 += c_vessel[4]

     

    But I don't know how to add now OF1 += c_vessel[v] just once even when the sum of all x for a vessel v is higher than 1.


    #CPLEXOptimizers
    #DecisionOptimization


  • 39.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/23/17 06:16 AM

    One simple way to model this would be to create an auxiliary variable used[v] that indicates whether vessel v is used at any time.

    Then add constraints

    x[v][b][j][t] <= used[v]   for all v, b, j, t

    and to the objective

    sum(v) used[v] * c_vessel[v]

    Since your objective sense is "minimize" used[v] will not be set to 1 unless vessel v is used in any period.

    If you want to go with the IloMax formulation I think you just have to compute a nested max like

    c_vessel[v] * max(t) max(b,j) x[v][b][j][t]

    max(b,j) x[v][b][j][t] = 1 if vessel v is used in time period t, 0 otherwise
    max(t) max(b,j) x[v][b][j][t] = 1 if vessel v is used in any time period, 0 otherwise
     


    #CPLEXOptimizers
    #DecisionOptimization


  • 40.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/28/17 02:58 AM

    Originally posted by: JodokusQuak


    Great, it's working this way. Thanks a lot, Daniel.

     

    I've got to other issues. Maybe you can help me out. .

     

    1) Now, I have to realise for the "max" constraint that I add to the objective function the max values of the first b = (2*n)+

    and the secound b = (2*n)+2. It is possible that they don't have their highest values in the same period. So I tried it the way to duplicate the constraint. It seems that I get the right values but the calculation time is now 1000 sec higher. Is there another way to save calculation time?

     

            IloNumExprArray sums(env); // sums[t] is sum(v,b,j)q[v][b][j][t]

            

            for (int t = 1; t < u+1; t++) {

                

                // Create the sum of q[*][*][*][t]

                

                IloExpr sum(env);

                

                for (int v = 1; v < s+1; v++)

                        

                    for (int j = 1; j < (2*n)+m+1; j++)

                            

                sum += q[v][(2*n)+1][j][t];

                

                sums.add(sum);

            }

            

            OF1 += c_tech * IloMax(sums); // IloMax() yields the maximum of all elements

            // in sums

            sums.end();

            

     

            IloNumExprArray sums2(env); // sums2[t] is sum(v,b,j)q[v][b][j][t]

            

            for (int t = 1; t < u+1; t++) {

                

                // Create the sum of q[*][*][*][t]

                

                IloExpr sum2(env);

                

                for (int v = 1; v < s+1; v++)

                    

                    for (int j = 1; j < (2*n)+m+1; j++)

                        

                        sum2 += q[v][(2*n)+2][j][t];

                

                sums2.add(sum2);

            }

            

            OF1 += c_tech * IloMax(sums2); // IloMax() yields the maximum of all elements

            // in sums2

            sums2.end();

     

    2) My second issue is the important one: I have another problem with the constraint which one we discussed earlier:

     

            for (int v = 1; v < s+1; v++){

             

                for (int i = 1; i < c+1; i++){

             

                    for (int t = 1; t < u+1; t++){

             

                        IloExpr x_sum(env);

                        for (int j = 1; j < (2*n)+m+1; j++)

                            

                            x_sum += x[v][i][j][t];

                            

                        OF1 += c_down[i][t] * (((z[v][i+n][t] + t_transfer[i]) * x_sum) + (24 * (1 - x_sum)));

                        

                        x_sum.end();

                    }

                }

            }

    The problem is that this formulation is adding the (24 * ... section) for every vessel [v] to the objective function. I want that it's adding this section one time to OF1 if no vessel [v] startet from [i] in [t]. So I tried it this way:

    Now, I've got the problem that it's still adding the (24 * ... section) to the obj function even when any vessel [v] startet already from [i] in any period [t] before. So an example: If vessel [v] traveled from [i] to [j] in t=3 of 4 periods then I want that the programming is adding 2 times (for t=1 and t=2) the (24 * ... section) to the obj function but not for the last period t=4 or any period after. Do you understand my problem? 

     

                for (int i = 1; i < c+1; i++){

                    

                    for (int t = 1; t < u+1; t++){

                        

                        IloExpr x_sum(env);

                        for (int v = 1; v < s+1; v++)

                            

                        for (int j = 1; j < (2*n)+m+1; j++)

                            

                            x_sum += x[v][i][j][t];

                        

                        OF1 += c_down[i][t] * (24 * (1 - x_sum));

                        

                        x_sum.end();

                }

            }


    #CPLEXOptimizers
    #DecisionOptimization


  • 41.  Re: implementation objective function - C++, CPLEX, XCode

    Posted 08/28/17 06:11 AM

    Originally posted by: JodokusQuak


    I think I solved the second problem. So I got just the open question 1).


    #CPLEXOptimizers
    #DecisionOptimization