1 // $Id$
2 // Copyright (C) 2004, International Business Machines
3 // Corporation and others. All Rights Reserved.
4 // This code is licensed under the terms of the Eclipse Public License (EPL).
5
6 #include "CbcConfig.h"
7
8 #include "CoinPragma.hpp"
9
10 #include <cassert>
11 #include <iomanip>
12
13 // For Branch and bound
14 #include "OsiSolverInterface.hpp"
15 #include "CbcModel.hpp"
16 #include "CbcBranchUser.hpp"
17 #include "CbcBranchActual.hpp"
18 #include "CbcCompareUser.hpp"
19 #include "CoinTime.hpp"
20 #include "OsiClpSolverInterface.hpp"
21
22 //#############################################################################
23
24 /************************************************************************
25
26 This main program reads in an SOS model (rgn) from an mps file.
27
28 It then solves it three ways :-
29
30 a) As normal
31 b) SOS 1
32 c) SOS 2 (so answer will be different)
33
34 ************************************************************************/
35
main(int argc,const char * argv[])36 int main(int argc, const char *argv[])
37 {
38
39 // Define your favorite OsiSolver
40
41 OsiClpSolverInterface solver1;
42 //solver1.messageHandler()->setLogLevel(0);
43 CbcModel model(solver1);
44 model.solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
45
46 // Read in rgn.mps
47 std::string mpsFileName;
48 #if defined(MIPLIB3DIR)
49 mpsFileName = MIPLIB3DIR "/rgn";
50 #else
51 if (argc < 2) {
52 fprintf(stderr, "Do not know where to find miplib3 MPS files.\n");
53 exit(1);
54 }
55 #endif
56 if (argc >= 2)
57 mpsFileName = argv[1];
58 int numMpsReadErrors = model.solver()->readMps(mpsFileName.c_str(), "");
59 if (numMpsReadErrors != 0) {
60 printf("%d errors reading MPS file\n", numMpsReadErrors);
61 return numMpsReadErrors;
62 }
63
64 // Definition of node choice
65 CbcCompareUser compare;
66 compare.setWeight(0.0);
67 model.setNodeComparison(compare);
68 // Reduce output
69 model.messageHandler()->setLogLevel(1);
70 // Get branching messages
71 model.messageHandler()->setLogLevel(3);
72
73 // Do initial solve to continuous
74 model.initialSolve();
75
76 // Save model
77 CbcModel model2 = model;
78 int numberColumns = model.getNumCols();
79 int numberIntegers = 0;
80 int *integerVariable = new int[numberColumns];
81 int i;
82 for (i = 0; i < numberColumns; i++) {
83 if (model.isInteger(i)) {
84 integerVariable[numberIntegers++] = i;
85 }
86 }
87
88 if (numberColumns != 180 || numberIntegers != 100) {
89 printf("Incorrect model for example\n");
90 exit(1);
91 }
92
93 double time1 = CoinCpuTime();
94
95 model.branchAndBound();
96
97 std::cout << "rgn.mps"
98 << " took " << CoinCpuTime() - time1 << " seconds, "
99 << model.getNodeCount() << " nodes with objective "
100 << model.getObjValue()
101 << (!model.status() ? " Finished" : " Not finished")
102 << std::endl;
103
104 const double *solution = model.solver()->getColSolution();
105
106 std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14);
107
108 std::cout << "--------------------------------------" << std::endl;
109 for (i = 0; i < numberIntegers; i++) {
110 int iColumn = integerVariable[i];
111 double value = solution[iColumn];
112 if (fabs(value) > 1.0e-7)
113 std::cout << std::setw(6) << iColumn << " " << value << std::endl;
114 }
115 std::cout << "--------------------------------------" << std::endl;
116
117 std::cout << std::resetiosflags(std::ios::fixed | std::ios::showpoint | std::ios::scientific);
118
119 // Restore model
120 model = model2;
121
122 // Convert slacks to variables
123 CoinBigIndex start[5] = { 0, 1, 2, 3, 4 };
124 int row[4] = { 0, 1, 2, 3 };
125 double element[4] = { 1.0, 1.0, 1.0, 1.0 };
126 double up[4] = { 1.0, 1.0, 1.0, 1.0 };
127 model.solver()->addCols(4, start, row, element, NULL, up, NULL);
128 // Now use SOS1
129 int numberSets = 4;
130 int which[104];
131 double weights[104];
132 int starts[5];
133 // load
134 int n = 0;
135 starts[0] = 0;
136 for (int iSet = 0; iSet < 4; iSet++) {
137 for (int i = 0; i < 25; i++) {
138 weights[n] = i + 1.0;
139 which[n] = iSet * 25 + i;
140 n++;
141 }
142 // slack - make sure first branch is on slack
143 weights[n] = 1000.0;
144 which[n] = 180 + iSet;
145 n++;
146 starts[iSet + 1] = n;
147 }
148 for (i = 0; i < numberIntegers; i++) {
149 int iColumn = integerVariable[i];
150 // Stop being integer
151 model.solver()->setContinuous(iColumn);
152 }
153 // save model in this state
154 CbcModel modelSOS = model;
155 CbcObject **objects = new CbcObject *[numberSets];
156 for (i = 0; i < numberSets; i++) {
157 objects[i] = new CbcSOS(&model, starts[i + 1] - starts[i], which + starts[i],
158 weights, i);
159 }
160 model.addObjects(numberSets, objects);
161 for (i = 0; i < numberSets; i++)
162 delete objects[i];
163 delete[] objects;
164
165 time1 = CoinCpuTime();
166
167 model.branchAndBound();
168
169 std::cout << "rgn.mps"
170 << " took " << CoinCpuTime() - time1 << " seconds, "
171 << model.getNodeCount() << " nodes with objective "
172 << model.getObjValue()
173 << (!model.status() ? " Finished" : " Not finished")
174 << std::endl;
175
176 solution = model.solver()->getColSolution();
177
178 std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14);
179
180 std::cout << "--------------------------------------" << std::endl;
181 for (i = 0; i < numberIntegers; i++) {
182 int iColumn = integerVariable[i];
183 double value = solution[iColumn];
184 if (fabs(value) > 1.0e-7)
185 std::cout << std::setw(6) << iColumn << " " << value << std::endl;
186 }
187 std::cout << "--------------------------------------" << std::endl;
188
189 std::cout << std::resetiosflags(std::ios::fixed | std::ios::showpoint | std::ios::scientific);
190
191 // Restore SOS model
192 model = modelSOS;
193
194 // Now use SOS2
195 objects = new CbcObject *[numberSets];
196 for (i = 0; i < numberSets; i++) {
197 objects[i] = new CbcSOS(&model, starts[i + 1] - starts[i], which + starts[i],
198 weights, i, 2);
199 }
200 model.addObjects(numberSets, objects);
201 for (i = 0; i < numberSets; i++)
202 delete objects[i];
203 delete[] objects;
204
205 time1 = CoinCpuTime();
206
207 model.branchAndBound();
208
209 std::cout << "rgn.mps"
210 << " took " << CoinCpuTime() - time1 << " seconds, "
211 << model.getNodeCount() << " nodes with objective "
212 << model.getObjValue()
213 << (!model.status() ? " Finished" : " Not finished")
214 << std::endl;
215
216 solution = model.solver()->getColSolution();
217
218 std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14);
219
220 std::cout << "--------------------------------------" << std::endl;
221
222 for (i = 0; i < numberIntegers; i++) {
223 int iColumn = integerVariable[i];
224 double value = solution[iColumn];
225 if (fabs(value) > 1.0e-7)
226 std::cout << std::setw(6) << iColumn << " " << value
227 << std::endl;
228 }
229 std::cout << "--------------------------------------" << std::endl;
230
231 std::cout << std::resetiosflags(std::ios::fixed | std::ios::showpoint | std::ios::scientific);
232
233 delete[] integerVariable;
234 return 0;
235 }
236