Topic
19 replies Latest Post - ‏2013-02-05T06:43:17Z by SystemAdmin
FANS_Nader_Al_Theeb
FANS_Nader_Al_Theeb
46 Posts
ACCEPTED ANSWER

Pinned topic Using different objective functions

‏2013-01-15T03:54:39Z |
Dear all

I'm solving a problem using an objective such as

model.add(IloMinimize(env, cost_C ));


Based on the optimal value, I take a copy from the model, modify it by adding some constraints and changing the objective. when I try to solve the new model, I receive an error " IloCplex can not handle multiple objectives". The following shows the procedure:

IloModel model3(env);
cplex.extract(model3);
model3.add(model);
.
.
.
 model3.add(IloMinimize(env, cost_W + cost_Wo));
.
.
cplex.solve();

Any help of why I got the error message.

Thanks
Nader
Updated on 2014-03-24T22:40:45Z at 2014-03-24T22:40:45Z by iron-man
  • SystemAdmin
    SystemAdmin
    7944 Posts
    ACCEPTED ANSWER

    Re: Using different objective functions

    ‏2013-01-15T07:14:04Z  in response to FANS_Nader_Al_Theeb
    CPLEX supports only a single objective (not multiple objectives). The sequence
    model.add(IloMinimize(...));
    model3.add(model);
    model3.add(IloMinimize(...));
    

    results in two objective functions in model3, that is why you get the exception.
    It should help to do
    model3.remove(model3.getObjective());
    

    before adding the objective function to model3.
    Updated on 2014-03-24T22:42:10Z at 2014-03-24T22:42:10Z by iron-man
    • SystemAdmin
      SystemAdmin
      7944 Posts
      ACCEPTED ANSWER

      Re: Using different objective functions

      ‏2013-01-15T07:15:58Z  in response to SystemAdmin
      Sorry, the IloModel class has no getObjective() function.
      So you need to use IloModel::Iterator to find the objective function and then remove it via IloModel::remove.
      • FANS_Nader_Al_Theeb
        FANS_Nader_Al_Theeb
        46 Posts
        ACCEPTED ANSWER

        Re: Using different objective functions

        ‏2013-01-15T16:10:29Z  in response to SystemAdmin
        Thanks for your reply, would you please give me a short example of how can we use the "Iterator" command? because I found some difficulties in applying this.
        Thanks
        • SystemAdmin
          SystemAdmin
          7944 Posts
          ACCEPTED ANSWER

          Re: Using different objective functions

          ‏2013-01-15T22:56:21Z  in response to FANS_Nader_Al_Theeb
          You might find this blog post helpful. (It uses the Java API, but the C++ API is similar.)

          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)
        • SystemAdmin
          SystemAdmin
          7944 Posts
          ACCEPTED ANSWER

          Re: Using different objective functions

          ‏2013-01-16T07:26:07Z  in response to FANS_Nader_Al_Theeb
          If you search this forum for "IloModel::Iterator" then you will find plenty of code snippets that illustrate how to use this iterator.
          • FANS_Nader_Al_Theeb
            FANS_Nader_Al_Theeb
            46 Posts
            ACCEPTED ANSWER

            Re: Using different objective functions

            ‏2013-01-29T18:52:52Z  in response to SystemAdmin
            Dear Daniel

            I read most of the posts that talking about Iterator, but still I have the problem to understand it.

            My question is "what the role of Iterator? is it just to find the objective?"

            If so, how I can delete the old objective function and re-enter a new one?

            Thanks in advance
            • SystemAdmin
              SystemAdmin
              7944 Posts
              ACCEPTED ANSWER

              Re: Using different objective functions

              ‏2013-01-29T22:44:38Z  in response to FANS_Nader_Al_Theeb
              If you are building the model yourself (which your original post suggests), rather than reading a model from an LP or SAV file, you don't need an iterator to switch objective functions. IloModel::add() returns the handle of the added object (essentially a pointer to it). So just assign the return value to a variable, then use the variable as the argument to IloModel::remove() to remove that objective function, and then add a new objective the same way you added the first one.

              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)
              • FANS_Nader_Al_Theeb
                FANS_Nader_Al_Theeb
                46 Posts
                ACCEPTED ANSWER

                Re: Using different objective functions

                ‏2013-01-30T03:18:23Z  in response to SystemAdmin
                Hi, thank you Paul, I understand you

                May I ask you other question?

                When I solve the model 100 times, once each iteration, I received "Killed" message which I think means out of memory

                I don't know why this happens, because I think each iteration I start a new model without saving anything. So the memory should be cleaned and re-start

                Is there any solution to this problem?

                Thanks a lot
                • SystemAdmin
                  SystemAdmin
                  7944 Posts
                  ACCEPTED ANSWER

                  Re: Using different objective functions

                  ‏2013-01-30T13:08:50Z  in response to FANS_Nader_Al_Theeb
                  Do you invoke the end() function at the end of the loop?
                  Note that for classes like IloEnv, IloModel, IloCplex and many others it is not sufficient to let them go out of scope. You have to explicitly invoke the end() member function to release all memory they have allocated.
                  • FANS_Nader_Al_Theeb
                    FANS_Nader_Al_Theeb
                    46 Posts
                    ACCEPTED ANSWER

                    Re: Using different objective functions

                    ‏2013-01-30T18:25:41Z  in response to SystemAdmin
                    Thank you all

                    I have more question, hoping it will be the last question
                    I solve the "killed" problem by bringing the first two lines outside the loop in the following. I have the following procedure:


                    IloCplex cplex(env);
                     cplex.extract(model);
                     
                    for (i=1; i<100; i++){
                     
                    IloModel model2(env);
                    cplex.extract(model2);
                    model2.add(model);
                     
                    Modify model 2
                     
                    solve model 2
                     
                    model2.end()
                     
                    }
                    

                    If I don't use "model2.end()", is this correct. I mean, does the 3 lines after the for loop make a new copy of model 2

                    And why when I use "model2.end()" the procedure take longer time than the procedure without "model2.end()". Any thoughts why?

                    Thanks
                    Updated on 2014-03-24T22:41:09Z at 2014-03-24T22:41:09Z by iron-man
                    • SystemAdmin
                      SystemAdmin
                      7944 Posts
                      ACCEPTED ANSWER

                      Re: Using different objective functions

                      ‏2013-01-30T22:48:01Z  in response to FANS_Nader_Al_Theeb
                      > FANS_Nader_Al_Theeb wrote:

                      > If I don't use "model2.end()", is this correct. I mean, does the 3 lines after the for loop make a new copy of model 2

                      Yes each time if you do use model2.end(). Without model2.end(), I think it only creates and extracts model2 on the first pass through the loop.
                      >
                      > And why when I use "model2.end()" the procedure take longer time than the procedure without "model2.end()". Any thoughts why?

                      If you end model2, then on the next pass it has to be re-extracted. If you do not end it, I suspect that the extraction step is skipped (as already done) after the first pass.

                      It seems to me that you do not really need model2 at all. Leave the extraction of model outside the loop, as it now is; inside the loop, modify and solve model.

                      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)
                      • SystemAdmin
                        SystemAdmin
                        7944 Posts
                        ACCEPTED ANSWER

                        Re: Using different objective functions

                        ‏2013-01-30T22:49:42Z  in response to SystemAdmin
                        Forgot to mention: when you modify the model, you may want to invoke the end() method on the elements you removed (if any) to free up space.
                      • FANS_Nader_Al_Theeb
                        FANS_Nader_Al_Theeb
                        46 Posts
                        ACCEPTED ANSWER

                        Re: Using different objective functions

                        ‏2013-01-31T02:08:46Z  in response to SystemAdmin
                        Thank you Paul

                        I'm confused little bit about your answer.

                        Let me explain more clearly. I have original model out side the iteration loop. Each iteration I want to take copy from this original model and modify it. But each iteration, the modifications are different

                        My question that if I modify the original model or a copied model inside the loop and solve it without using extract or end as you suggest, I think this will keep the old modifications and add the new modifications to them, right?
                        I'm sorry for these many question, but this part is the main part of my research.

                        Thanks
                        • SystemAdmin
                          SystemAdmin
                          7944 Posts
                          ACCEPTED ANSWER

                          Re: Using different objective functions

                          ‏2013-01-31T22:33:10Z  in response to FANS_Nader_Al_Theeb
                          Yes, the changes will be cumulative, unless at each stage you undo the previous changes and then make the new changes. Whether this is faster or slower than copying the model may depend on the nature of the changes and how much of the model is changing.

                          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)
                          • FANS_Nader_Al_Theeb
                            FANS_Nader_Al_Theeb
                            46 Posts
                            ACCEPTED ANSWER

                            Re: Using different objective functions

                            ‏2013-02-01T19:41:34Z  in response to SystemAdmin
                            Thank you Paul

                            I can't undo the changes because they are random

                            As a conclusion, do you suggest to use the following three lines inside the loop to create a new copy at each iteration

                            IloModel model3(env);
                            cplex.extract(model3);
                            model3.add(model);
                            


                            And do I need to add model3.end(); before the end of for loop
                            Thanks for this great help
                            Updated on 2014-03-24T22:41:06Z at 2014-03-24T22:41:06Z by iron-man
                            • SystemAdmin
                              SystemAdmin
                              7944 Posts
                              ACCEPTED ANSWER

                              Re: Using different objective functions

                              ‏2013-02-01T20:55:51Z  in response to FANS_Nader_Al_Theeb
                              > FANS_Nader_Al_Theeb wrote:
                              >
                              > As a conclusion, do you suggest to use the following three lines inside the loop to create a new copy at each iteration
                              >
                              >
                              > 
                              > IloModel model3(env);
                              > cplex.extract(model3);
                              > model3.add(model);
                              > 
                              >
                              


                              I think it might ruin slightly faster if you swap the second and third lines (add, then extract).
                              >
                              > And do I need to add model3.end(); before the end of for loop

                              I would.

                              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)
                              Updated on 2014-03-24T22:41:02Z at 2014-03-24T22:41:02Z by iron-man
                              • FANS_Nader_Al_Theeb
                                FANS_Nader_Al_Theeb
                                46 Posts
                                ACCEPTED ANSWER

                                Re: Using different objective functions

                                ‏2013-02-01T23:21:10Z  in response to SystemAdmin
                                Thanks Paul

                                I noticed something strange, and I would like to know if it is normal or not.

                                The command model2.end(); takes about 30 minutes to finish and solving model2 takes only 40 seconds

                                Is this possible that the end commands takes time about 45 times of solving time?

                                Thanks for your time
                                • SystemAdmin
                                  SystemAdmin
                                  7944 Posts
                                  ACCEPTED ANSWER

                                  Re: Using different objective functions

                                  ‏2013-02-02T16:16:59Z  in response to FANS_Nader_Al_Theeb
                                  That's odd but not impossible, especially given hot starts. If your modified model2 has enough in common with the preceding model2 (and there is now way to quantify or qualify "enough"), the solution to the preceding model2 (used to hot-start the modified version) may be optimal or at least within a small number of pivots of optimal for the modified model2. So a short solution time is not a shock. On the other hand, the time to end model2 depends on the size and complexity of model2 (which I gather is enormous).

                                  If you search the forum, you will see various questions and answers relating the time required to end a model. One thing you should definitely do is end the extracted IloCplex object before you end the IloModel instance. Otherwise, when you invoke IloModel.end(), I think it notifies the IloCplex instance each time a piece of the IloModel is zapped, and all those notifications add up to a lot of overhead (all wasted, since the IloCplex object has outlived its usefulness).

                                  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)
                            • SystemAdmin
                              SystemAdmin
                              7944 Posts
                              ACCEPTED ANSWER

                              Re: Using different objective functions

                              ‏2013-02-05T06:43:17Z  in response to FANS_Nader_Al_Theeb
                              In any case, you need to add modelX.end() or each new modelX that you create in the loop. Otherwise you will leak memory. To speed up modelX.end() try calling cplex.clearModel() before calling modelX.end().