Decision Optimization

Decision Optimization

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

 View Only
  • 1.  CPLEX generated Cuts at differnet nodes

    Posted Sat February 20, 2016 02:25 AM

    Originally posted by: prasenjit mandal


    I want to retrieve the cuts added by CPLEX during a MIP optimization For that I ran an API written in C. Now, I have few questions regarding this.

     

    1) When I ran the code, I got a number of output files (the node LP files) in the following format:

    nodelp<count>_<nodecount>.lp

     

    Now, could you please tell me what these <count> and <nodecount> variables hold? 

    Let's take a file nodelp0_0 : Is the first "0" signifies the total number of file generated and the second "0" the root node???

    Similarly, let's take another file nodelp1_0 : then what about this "1" and "0" here? (second file in root node!!!)

    If, the file  nodelp2_1 is also generated, then can we say that it is the third file in the 1st child node????

     

     

    2) Generally, when I was running the code from Visual Basic to get an integer solution, I can get the output within 1 second.

     

    But, when I am trying to retrieve the cplex generated cut, I am passing the lp file as an argument to the the program from the command prompt.

    Now, from the command prompt (cuts retrieval), it is taking huge amount of time. Couple of hundreds of  <nodelp<count>_<nodecount>.lp> type of files are generated.

    Why it is taking some much time while it is taking just 1 second when I am using the Visual Basic front end?

     

    From the Visual Basic log file (I am also attaching this log file: WPK6P4T7.log ), I observe mainly 4 types of cuts are added:

    Mixed integer rounding cuts applied:  13
    Zero-half cuts applied:  4
    Lift and project cuts applied:  6
    Gomory fractional cuts applied:  3

     

    How can I retrieve these 26 cuts (13+4+6+3=26) from the C API? Could you please give me some idea?

     

    3) I want to get the cuts which cplex are adding to the root nodes. But, for my problem, I have observed that the cplex didn't add any cut to nodelp0_0.lp file. But it has add some cut to other files?

    Why it is like this?

     

    I am herewith attaching the C API file (main.c) which I am using. Please find the file.

    Thanks in advance.

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: CPLEX generated Cuts at differnet nodes

    Posted Mon February 22, 2016 07:42 AM

    How about looking at your own source code? You can find this:

    int       nodecount;
    static    int count = 0;
    ...

    status = CPXgetcallbackinfo (env, cbdata, wherefrom,

                                 CPX_CALLBACK_INFO_NODE_COUNT, &nodecount);
    if ( status )  goto TERMINATE;
       
    if ( nodecount >= nodeswritten->startnode &&
         nodecount <= nodeswritten->endnode ) {
       char filename[128];

       /* Get pointer to LP subproblem, then write a SAV file. */

       status = CPXgetcallbacknodelp (env, cbdata, wherefrom, &nodelp);
       if ( status )  goto TERMINATE;

       sprintf (filename, "nodelp%d_%d", count, nodecount);
       strcat (filename, ".lp");
     
       status = CPXwriteprob (env, nodelp, filename, NULL);

    So 'nodecount' is the number of nodes processed and 'count' is the number of times the callback was invoked. Note that the callback may be invoked multiple times at the same node, especially at the root node.

    There are a number of reasons why your program is slower than a default solve. First of all, using control callbacks with implicitly switch to single-threaded solves, you have to explicitly set CPX_PARAM_THREADS to get a multi-threaded solve (I recommend not doing that since your current callback code is not thread-safe). The default solve instead used 4 threads. Moreover, dumping out the nodelp at each and every node will of course introduce a significant overhead.


    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: CPLEX generated Cuts at differnet nodes

    Posted Tue February 23, 2016 01:54 AM

    Originally posted by: prasenjit mandal


    Hi Daniel,

    Thank you very much for your reply.  I have further question to ask you.

     

    I executed the same code and generated a log file (FindRootNodeCuts.log). Please find the log file. Now, inspecting the log file, we can observe that C API has generated a total 7 cuts...

    Cover cuts applied:  1
    Mixed integer rounding cuts applied:  4
    Gomory fractional cuts applied:  2

     

    Also,  at first, the duality GAP quickly reduced to 8.26%, and then became steady at 8.26%, after 9000 callbacks, it further reduced to 2.72%; ultimately the IP solution was generated after 9069th callback. The total solution time was 121.45 sec.

     

     

    But, when I ran the same .lp file from the Visual C++ (Visual Studio) front end, I get  another log file ( WPK6P4T7.log ), I observe totally 26 cuts (13+4+6+3=26) are added:

    Mixed integer rounding cuts applied:  13
    Zero-half cuts applied:  4
    Lift and project cuts applied:  6
    Gomory fractional cuts applied:  3

     

    1)  Why there is a difference in numbers of cuts added to get the IP solution (only 7 from using C API, whereas 26 using Visual C++)? Then, how can I retrieve those additional cuts (26-7 =19 additional cuts)?


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: CPLEX generated Cuts at differnet nodes

    Posted Tue February 23, 2016 02:53 AM

    Like I said, your C code uses only a single thread while the solve in the interactive uses 4. This alone will result in two different search trees being explored (and the differences will almost certainly start already at the root node). So it is expected that you get different solution paths and cuts.

    Moreover, since the presence of control callbacks switches of dynamic search, the C code uses traditional B&C. This also contributes to the differences you see.

    So the answer is: the number of cuts added exists because you are doing different things. Try 'set thread 1' and 'set mip strat search 1' in the interactive. That should get you closer to what the C code does.

    Alternatively, you can make the callback thread-safe and use 4 threads (CPX_PARAM_THREADS) in the C code. There is no way to get dynamic search with a control callback in the C code.


    #CPLEXOptimizers
    #DecisionOptimization