Originally posted by: EdKlotz
First of all, to save any other readers time, the difference between 1.cpp and 2.cpp (which actually use the C API) is that 1.cpp is basically the mipex2.c example that reads in a model in an LP, MPS or SAV file and solves it. 2.cpp does the same thing, but has a solve callback that writes out node LPs; it is essentially the wrtnode.c program that can be found here:
https://www.ibm.com/support/pages/sample-c-program-retrieve-cuts-added-cplex-during-mip-optimization
Regarding
> I was expecting that nodelp_0.lp would be the file containing all cuts that helped CPLEX raise the lower bound upto 5466.
Be careful about your definition of the root node LP. The root node LP includes the initial LP relaxation solve, which involves no cuts at all (other than any simple cuts obtained during presolve that are bound changes that result in removal of variables). The nodelp_0.lp in your program is this initial LP relaxation solve, and it never involves cuts. Furthermore, for this model, it has a sub optimal objective, as can be seen by running interactive CPLEX on the problemIP file. Here we see that the root node consists not only of the initial LP relaxation solve, but subsequently LP relaxation solves associated with the root node cut loop:
Nodes Cuts/
Node Left Objective IInf Best Integer Best Bound ItCnt Gap
* 0+ 0 6152.0000 0.0000 100.00%
0 0 3752.0000 9 6152.0000 3752.0000 18 39.01% // this is the initial root node LP relaxation value
* 0+ 0 6099.0000 3752.0000 38.48%
0 0 4812.2656 7 6099.0000 Cuts: 52 51 21.10%
* 0+ 0 5482.0000 4812.2656 12.22%
0 0 5056.2801 8 5482.0000 Cuts: 62 79 7.77%
0 0 5072.5000 4 5482.0000 Cuts: 26 83 7.47%
0 0 5080.2254 8 5482.0000 MIRcuts: 3 92 7.33%
0 0 5110.5010 9 5482.0000 Cuts: 7 109 6.78%
0 0 5121.6906 8 5482.0000 Cuts: 12 121 6.57%
* 0+ 0 5466.0000 5121.6906 6.30%
0 0 cutoff 5466.0000 5466.0000 121 0.00%
So yes, this model solves at the root node, but only after several cut passes, so you want to look at the final node LP exported by your 2.cpp program, not the first one, if you want to examine the cuts CPLEX generated. However, the final node LP still may not match the optimal objective value. The node log above indicates that the penultimate node LP has an objective of 5121.6906, but that the final node LP has no objective because the last node LP solve was determined to exceed the cutoff value and terminated early. Still, the final exported node LP will have all the cuts CPLEX generated.
Also, while I don't think it really matters for your particular question here, note that by adding a solve callback you disable dynamic search and restrict the optimization to a single thread, which could lead to other differences in the optimization for your 2.cpp program relative to the 1.cpp program which will run dynamic search and use multiple threads. So that can lead to other differences in the optimization performed by your 2 programs, e.g. the 1.cpp program may use heuristics more effectively and, if the solve goes part the root node, benefit more from dynamic search.
#CPLEXOptimizers#DecisionOptimization