1 | // Copyright (C) 2007, International Business Machines |
---|
2 | // Corporation and others. All Rights Reserved. |
---|
3 | #if defined(_MSC_VER) |
---|
4 | // Turn off compiler warning about long names |
---|
5 | # pragma warning(disable:4786) |
---|
6 | #endif |
---|
7 | |
---|
8 | #include <cassert> |
---|
9 | #include <iomanip> |
---|
10 | |
---|
11 | #include "CbcConfig.h" |
---|
12 | #include "CbcModel.hpp" |
---|
13 | #include "OsiClpSolverInterface.hpp" |
---|
14 | #include "CbcBranchDynamic.hpp" |
---|
15 | |
---|
16 | #include "CoinTime.hpp" |
---|
17 | |
---|
18 | //############################################################################# |
---|
19 | |
---|
20 | |
---|
21 | /************************************************************************ |
---|
22 | |
---|
23 | This main program shows how to take advantage of the standalone cbc in your program. |
---|
24 | It should perform very nearly the same as cbc |
---|
25 | First it reads in an integer model from an mps file and saves and strips off integer information. |
---|
26 | Then it initializes the integer model with cbc defaults |
---|
27 | Then it puts back integers - here you could do anything and also set parameters |
---|
28 | Then it calls CbcMain1 passing all parameters apart from first |
---|
29 | Finally it prints solution |
---|
30 | |
---|
31 | ************************************************************************/ |
---|
32 | |
---|
33 | int main (int argc, const char *argv[]) |
---|
34 | { |
---|
35 | |
---|
36 | OsiClpSolverInterface solver1; |
---|
37 | //#define USE_OSI_NAMES |
---|
38 | #ifdef USE_OSI_NAMES |
---|
39 | // Say we are keeping names (a bit slower this way) |
---|
40 | solver1.setIntParam(OsiNameDiscipline,1); |
---|
41 | #endif |
---|
42 | // Read in model using argv[1] |
---|
43 | // and assert that it is a clean model |
---|
44 | std::string mpsFileName; |
---|
45 | #if defined(COIN_HAS_SAMPLE) && defined(SAMPLEDIR) |
---|
46 | mpsFileName = SAMPLEDIR "/p0033.mps"; |
---|
47 | #else |
---|
48 | if (argc < 2) { |
---|
49 | fprintf(stderr, "Do not know where to find sample MPS files.\n"); |
---|
50 | exit(1); |
---|
51 | } |
---|
52 | #endif |
---|
53 | if (argc>=2) mpsFileName = argv[1]; |
---|
54 | int numMpsReadErrors = solver1.readMps(mpsFileName.c_str(),""); |
---|
55 | assert(numMpsReadErrors==0); |
---|
56 | |
---|
57 | // Strip off integer information and save |
---|
58 | int numberColumns = solver1.getNumCols(); |
---|
59 | char * integer = new char[numberColumns]; |
---|
60 | int i; |
---|
61 | for (i=0;i<numberColumns;i++) { |
---|
62 | if (solver1.isInteger(i)) { |
---|
63 | integer[i]=1; |
---|
64 | solver1.setContinuous(i); |
---|
65 | } else { |
---|
66 | integer[i]=0; |
---|
67 | } |
---|
68 | } |
---|
69 | // Pass to Cbc initialize defaults |
---|
70 | CbcModel model(solver1); |
---|
71 | CbcMain0(model); |
---|
72 | |
---|
73 | // Solve just to show there are no integers |
---|
74 | model.branchAndBound(); |
---|
75 | // Set cutoff etc back in model and solver |
---|
76 | model.resetModel(); |
---|
77 | // Solver was cloned so get it |
---|
78 | OsiSolverInterface * solver = model.solver(); |
---|
79 | // Put back integers. Here the user could do anything really |
---|
80 | #define ADD_DIRECTLY |
---|
81 | #ifndef ADD_DIRECTLY |
---|
82 | for (i=0;i<numberColumns;i++) { |
---|
83 | if (integer[i]) |
---|
84 | solver->setInteger(i); |
---|
85 | } |
---|
86 | #else |
---|
87 | CbcObject ** objects = new CbcObject * [ numberColumns]; |
---|
88 | int n=0; |
---|
89 | for (i=0;i<numberColumns;i++) { |
---|
90 | if (integer[i]) { |
---|
91 | CbcSimpleIntegerDynamicPseudoCost * newObject = |
---|
92 | new CbcSimpleIntegerDynamicPseudoCost(&model,i); |
---|
93 | objects[n++]=newObject; |
---|
94 | } |
---|
95 | } |
---|
96 | model.addObjects(n,objects); |
---|
97 | for (i=0;i<n;i++) |
---|
98 | delete objects[i]; |
---|
99 | delete [] objects; |
---|
100 | #endif |
---|
101 | delete [] integer; |
---|
102 | /* Now go into code for standalone solver |
---|
103 | Could copy arguments and add -quit at end to be safe |
---|
104 | but this will do |
---|
105 | */ |
---|
106 | if (argc>2) { |
---|
107 | CbcMain1(argc-1,argv+1,model); |
---|
108 | } else { |
---|
109 | const char * argv2[]={"driver3","-solve","-quit"}; |
---|
110 | CbcMain1(3,argv2,model); |
---|
111 | } |
---|
112 | |
---|
113 | // Print solution if finished (could get from model.bestSolution() as well |
---|
114 | |
---|
115 | if (solver->getObjValue()*solver->getObjSense()<1.0e50) { |
---|
116 | |
---|
117 | const double * solution = solver->getColSolution(); |
---|
118 | |
---|
119 | int iColumn; |
---|
120 | std::cout<<std::setiosflags(std::ios::fixed|std::ios::showpoint)<<std::setw(14); |
---|
121 | |
---|
122 | std::cout<<"--------------------------------------"<<std::endl; |
---|
123 | #ifdef USE_OSI_NAMES |
---|
124 | |
---|
125 | for (iColumn=0;iColumn<numberColumns;iColumn++) { |
---|
126 | double value=solution[iColumn]; |
---|
127 | if (fabs(value)>1.0e-7&&solver->isInteger(iColumn)) |
---|
128 | std::cout<<std::setw(6)<<iColumn<<" "<<std::setw(8)<<setiosflags(std::ios::left)<<solver->getColName(iColumn) |
---|
129 | <<resetiosflags(std::ios::adjustfield)<<std::setw(14)<<" "<<value<<std::endl; |
---|
130 | } |
---|
131 | #else |
---|
132 | // names may not be in current solver - use original |
---|
133 | |
---|
134 | for (iColumn=0;iColumn<numberColumns;iColumn++) { |
---|
135 | double value=solution[iColumn]; |
---|
136 | if (fabs(value)>1.0e-7&&solver->isInteger(iColumn)) |
---|
137 | std::cout<<std::setw(6)<<iColumn<<" "<<std::setw(8)<<setiosflags(std::ios::left)<<solver1.getModelPtr()->columnName(iColumn) |
---|
138 | <<resetiosflags(std::ios::adjustfield)<<std::setw(14)<<" "<<value<<std::endl; |
---|
139 | } |
---|
140 | #endif |
---|
141 | std::cout<<"--------------------------------------"<<std::endl; |
---|
142 | |
---|
143 | std::cout<<std::resetiosflags(std::ios::fixed|std::ios::showpoint|std::ios::scientific); |
---|
144 | } |
---|
145 | return 0; |
---|
146 | } |
---|