Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  Extending Callback Functionality

    Posted 12/27/13 02:33 PM

    Originally posted by: CDYD_Victor_Miller


    In FAQ 186 there is the following the paragraph below.  Can someone point me to more detail as to how to do that, such as a worked example?

     

    "Tactics for Extending Callback Functionality

    Given these conventions, users may find that they can perform additional tasks with callbacks by having the callback stop the optimization, returning control to the user's program after the optimization. Then, the user can use any CPLEX API function to obtain information not available through the callback APIs. After obtaining the required information, the user resumes the optimization from where it left off. The overhead associated with restarting the optimization in this way is minimal, even if this operation is repeated many times."


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Extending Callback Functionality

    Posted 01/06/14 05:45 AM

    In which API do you want to do that? Callable library, Concert, Python, ...?


    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: Extending Callback Functionality

    Posted 01/07/14 12:04 PM

    Originally posted by: CDYD_Victor_Miller


    I'm using C++ concert technology.


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: Extending Callback Functionality

    Posted 01/17/14 02:04 PM

    If you call IloCplex::CallbackI::abort() from a callback's main() function then this will stop the optimization. After IloCplex::solve() returned and you have performed all the desired queries then you can call IloCplex::solve() again to continue the optimization at the point at which the callback stopped it.


    #CPLEXOptimizers
    #DecisionOptimization


  • 5.  Re: Extending Callback Functionality

    Posted 04/10/14 04:18 PM

    Originally posted by: CDYD_Victor_Miller


    Daniel, Thanks for the answer.  I want to do the following: every time I find an incumbent solution I want to test it for a desired property.  If that property is true, I want to stop the optimization and have the latest incument be the solution.  If I just use abort() at that point (from an Incumbent callback) this doesn't work.  This should be simple to do, but I can't find the answer in the docuementation.

     

    VIctor


    #CPLEXOptimizers
    #DecisionOptimization


  • 6.  Re: Extending Callback Functionality

    Posted 04/11/14 02:03 AM

    That is expected since calling abort() from the incumbent callback stops the optimization before the incumbent is accepted. So that is not good enough to implement what you have in mind.

    I see 3 ways to implement what you want. None of them is simple but they are still all easy:

    1. Instead of using callback set parameter IloCplex::IntSolLim to 1. Then call IloCplex::solve() in a loop. The solve() call will return whenever CPLEX finds a new solution. You can then check all new solutions found for the property. If none of the new solutions have the property then call solve() again. CPLEX will continue optimization from where it stopped before. Note that in multi-threaded solves CPLEX may find more than a single solution for a single call to solve(). This can happen if multiple threads find solutions simultaneously.
    2. Use only an incumbent callback. When you find that the incumbent in the callback has the desired property then store the x vector of the incumbent in some global data structure (or a data structure that is shared between your main program and the callback) and abort() the callback. After solve() returns you then need to check this global data structure: if it contains an x vector then you found an incumbent with the desired property, otherwise CPLEX did not encounter such an incumbent before proving optimality.
    3. Use 3 callbacks: incumbent, node, and branch callback. All callbacks share a flag that is initially set to false. If you find an incumbent of the desired property in the incumbent callback then you set the flag to true (and do nothing else). In the node and branch callback you check the flag. If the flag is true then you abort() the respective callback, otherwise you do nothing.

    #CPLEXOptimizers
    #DecisionOptimization


  • 7.  Re: Extending Callback Functionality

    Posted 04/11/14 11:20 AM

    Originally posted by: CDYD_Victor_Miller


    Daniel, Thanks for the detailed answer.  I like choice 1.  So here are two questions about it:

    1) Since you point out that there might be more than one incumbent found because of multiple threads, how do I find all of the "new" incumbents?

     

    2) In the main program do I check the solution status to find out why solve terminated?  Where can I find the list of solution status codes.  I assume that there's one that says that solve was terminated because of IntSolLim being set, and another which says that it terminated because cplex finished searching the solution tree.

     

    Victor


    #CPLEXOptimizers
    #DecisionOptimization


  • 8.  Re: Extending Callback Functionality

    Posted 04/14/14 02:56 AM

    To get all the solutions that CPLEX found you look at the solution pool (in rare cases you may have to extend the solution pool capacity to make sure no solutions are discarded).

    To figure out why CPLEX stopped use IloCplex::getCplexStatus(). This returns a value from IloCplex::CplexStatus. If CPLEX stopped due to a solution limit then getCplexStatus() will return IloCplex::SolLim, otherwise it should return IloCplex::Optimal or IloCplex::OptimalTol (provided you did not set other limits).


    #CPLEXOptimizers
    #DecisionOptimization


  • 9.  Re: Extending Callback Functionality

    Posted 07/09/14 12:44 PM

    Originally posted by: CDYD_Victor_Miller


    Daniel, Thanks for the answer.  I have a few more questions:

    1) If I choose to stop cplex because of setting the integer solution limit to 1, do I need to delete that solution (or more than one if running multiple threads) before restarting solve() to get another integer solution -- i.e. is the integer solution that I just found counted in the solution limit when I restart?  If so, should I then bump up the integer solution limit the next time?  More specifically, should I set it to 1 more than the number of solutions in the pool?

    2) If I also want to have a criterion where I'll stop if a number of branch and bound nodes is exceeded or I get another integer solution, should I first check the status where the number of solutions is exceeded, and *then* check NodeLimInfeas (can NodeLimFeas ever be the case if I use these two limits?)?

     

    Victor


    #CPLEXOptimizers
    #DecisionOptimization


  • 10.  Re: Extending Callback Functionality

    Posted 08/04/14 12:12 PM

    1) If I choose to stop cplex because of setting the integer solution limit to 1, do I need to delete that solution (or more than one if running multiple threads) before restarting solve() to get another integer solution -- i.e. is the integer solution that I just found counted in the solution limit when I restart?  If so, should I then bump up the integer solution limit the next time?  More specifically, should I set it to 1 more than the number of solutions in the pool?

    You can just loop with the solution limit set to 1. Solutions that already exist when solve() is called do not count towards the solution limit.

    2) If I also want to have a criterion where I'll stop if a number of branch and bound nodes is exceeded or I get another integer solution, should I first check the status where the number of solutions is exceeded, and *then* check NodeLimInfeas (can NodeLimFeas ever be the case if I use these two limits?)?

    The order in which you check the status should not matter since you can get only one of them. Hence you probably just want to 'switch' on them. I think you should get NodeLimFeas if there is at least one feasible solution (from this iteration or a previous one) and NodeLimInfeas only if there was no feasible solution at all before you hit the node limit.


    #CPLEXOptimizers
    #DecisionOptimization