1 //-----------------------------------------------------
2 // Simple example usage of the cut generation library.
3 //
4 // This sample program iteratively tightens a
5 // given formulation by adding conic cuts, then calls
6 // branch-and-bound to solve the tightened
7 // formulation.
8 //
9 // usage:
10 //   solve_with_mir mpsFileName objectiveSense
11 // where:
12 //   mpsFileName: Name of an mps file (without the
13 //                file extension)
14 // example:
15 //   solve_with_mir ../../Data/Sample/p0033
16 //-----------------------------------------------------
17 
18 // STDLIB headers
19 #include <cassert>
20 #include <iostream>
21 #include <string>
22 #include <cassert>
23 // CoinUtils headers
24 #include "CoinError.hpp"
25 #include "CoinWarmStartBasis.hpp"
26 // OSI headers
27 #include "OsiCuts.hpp"
28 #include "OsiClpSolverInterface.hpp"
29 // OSICONIC header
30 #include <OsiConicSolverInterface.hpp>
31 #include <OsiConicCuts.hpp>
32 // COLA headers
33 #include <ColaModel.hpp>
34 // CGL headers
35 // #include "CglKnapsackCover.hpp"
36 // #include "CglSimpleRounding.hpp"
37 // #include "CglGMI.hpp"
38 // #include "CglGomory.hpp"
39 // #include "CglMixedIntegerRounding.hpp"
40 // #include "CglMixedIntegerRounding2.hpp"
41 // Conic CGL headers
42 #include "CglConicMIR.hpp"
43 
44 using std::cerr;
45 using std::cout;
46 using std::endl;
47 using std::string;
48 
main(int argc,const char * argv[])49 int main(int argc, const char *argv[])
50 {
51   // If no parms specified then use these
52   string mpsFileName = argv[1];
53   try {
54     // Instantiate a specific solver interface
55     OsiConicSolverInterface * si = new ColaModel();
56     // Read file describing problem
57     si->readMps(mpsFileName.c_str(),"mps");
58     // Solve continuous problem
59     si->initialSolve();
60     // Save the orig lp/soco relaxation value for
61     // comparisons later
62     double origLpObj = si->getObjValue();
63     // Instantiate cut generators
64     CglConicMIR cg;
65     //---------------------------------------------------
66     // Keep applying cuts until
67     //   1. no more cuts are generated
68     // or
69     //   2. the objective function value doesn't change
70     //---------------------------------------------------
71     bool equalObj;
72     CoinRelFltEq eq(0.0001);
73     double obj;
74     do {
75       // Get current solution value
76       obj = si->getObjValue();
77       // Generate and apply cuts
78       cg.generateAndAddCuts(*si);
79       // si->writeMps("after_cut");
80       si->resolve();
81       //si->initialSolve();
82       cout <<endl;
83       // -----------------------------------------------
84       // Set Boolean flag to true if new objective is
85       // almost equal to prior value.
86       //
87       // The test is:
88       // abs(oldObj-newObj) <= 0.0001*(CoinMax(abs(oldObj),abs(newObj))+1.);
89       // see CoinRelFloatEqual.h
90       // -----------------------------------------------
91       equalObj = eq(si->getObjValue(), obj);
92       break;
93     } while (!equalObj);
94     double const * sol = si->getColSolution();
95     // Print total number of cuts applied,
96     // and total improvement in the lp objective value
97     cout <<endl <<endl;
98     cout << "----------------------------------------------------------"
99          <<endl;
100     cout << "Cut generation phase completed:" <<endl;
101     cout << "   " << cg.getNumCutsAdded() << " many cuts added." << endl;
102     cout << "   changing the lp objective value from " << origLpObj
103          << " to " << si->getObjValue() <<endl;
104     cout << "----------------------------------------------------------"
105          <<endl;
106     cout <<endl <<endl;
107   }
108   catch (CoinError e) {
109     cout << e.className() << "::" << e.methodName() << " - " << e.message() << endl;
110   }
111   return 0;
112 }
113