1 | // $Id: OsiCbcSolverInterfaceTest.cpp 1854 2013-01-28 00:02:55Z forrest $ |
---|
2 | // Copyright (C) 2005, 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 "CoinPragma.hpp" |
---|
7 | |
---|
8 | //#include <cassert> |
---|
9 | //#include <cstdlib> |
---|
10 | //#include <cstdio> |
---|
11 | //#include <iostream> |
---|
12 | |
---|
13 | #include "OsiCbcSolverInterface.hpp" |
---|
14 | #include "OsiCuts.hpp" |
---|
15 | #include "OsiRowCut.hpp" |
---|
16 | #include "OsiColCut.hpp" |
---|
17 | #include "OsiUnitTests.hpp" |
---|
18 | #include "CoinMessage.hpp" |
---|
19 | #include "CoinModel.hpp" |
---|
20 | |
---|
21 | //############################################################################# |
---|
22 | |
---|
23 | namespace { |
---|
24 | CoinPackedMatrix &BuildExmip1Mtx () |
---|
25 | /* |
---|
26 | Simple function to build a packed matrix for the exmip1 example used in |
---|
27 | tests. The function exists solely to hide the intermediate variables. |
---|
28 | Probably could be written as an initialised declaration. |
---|
29 | See COIN/Mps/Sample/exmip1.mps for a human-readable presentation. |
---|
30 | |
---|
31 | Ordered triples seem easiest. They're listed in row-major order. |
---|
32 | */ |
---|
33 | |
---|
34 | { int rowndxs[] = { 0, 0, 0, 0, 0, |
---|
35 | 1, 1, |
---|
36 | 2, 2, |
---|
37 | 3, 3, |
---|
38 | 4, 4, 4 } ; |
---|
39 | int colndxs[] = { 0, 1, 3, 4, 7, |
---|
40 | 1, 2, |
---|
41 | 2, 5, |
---|
42 | 3, 6, |
---|
43 | 0, 4, 7 } ; |
---|
44 | double coeffs[] = { 3.0, 1.0, -2.0, -1.0, -1.0, |
---|
45 | 2.0, 1.1, |
---|
46 | 1.0, 1.0, |
---|
47 | 2.8, -1.2, |
---|
48 | 5.6, 1.0, 1.9 } ; |
---|
49 | |
---|
50 | static CoinPackedMatrix exmip1mtx = |
---|
51 | CoinPackedMatrix(true,&rowndxs[0],&colndxs[0],&coeffs[0],14) ; |
---|
52 | |
---|
53 | return (exmip1mtx) ; } |
---|
54 | } |
---|
55 | |
---|
56 | //-------------------------------------------------------------------------- |
---|
57 | // test solution methods. |
---|
58 | void OsiCbcSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir) |
---|
59 | { |
---|
60 | { |
---|
61 | CoinRelFltEq eq; |
---|
62 | OsiCbcSolverInterface m; |
---|
63 | std::string fn = mpsDir+"exmip1"; |
---|
64 | m.readMps(fn.c_str(),"mps"); |
---|
65 | |
---|
66 | { |
---|
67 | OsiCbcSolverInterface im; |
---|
68 | OSIUNITTEST_ASSERT_ERROR(im.getNumCols() == 0, {}, "cbc", "default constructor"); |
---|
69 | OSIUNITTEST_ASSERT_ERROR(im.getModelPtr() != NULL, {}, "cbc", "default constructor"); |
---|
70 | } |
---|
71 | |
---|
72 | // Test copy constructor and assignment operator |
---|
73 | { |
---|
74 | OsiCbcSolverInterface lhs; |
---|
75 | { |
---|
76 | OsiCbcSolverInterface im(m); |
---|
77 | |
---|
78 | OsiCbcSolverInterface imC1(im); |
---|
79 | OSIUNITTEST_ASSERT_ERROR(imC1.getModelPtr() != im.getModelPtr(), {}, "cbc", "copy constructor"); |
---|
80 | OSIUNITTEST_ASSERT_ERROR(imC1.getNumCols() == im.getNumCols(), {}, "cbc", "copy constructor"); |
---|
81 | OSIUNITTEST_ASSERT_ERROR(imC1.getNumRows() == im.getNumRows(), {}, "cbc", "copy constructor"); |
---|
82 | |
---|
83 | OsiCbcSolverInterface imC2(im); |
---|
84 | OSIUNITTEST_ASSERT_ERROR(imC2.getModelPtr() != im.getModelPtr(), {}, "cbc", "copy constructor"); |
---|
85 | OSIUNITTEST_ASSERT_ERROR(imC2.getNumCols() == im.getNumCols(), {}, "cbc", "copy constructor"); |
---|
86 | OSIUNITTEST_ASSERT_ERROR(imC2.getNumRows() == im.getNumRows(), {}, "cbc", "copy constructor"); |
---|
87 | |
---|
88 | OSIUNITTEST_ASSERT_ERROR(imC1.getModelPtr() != imC2.getModelPtr(), {}, "cbc", "copy constructor"); |
---|
89 | |
---|
90 | lhs = imC2; |
---|
91 | } |
---|
92 | |
---|
93 | // Test that lhs has correct values even though rhs has gone out of scope |
---|
94 | OSIUNITTEST_ASSERT_ERROR(lhs.getModelPtr() != m.getModelPtr(), {}, "cbc", "assignment operator"); |
---|
95 | OSIUNITTEST_ASSERT_ERROR(lhs.getNumCols() == m.getNumCols(), {}, "cbc", "copy constructor"); |
---|
96 | OSIUNITTEST_ASSERT_ERROR(lhs.getNumRows() == m.getNumRows(), {}, "cbc", "copy constructor"); |
---|
97 | } |
---|
98 | |
---|
99 | // Test clone |
---|
100 | { |
---|
101 | OsiCbcSolverInterface cbcSi(m); |
---|
102 | OsiSolverInterface * siPtr = &cbcSi; |
---|
103 | OsiSolverInterface * siClone = siPtr->clone(); |
---|
104 | OsiCbcSolverInterface * cbcClone = dynamic_cast<OsiCbcSolverInterface*>(siClone); |
---|
105 | |
---|
106 | OSIUNITTEST_ASSERT_ERROR(cbcClone != NULL, {}, "cbc", "clone"); |
---|
107 | OSIUNITTEST_ASSERT_ERROR(cbcClone->getModelPtr() != cbcSi.getModelPtr(), {}, "cbc", "clone"); |
---|
108 | OSIUNITTEST_ASSERT_ERROR(cbcClone->getNumRows() == cbcSi.getNumRows(), {}, "cbc", "clone"); |
---|
109 | OSIUNITTEST_ASSERT_ERROR(cbcClone->getNumCols() == m.getNumCols(), {}, "cbc", "clone"); |
---|
110 | |
---|
111 | delete siClone; |
---|
112 | } |
---|
113 | |
---|
114 | // test infinity |
---|
115 | { |
---|
116 | OsiCbcSolverInterface si; |
---|
117 | OSIUNITTEST_ASSERT_ERROR(si.getInfinity() == OsiCbcInfinity, {}, "cbc", "infinity"); |
---|
118 | } |
---|
119 | |
---|
120 | // Test some catches |
---|
121 | if (!OsiCbcHasNDEBUG()) |
---|
122 | { |
---|
123 | OsiCbcSolverInterface solver; |
---|
124 | try { |
---|
125 | solver.setObjCoeff(0,0.0); |
---|
126 | OSIUNITTEST_ADD_OUTCOME("cbc", "setObjCoeff on empty model", "should throw exception", OsiUnitTest::TestOutcome::ERROR, false); |
---|
127 | } |
---|
128 | catch (CoinError e) { |
---|
129 | if (OsiUnitTest::verbosity >= 1) |
---|
130 | std::cout<<"Correct throw from setObjCoeff on empty model"<<std::endl; |
---|
131 | } |
---|
132 | |
---|
133 | std::string fn = mpsDir+"exmip1"; |
---|
134 | solver.readMps(fn.c_str(),"mps"); |
---|
135 | OSIUNITTEST_CATCH_ERROR(solver.setObjCoeff(0,0.0), {}, "cbc", "setObjCoeff on nonempty model"); |
---|
136 | |
---|
137 | try { |
---|
138 | int index[]={0,20}; |
---|
139 | double value[]={0.0,0.0,0.0,0.0}; |
---|
140 | solver.setColSetBounds(index,index+2,value); |
---|
141 | OSIUNITTEST_ADD_OUTCOME("cbc", "setColSetBounds on cols not in model", "should throw exception", OsiUnitTest::TestOutcome::ERROR, false); |
---|
142 | } |
---|
143 | catch (CoinError e) { |
---|
144 | if (OsiUnitTest::verbosity >= 1) |
---|
145 | std::cout<<"Correct throw from setObjCoeff on empty model"<<std::endl; |
---|
146 | } |
---|
147 | } |
---|
148 | |
---|
149 | { |
---|
150 | OsiCbcSolverInterface cbcSi(m); |
---|
151 | int nc = cbcSi.getNumCols(); |
---|
152 | int nr = cbcSi.getNumRows(); |
---|
153 | const double * cl = cbcSi.getColLower(); |
---|
154 | const double * cu = cbcSi.getColUpper(); |
---|
155 | const double * rl = cbcSi.getRowLower(); |
---|
156 | const double * ru = cbcSi.getRowUpper(); |
---|
157 | OSIUNITTEST_ASSERT_ERROR(nc == 8, return, "cbc", "read and copy exmip1"); |
---|
158 | OSIUNITTEST_ASSERT_ERROR(nr == 5, return, "cbc", "read and copy exmip1"); |
---|
159 | OSIUNITTEST_ASSERT_ERROR(eq(cl[0],2.5), {}, "cbc", "read and copy exmip1"); |
---|
160 | OSIUNITTEST_ASSERT_ERROR(eq(cl[1],0.0), {}, "cbc", "read and copy exmip1"); |
---|
161 | OSIUNITTEST_ASSERT_ERROR(eq(cu[1],4.1), {}, "cbc", "read and copy exmip1"); |
---|
162 | OSIUNITTEST_ASSERT_ERROR(eq(cu[2],1.0), {}, "cbc", "read and copy exmip1"); |
---|
163 | OSIUNITTEST_ASSERT_ERROR(eq(rl[0],2.5), {}, "cbc", "read and copy exmip1"); |
---|
164 | OSIUNITTEST_ASSERT_ERROR(eq(rl[4],3.0), {}, "cbc", "read and copy exmip1"); |
---|
165 | OSIUNITTEST_ASSERT_ERROR(eq(ru[1],2.1), {}, "cbc", "read and copy exmip1"); |
---|
166 | OSIUNITTEST_ASSERT_ERROR(eq(ru[4],15.), {}, "cbc", "read and copy exmip1"); |
---|
167 | |
---|
168 | const double * cs = cbcSi.getColSolution(); |
---|
169 | OSIUNITTEST_ASSERT_ERROR(eq(cs[0],2.5), {}, "cbc", "read and copy exmip1"); |
---|
170 | OSIUNITTEST_ASSERT_ERROR(eq(cs[7],0.0), {}, "cbc", "read and copy exmip1"); |
---|
171 | |
---|
172 | OSIUNITTEST_ASSERT_ERROR(!eq(cl[3],1.2345), {}, "cbc", "set col lower"); |
---|
173 | cbcSi.setColLower( 3, 1.2345 ); |
---|
174 | OSIUNITTEST_ASSERT_ERROR( eq(cbcSi.getColLower()[3],1.2345), {}, "cbc", "set col lower"); |
---|
175 | |
---|
176 | OSIUNITTEST_ASSERT_ERROR(!eq(cbcSi.getColUpper()[4],10.2345), {}, "cbc", "set col upper"); |
---|
177 | cbcSi.setColUpper( 4, 10.2345 ); |
---|
178 | OSIUNITTEST_ASSERT_ERROR( eq(cbcSi.getColUpper()[4],10.2345), {}, "cbc", "set col upper"); |
---|
179 | |
---|
180 | // LH: Objective will depend on how underlying solver constructs and maintains initial solution |
---|
181 | double objValue = cbcSi.getObjValue(); |
---|
182 | OSIUNITTEST_ASSERT_ERROR(eq(objValue,3.5) || eq(objValue,10.5), {}, "cbc", "getObjValue() before solve"); |
---|
183 | |
---|
184 | OSIUNITTEST_ASSERT_ERROR(eq(cbcSi.getObjCoefficients()[0], 1.0), {}, "cbc", "read and copy exmip1"); |
---|
185 | OSIUNITTEST_ASSERT_ERROR(eq(cbcSi.getObjCoefficients()[1], 0.0), {}, "cbc", "read and copy exmip1"); |
---|
186 | OSIUNITTEST_ASSERT_ERROR(eq(cbcSi.getObjCoefficients()[2], 0.0), {}, "cbc", "read and copy exmip1"); |
---|
187 | OSIUNITTEST_ASSERT_ERROR(eq(cbcSi.getObjCoefficients()[3], 0.0), {}, "cbc", "read and copy exmip1"); |
---|
188 | OSIUNITTEST_ASSERT_ERROR(eq(cbcSi.getObjCoefficients()[4], 2.0), {}, "cbc", "read and copy exmip1"); |
---|
189 | OSIUNITTEST_ASSERT_ERROR(eq(cbcSi.getObjCoefficients()[5], 0.0), {}, "cbc", "read and copy exmip1"); |
---|
190 | OSIUNITTEST_ASSERT_ERROR(eq(cbcSi.getObjCoefficients()[6], 0.0), {}, "cbc", "read and copy exmip1"); |
---|
191 | OSIUNITTEST_ASSERT_ERROR(eq(cbcSi.getObjCoefficients()[7],-1.0), {}, "cbc", "read and copy exmip1"); |
---|
192 | } |
---|
193 | |
---|
194 | // Test matrixByRow method |
---|
195 | { |
---|
196 | const OsiCbcSolverInterface si(m); |
---|
197 | const CoinPackedMatrix * smP = si.getMatrixByRow(); |
---|
198 | |
---|
199 | OSIUNITTEST_ASSERT_ERROR(smP->getMajorDim() == 5, return, "cbc", "getMatrixByRow: major dim"); |
---|
200 | OSIUNITTEST_ASSERT_ERROR(smP->getMinorDim() == 8, return, "cbc", "getMatrixByRow: major dim"); |
---|
201 | OSIUNITTEST_ASSERT_ERROR(smP->getNumElements() == 14, return, "cbc", "getMatrixByRow: num elements"); |
---|
202 | OSIUNITTEST_ASSERT_ERROR(smP->getSizeVectorStarts() == 6, return, "cbc", "getMatrixByRow: num elements"); |
---|
203 | |
---|
204 | #ifdef OSICBC_TEST_MTX_STRUCTURE |
---|
205 | CoinRelFltEq eq; |
---|
206 | const double * ev = smP->getElements(); |
---|
207 | OSIUNITTEST_ASSERT_ERROR(eq(ev[0], 3.0), {}, "cbc", "getMatrixByRow: elements"); |
---|
208 | OSIUNITTEST_ASSERT_ERROR(eq(ev[1], 1.0), {}, "cbc", "getMatrixByRow: elements"); |
---|
209 | OSIUNITTEST_ASSERT_ERROR(eq(ev[2], -2.0), {}, "cbc", "getMatrixByRow: elements"); |
---|
210 | OSIUNITTEST_ASSERT_ERROR(eq(ev[3], -1.0), {}, "cbc", "getMatrixByRow: elements"); |
---|
211 | OSIUNITTEST_ASSERT_ERROR(eq(ev[4], -1.0), {}, "cbc", "getMatrixByRow: elements"); |
---|
212 | OSIUNITTEST_ASSERT_ERROR(eq(ev[5], 2.0), {}, "cbc", "getMatrixByRow: elements"); |
---|
213 | OSIUNITTEST_ASSERT_ERROR(eq(ev[6], 1.1), {}, "cbc", "getMatrixByRow: elements"); |
---|
214 | OSIUNITTEST_ASSERT_ERROR(eq(ev[7], 1.0), {}, "cbc", "getMatrixByRow: elements"); |
---|
215 | OSIUNITTEST_ASSERT_ERROR(eq(ev[8], 1.0), {}, "cbc", "getMatrixByRow: elements"); |
---|
216 | OSIUNITTEST_ASSERT_ERROR(eq(ev[9], 2.8), {}, "cbc", "getMatrixByRow: elements"); |
---|
217 | OSIUNITTEST_ASSERT_ERROR(eq(ev[10], -1.2), {}, "cbc", "getMatrixByRow: elements"); |
---|
218 | OSIUNITTEST_ASSERT_ERROR(eq(ev[11], 5.6), {}, "cbc", "getMatrixByRow: elements"); |
---|
219 | OSIUNITTEST_ASSERT_ERROR(eq(ev[12], 1.0), {}, "cbc", "getMatrixByRow: elements"); |
---|
220 | OSIUNITTEST_ASSERT_ERROR(eq(ev[13], 1.9), {}, "cbc", "getMatrixByRow: elements"); |
---|
221 | |
---|
222 | const int * mi = smP->getVectorStarts(); |
---|
223 | OSIUNITTEST_ASSERT_ERROR(mi[0] == 0, {}, "cbc", "getMatrixByRow: vector starts"); |
---|
224 | OSIUNITTEST_ASSERT_ERROR(mi[1] == 5, {}, "cbc", "getMatrixByRow: vector starts"); |
---|
225 | OSIUNITTEST_ASSERT_ERROR(mi[2] == 7, {}, "cbc", "getMatrixByRow: vector starts"); |
---|
226 | OSIUNITTEST_ASSERT_ERROR(mi[3] == 9, {}, "cbc", "getMatrixByRow: vector starts"); |
---|
227 | OSIUNITTEST_ASSERT_ERROR(mi[4] == 11, {}, "cbc", "getMatrixByRow: vector starts"); |
---|
228 | OSIUNITTEST_ASSERT_ERROR(mi[5] == 14, {}, "cbc", "getMatrixByRow: vector starts"); |
---|
229 | |
---|
230 | const int * ei = smP->getIndices(); |
---|
231 | OSIUNITTEST_ASSERT_ERROR(ei[ 0] == 0, {}, "cbc", "getMatrixByRow: indices"); |
---|
232 | OSIUNITTEST_ASSERT_ERROR(ei[ 1] == 1, {}, "cbc", "getMatrixByRow: indices"); |
---|
233 | OSIUNITTEST_ASSERT_ERROR(ei[ 2] == 3, {}, "cbc", "getMatrixByRow: indices"); |
---|
234 | OSIUNITTEST_ASSERT_ERROR(ei[ 3] == 4, {}, "cbc", "getMatrixByRow: indices"); |
---|
235 | OSIUNITTEST_ASSERT_ERROR(ei[ 4] == 7, {}, "cbc", "getMatrixByRow: indices"); |
---|
236 | OSIUNITTEST_ASSERT_ERROR(ei[ 5] == 1, {}, "cbc", "getMatrixByRow: indices"); |
---|
237 | OSIUNITTEST_ASSERT_ERROR(ei[ 6] == 2, {}, "cbc", "getMatrixByRow: indices"); |
---|
238 | OSIUNITTEST_ASSERT_ERROR(ei[ 7] == 2, {}, "cbc", "getMatrixByRow: indices"); |
---|
239 | OSIUNITTEST_ASSERT_ERROR(ei[ 8] == 5, {}, "cbc", "getMatrixByRow: indices"); |
---|
240 | OSIUNITTEST_ASSERT_ERROR(ei[ 9] == 3, {}, "cbc", "getMatrixByRow: indices"); |
---|
241 | OSIUNITTEST_ASSERT_ERROR(ei[10] == 6, {}, "cbc", "getMatrixByRow: indices"); |
---|
242 | OSIUNITTEST_ASSERT_ERROR(ei[11] == 0, {}, "cbc", "getMatrixByRow: indices"); |
---|
243 | OSIUNITTEST_ASSERT_ERROR(ei[12] == 4, {}, "cbc", "getMatrixByRow: indices"); |
---|
244 | OSIUNITTEST_ASSERT_ERROR(ei[13] == 7, {}, "cbc", "getMatrixByRow: indices"); |
---|
245 | #else // OSICBC_TEST_MTX_STRUCTURE |
---|
246 | |
---|
247 | CoinPackedMatrix exmip1Mtx ; |
---|
248 | exmip1Mtx.reverseOrderedCopyOf(BuildExmip1Mtx()) ; |
---|
249 | OSIUNITTEST_ASSERT_ERROR(exmip1Mtx.isEquivalent(*smP), {}, "cbc", "getMatrixByRow") ; |
---|
250 | #endif // OSICBC_TEST_MTX_STRUCTURE |
---|
251 | } |
---|
252 | |
---|
253 | // Test adding several cuts, and handling of a coefficient of infinity |
---|
254 | // in the constraint matrix. |
---|
255 | { |
---|
256 | OsiCbcSolverInterface fim; |
---|
257 | std::string fn = mpsDir+"exmip1"; |
---|
258 | fim.readMps(fn.c_str(),"mps"); |
---|
259 | // exmip1.mps has 2 integer variables with index 2 & 3 |
---|
260 | fim.initialSolve(); |
---|
261 | OsiRowCut cuts[3]; |
---|
262 | |
---|
263 | |
---|
264 | // Generate one ineffective cut plus two trivial cuts |
---|
265 | int c; |
---|
266 | int nc = fim.getNumCols(); |
---|
267 | int *inx = new int[nc]; |
---|
268 | for (c=0;c<nc;c++) inx[c]=c; |
---|
269 | double *el = new double[nc]; |
---|
270 | for (c=0;c<nc;c++) el[c]=1.0e-50+((double)c)*((double)c); |
---|
271 | |
---|
272 | cuts[0].setRow(nc,inx,el); |
---|
273 | cuts[0].setLb(-100.); |
---|
274 | cuts[0].setUb(500.); |
---|
275 | cuts[0].setEffectiveness(22); |
---|
276 | el[4]=0.0; // to get inf later |
---|
277 | |
---|
278 | for (c=2;c<4;c++) { |
---|
279 | el[0]=1.0; |
---|
280 | inx[0]=c; |
---|
281 | cuts[c-1].setRow(1,inx,el); |
---|
282 | cuts[c-1].setLb(1.); |
---|
283 | cuts[c-1].setUb(100.); |
---|
284 | cuts[c-1].setEffectiveness(c); |
---|
285 | } |
---|
286 | fim.writeMps("x1.mps"); |
---|
287 | fim.applyRowCuts(3,cuts); |
---|
288 | fim.writeMps("x2.mps"); |
---|
289 | // resolve - should get message about zero elements |
---|
290 | fim.resolve(); |
---|
291 | fim.writeMps("x3.mps"); |
---|
292 | // check integer solution |
---|
293 | const double * cs = fim.getColSolution(); |
---|
294 | CoinRelFltEq eq; |
---|
295 | OSIUNITTEST_ASSERT_ERROR(eq(cs[2], 1.0), {}, "cbc", "add cuts"); |
---|
296 | OSIUNITTEST_ASSERT_ERROR(eq(cs[3], 1.0), {}, "cbc", "add cuts"); |
---|
297 | // check will find invalid matrix |
---|
298 | el[0]=1.0/el[4]; |
---|
299 | inx[0]=0; |
---|
300 | cuts[0].setRow(nc,inx,el); |
---|
301 | cuts[0].setLb(-100.); |
---|
302 | cuts[0].setUb(500.); |
---|
303 | cuts[0].setEffectiveness(22); |
---|
304 | fim.applyRowCut(cuts[0]); |
---|
305 | // resolve - should get message about zero elements |
---|
306 | fim.resolve(); |
---|
307 | OSIUNITTEST_ASSERT_WARNING(fim.isAbandoned(), {}, "cbc", "add cuts"); |
---|
308 | delete[]el; |
---|
309 | delete[]inx; |
---|
310 | } |
---|
311 | |
---|
312 | // Test matrixByCol method |
---|
313 | { |
---|
314 | const OsiCbcSolverInterface si(m); |
---|
315 | const CoinPackedMatrix * smP = si.getMatrixByCol(); |
---|
316 | |
---|
317 | OSIUNITTEST_ASSERT_ERROR(smP->getMajorDim() == 8, return, "cbc", "getMatrixByCol: major dim"); |
---|
318 | OSIUNITTEST_ASSERT_ERROR(smP->getMinorDim() == 5, return, "cbc", "getMatrixByCol: minor dim"); |
---|
319 | OSIUNITTEST_ASSERT_ERROR(smP->getNumElements() == 14, return, "cbc", "getMatrixByCol: number of elements"); |
---|
320 | OSIUNITTEST_ASSERT_ERROR(smP->getSizeVectorStarts() == 9, return, "cbc", "getMatrixByCol: vector starts size"); |
---|
321 | |
---|
322 | #ifdef OSICBC_TEST_MTX_STRUCTURE |
---|
323 | CoinRelFltEq eq; |
---|
324 | const double * ev = smP->getElements(); |
---|
325 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 0], 3.0), {}, "cbc", "getMatrixByCol: elements"); |
---|
326 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 1], 5.6), {}, "cbc", "getMatrixByCol: elements"); |
---|
327 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 2], 1.0), {}, "cbc", "getMatrixByCol: elements"); |
---|
328 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 3], 2.0), {}, "cbc", "getMatrixByCol: elements"); |
---|
329 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 4], 1.1), {}, "cbc", "getMatrixByCol: elements"); |
---|
330 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 5], 1.0), {}, "cbc", "getMatrixByCol: elements"); |
---|
331 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 6],-2.0), {}, "cbc", "getMatrixByCol: elements"); |
---|
332 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 7], 2.8), {}, "cbc", "getMatrixByCol: elements"); |
---|
333 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 8],-1.0), {}, "cbc", "getMatrixByCol: elements"); |
---|
334 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 9], 1.0), {}, "cbc", "getMatrixByCol: elements"); |
---|
335 | OSIUNITTEST_ASSERT_ERROR(eq(ev[10], 1.0), {}, "cbc", "getMatrixByCol: elements"); |
---|
336 | OSIUNITTEST_ASSERT_ERROR(eq(ev[11],-1.2), {}, "cbc", "getMatrixByCol: elements"); |
---|
337 | OSIUNITTEST_ASSERT_ERROR(eq(ev[12],-1.0), {}, "cbc", "getMatrixByCol: elements"); |
---|
338 | OSIUNITTEST_ASSERT_ERROR(eq(ev[13], 1.9), {}, "cbc", "getMatrixByCol: elements"); |
---|
339 | |
---|
340 | const CoinBigIndex * mi = smP->getVectorStarts(); |
---|
341 | OSIUNITTEST_ASSERT_ERROR(mi[0] == 0, {}, "cbc", "getMatrixByCol: vector starts"); |
---|
342 | OSIUNITTEST_ASSERT_ERROR(mi[1] == 2, {}, "cbc", "getMatrixByCol: vector starts"); |
---|
343 | OSIUNITTEST_ASSERT_ERROR(mi[2] == 4, {}, "cbc", "getMatrixByCol: vector starts"); |
---|
344 | OSIUNITTEST_ASSERT_ERROR(mi[3] == 6, {}, "cbc", "getMatrixByCol: vector starts"); |
---|
345 | OSIUNITTEST_ASSERT_ERROR(mi[4] == 8, {}, "cbc", "getMatrixByCol: vector starts"); |
---|
346 | OSIUNITTEST_ASSERT_ERROR(mi[5] == 10, {}, "cbc", "getMatrixByCol: vector starts"); |
---|
347 | OSIUNITTEST_ASSERT_ERROR(mi[6] == 11, {}, "cbc", "getMatrixByCol: vector starts"); |
---|
348 | OSIUNITTEST_ASSERT_ERROR(mi[7] == 12, {}, "cbc", "getMatrixByCol: vector starts"); |
---|
349 | OSIUNITTEST_ASSERT_ERROR(mi[8] == 14, {}, "cbc", "getMatrixByCol: vector starts"); |
---|
350 | |
---|
351 | const int * ei = smP->getIndices(); |
---|
352 | OSIUNITTEST_ASSERT_ERROR(ei[ 0] == 0, {}, "cbc", "getMatrixByCol: indices"); |
---|
353 | OSIUNITTEST_ASSERT_ERROR(ei[ 1] == 4, {}, "cbc", "getMatrixByCol: indices"); |
---|
354 | OSIUNITTEST_ASSERT_ERROR(ei[ 2] == 0, {}, "cbc", "getMatrixByCol: indices"); |
---|
355 | OSIUNITTEST_ASSERT_ERROR(ei[ 3] == 1, {}, "cbc", "getMatrixByCol: indices"); |
---|
356 | OSIUNITTEST_ASSERT_ERROR(ei[ 4] == 1, {}, "cbc", "getMatrixByCol: indices"); |
---|
357 | OSIUNITTEST_ASSERT_ERROR(ei[ 5] == 2, {}, "cbc", "getMatrixByCol: indices"); |
---|
358 | OSIUNITTEST_ASSERT_ERROR(ei[ 6] == 0, {}, "cbc", "getMatrixByCol: indices"); |
---|
359 | OSIUNITTEST_ASSERT_ERROR(ei[ 7] == 3, {}, "cbc", "getMatrixByCol: indices"); |
---|
360 | OSIUNITTEST_ASSERT_ERROR(ei[ 8] == 0, {}, "cbc", "getMatrixByCol: indices"); |
---|
361 | OSIUNITTEST_ASSERT_ERROR(ei[ 9] == 4, {}, "cbc", "getMatrixByCol: indices"); |
---|
362 | OSIUNITTEST_ASSERT_ERROR(ei[10] == 2, {}, "cbc", "getMatrixByCol: indices"); |
---|
363 | OSIUNITTEST_ASSERT_ERROR(ei[11] == 3, {}, "cbc", "getMatrixByCol: indices"); |
---|
364 | OSIUNITTEST_ASSERT_ERROR(ei[12] == 0, {}, "cbc", "getMatrixByCol: indices"); |
---|
365 | OSIUNITTEST_ASSERT_ERROR(ei[13] == 4, {}, "cbc", "getMatrixByCol: indices"); |
---|
366 | #else // OSICBC_TEST_MTX_STRUCTURE |
---|
367 | |
---|
368 | CoinPackedMatrix &exmip1Mtx = BuildExmip1Mtx() ; |
---|
369 | OSIUNITTEST_ASSERT_ERROR(exmip1Mtx.isEquivalent(*smP), {}, "cbc", "getMatrixByCol"); |
---|
370 | #endif // OSICBC_TEST_MTX_STRUCTURE |
---|
371 | } |
---|
372 | |
---|
373 | //-------------- |
---|
374 | // Test rowsense, rhs, rowrange, matrixByRow, solver assignment |
---|
375 | { |
---|
376 | OsiCbcSolverInterface lhs; |
---|
377 | { |
---|
378 | OsiCbcSolverInterface siC1(m); |
---|
379 | |
---|
380 | const char * siC1rs = siC1.getRowSense(); |
---|
381 | OSIUNITTEST_ASSERT_ERROR(siC1rs[0] == 'G', {}, "cbc", "row sense"); |
---|
382 | OSIUNITTEST_ASSERT_ERROR(siC1rs[1] == 'L', {}, "cbc", "row sense"); |
---|
383 | OSIUNITTEST_ASSERT_ERROR(siC1rs[2] == 'E', {}, "cbc", "row sense"); |
---|
384 | OSIUNITTEST_ASSERT_ERROR(siC1rs[3] == 'R', {}, "cbc", "row sense"); |
---|
385 | OSIUNITTEST_ASSERT_ERROR(siC1rs[4] == 'R', {}, "cbc", "row sense"); |
---|
386 | |
---|
387 | const double * siC1rhs = siC1.getRightHandSide(); |
---|
388 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[0],2.5), {}, "cbc", "right hand side"); |
---|
389 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[1],2.1), {}, "cbc", "right hand side"); |
---|
390 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[2],4.0), {}, "cbc", "right hand side"); |
---|
391 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[3],5.0), {}, "cbc", "right hand side"); |
---|
392 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[4],15.), {}, "cbc", "right hand side"); |
---|
393 | |
---|
394 | const double * siC1rr = siC1.getRowRange(); |
---|
395 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[0],0.0), {}, "cbc", "row range"); |
---|
396 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[1],0.0), {}, "cbc", "row range"); |
---|
397 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[2],0.0), {}, "cbc", "row range"); |
---|
398 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[3],5.0-1.8), {}, "cbc", "row range"); |
---|
399 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[4],15.0-3.0), {}, "cbc", "row range"); |
---|
400 | |
---|
401 | const CoinPackedMatrix * siC1mbr = siC1.getMatrixByRow(); |
---|
402 | OSIUNITTEST_ASSERT_ERROR(siC1mbr != NULL, {}, "cbc", "matrix by row"); |
---|
403 | OSIUNITTEST_ASSERT_ERROR(siC1mbr->getMajorDim() == 5, return, "cbc", "matrix by row: major dim"); |
---|
404 | OSIUNITTEST_ASSERT_ERROR(siC1mbr->getMinorDim() == 8, return, "cbc", "matrix by row: major dim"); |
---|
405 | OSIUNITTEST_ASSERT_ERROR(siC1mbr->getNumElements() == 14, return, "cbc", "matrix by row: num elements"); |
---|
406 | OSIUNITTEST_ASSERT_ERROR(siC1mbr->getSizeVectorStarts() == 6, return, "cbc", "matrix by row: num elements"); |
---|
407 | |
---|
408 | #ifdef OSICBC_TEST_MTX_STRUCTURE |
---|
409 | const double * ev = siC1mbr->getElements(); |
---|
410 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 0], 3.0), {}, "cbc", "matrix by row: elements"); |
---|
411 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 1], 1.0), {}, "cbc", "matrix by row: elements"); |
---|
412 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 2],-2.0), {}, "cbc", "matrix by row: elements"); |
---|
413 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 3],-1.0), {}, "cbc", "matrix by row: elements"); |
---|
414 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 4],-1.0), {}, "cbc", "matrix by row: elements"); |
---|
415 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 5], 2.0), {}, "cbc", "matrix by row: elements"); |
---|
416 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 6], 1.1), {}, "cbc", "matrix by row: elements"); |
---|
417 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 7], 1.0), {}, "cbc", "matrix by row: elements"); |
---|
418 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 8], 1.0), {}, "cbc", "matrix by row: elements"); |
---|
419 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 9], 2.8), {}, "cbc", "matrix by row: elements"); |
---|
420 | OSIUNITTEST_ASSERT_ERROR(eq(ev[10],-1.2), {}, "cbc", "matrix by row: elements"); |
---|
421 | OSIUNITTEST_ASSERT_ERROR(eq(ev[11], 5.6), {}, "cbc", "matrix by row: elements"); |
---|
422 | OSIUNITTEST_ASSERT_ERROR(eq(ev[12], 1.0), {}, "cbc", "matrix by row: elements"); |
---|
423 | OSIUNITTEST_ASSERT_ERROR(eq(ev[13], 1.9), {}, "cbc", "matrix by row: elements"); |
---|
424 | |
---|
425 | const CoinBigIndex * mi = siC1mbr->getVectorStarts(); |
---|
426 | OSIUNITTEST_ASSERT_ERROR(mi[0] == 0, {}, "cbc", "matrix by row: vector starts"); |
---|
427 | OSIUNITTEST_ASSERT_ERROR(mi[1] == 5, {}, "cbc", "matrix by row: vector starts"); |
---|
428 | OSIUNITTEST_ASSERT_ERROR(mi[2] == 7, {}, "cbc", "matrix by row: vector starts"); |
---|
429 | OSIUNITTEST_ASSERT_ERROR(mi[3] == 9, {}, "cbc", "matrix by row: vector starts"); |
---|
430 | OSIUNITTEST_ASSERT_ERROR(mi[4] == 11, {}, "cbc", "matrix by row: vector starts"); |
---|
431 | OSIUNITTEST_ASSERT_ERROR(mi[5] == 14, {}, "cbc", "matrix by row: vector starts"); |
---|
432 | |
---|
433 | const int * ei = siC1mbr->getIndices(); |
---|
434 | OSIUNITTEST_ASSERT_ERROR(ei[ 0] == 0, {}, "cbc", "matrix by row: indices"); |
---|
435 | OSIUNITTEST_ASSERT_ERROR(ei[ 1] == 1, {}, "cbc", "matrix by row: indices"); |
---|
436 | OSIUNITTEST_ASSERT_ERROR(ei[ 2] == 3, {}, "cbc", "matrix by row: indices"); |
---|
437 | OSIUNITTEST_ASSERT_ERROR(ei[ 3] == 4, {}, "cbc", "matrix by row: indices"); |
---|
438 | OSIUNITTEST_ASSERT_ERROR(ei[ 4] == 7, {}, "cbc", "matrix by row: indices"); |
---|
439 | OSIUNITTEST_ASSERT_ERROR(ei[ 5] == 1, {}, "cbc", "matrix by row: indices"); |
---|
440 | OSIUNITTEST_ASSERT_ERROR(ei[ 6] == 2, {}, "cbc", "matrix by row: indices"); |
---|
441 | OSIUNITTEST_ASSERT_ERROR(ei[ 7] == 2, {}, "cbc", "matrix by row: indices"); |
---|
442 | OSIUNITTEST_ASSERT_ERROR(ei[ 8] == 5, {}, "cbc", "matrix by row: indices"); |
---|
443 | OSIUNITTEST_ASSERT_ERROR(ei[ 9] == 3, {}, "cbc", "matrix by row: indices"); |
---|
444 | OSIUNITTEST_ASSERT_ERROR(ei[10] == 6, {}, "cbc", "matrix by row: indices"); |
---|
445 | OSIUNITTEST_ASSERT_ERROR(ei[11] == 0, {}, "cbc", "matrix by row: indices"); |
---|
446 | OSIUNITTEST_ASSERT_ERROR(ei[12] == 4, {}, "cbc", "matrix by row: indices"); |
---|
447 | OSIUNITTEST_ASSERT_ERROR(ei[13] == 7, {}, "cbc", "matrix by row: indices"); |
---|
448 | #else // OSICBC_TEST_MTX_STRUCTURE |
---|
449 | |
---|
450 | CoinPackedMatrix exmip1Mtx ; |
---|
451 | exmip1Mtx.reverseOrderedCopyOf(BuildExmip1Mtx()) ; |
---|
452 | OSIUNITTEST_ASSERT_ERROR(exmip1Mtx.isEquivalent(*siC1mbr), {}, "cbc", "matrix by row"); |
---|
453 | #endif // OSICBC_TEST_MTX_STRUCTURE |
---|
454 | |
---|
455 | OSIUNITTEST_ASSERT_WARNING(siC1rs == siC1.getRowSense(), {}, "cbc", "row sense"); |
---|
456 | OSIUNITTEST_ASSERT_WARNING(siC1rhs == siC1.getRightHandSide(), {}, "cbc", "right hand side"); |
---|
457 | OSIUNITTEST_ASSERT_WARNING(siC1rr == siC1.getRowRange(), {}, "cbc", "row range"); |
---|
458 | |
---|
459 | // Change CBC Model by adding free row |
---|
460 | OsiRowCut rc; |
---|
461 | rc.setLb(-COIN_DBL_MAX); |
---|
462 | rc.setUb( COIN_DBL_MAX); |
---|
463 | OsiCuts cuts; |
---|
464 | cuts.insert(rc); |
---|
465 | siC1.applyCuts(cuts); |
---|
466 | |
---|
467 | siC1rs = siC1.getRowSense(); |
---|
468 | OSIUNITTEST_ASSERT_ERROR(siC1rs[0] == 'G', {}, "cbc", "row sense after adding row"); |
---|
469 | OSIUNITTEST_ASSERT_ERROR(siC1rs[1] == 'L', {}, "cbc", "row sense after adding row"); |
---|
470 | OSIUNITTEST_ASSERT_ERROR(siC1rs[2] == 'E', {}, "cbc", "row sense after adding row"); |
---|
471 | OSIUNITTEST_ASSERT_ERROR(siC1rs[3] == 'R', {}, "cbc", "row sense after adding row"); |
---|
472 | OSIUNITTEST_ASSERT_ERROR(siC1rs[4] == 'R', {}, "cbc", "row sense after adding row"); |
---|
473 | OSIUNITTEST_ASSERT_ERROR(siC1rs[5] == 'N', {}, "cbc", "row sense after adding row"); |
---|
474 | |
---|
475 | siC1rhs = siC1.getRightHandSide(); |
---|
476 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[0],2.5), {}, "cbc", "right hand side after adding row"); |
---|
477 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[1],2.1), {}, "cbc", "right hand side after adding row"); |
---|
478 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[2],4.0), {}, "cbc", "right hand side after adding row"); |
---|
479 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[3],5.0), {}, "cbc", "right hand side after adding row"); |
---|
480 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[4],15.), {}, "cbc", "right hand side after adding row"); |
---|
481 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[5],0.0), {}, "cbc", "right hand side after adding row"); |
---|
482 | |
---|
483 | siC1rr = siC1.getRowRange(); |
---|
484 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[0],0.0), {}, "cbc", "row range after adding row"); |
---|
485 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[1],0.0), {}, "cbc", "row range after adding row"); |
---|
486 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[2],0.0), {}, "cbc", "row range after adding row"); |
---|
487 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[3],5.0-1.8), {}, "cbc", "row range after adding row"); |
---|
488 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[4],15.0-3.0), {}, "cbc", "row range after adding row"); |
---|
489 | OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[5],0.0), {}, "cbc", "row range after adding row"); |
---|
490 | |
---|
491 | lhs = siC1; |
---|
492 | } |
---|
493 | |
---|
494 | // Test that lhs has correct values even though siC1 has gone out of scope |
---|
495 | const char * lhsrs = lhs.getRowSense(); |
---|
496 | OSIUNITTEST_ASSERT_ERROR(lhsrs[0] == 'G', {}, "cbc", "row sense after assignment"); |
---|
497 | OSIUNITTEST_ASSERT_ERROR(lhsrs[1] == 'L', {}, "cbc", "row sense after assignment"); |
---|
498 | OSIUNITTEST_ASSERT_ERROR(lhsrs[2] == 'E', {}, "cbc", "row sense after assignment"); |
---|
499 | OSIUNITTEST_ASSERT_ERROR(lhsrs[3] == 'R', {}, "cbc", "row sense after assignment"); |
---|
500 | OSIUNITTEST_ASSERT_ERROR(lhsrs[4] == 'R', {}, "cbc", "row sense after assignment"); |
---|
501 | OSIUNITTEST_ASSERT_ERROR(lhsrs[5] == 'N', {}, "cbc", "row sense after assignment"); |
---|
502 | |
---|
503 | const double * lhsrhs = lhs.getRightHandSide(); |
---|
504 | OSIUNITTEST_ASSERT_ERROR(eq(lhsrhs[0],2.5), {}, "cbc", "right hand side after assignment"); |
---|
505 | OSIUNITTEST_ASSERT_ERROR(eq(lhsrhs[1],2.1), {}, "cbc", "right hand side after assignment"); |
---|
506 | OSIUNITTEST_ASSERT_ERROR(eq(lhsrhs[2],4.0), {}, "cbc", "right hand side after assignment"); |
---|
507 | OSIUNITTEST_ASSERT_ERROR(eq(lhsrhs[3],5.0), {}, "cbc", "right hand side after assignment"); |
---|
508 | OSIUNITTEST_ASSERT_ERROR(eq(lhsrhs[4],15.), {}, "cbc", "right hand side after assignment"); |
---|
509 | OSIUNITTEST_ASSERT_ERROR(eq(lhsrhs[5],0.0), {}, "cbc", "right hand side after assignment"); |
---|
510 | |
---|
511 | const double *lhsrr = lhs.getRowRange(); |
---|
512 | OSIUNITTEST_ASSERT_ERROR(eq(lhsrr[0],0.0), {}, "cbc", "row range after assignment"); |
---|
513 | OSIUNITTEST_ASSERT_ERROR(eq(lhsrr[1],0.0), {}, "cbc", "row range after assignment"); |
---|
514 | OSIUNITTEST_ASSERT_ERROR(eq(lhsrr[2],0.0), {}, "cbc", "row range after assignment"); |
---|
515 | OSIUNITTEST_ASSERT_ERROR(eq(lhsrr[3],5.0-1.8), {}, "cbc", "row range after assignment"); |
---|
516 | OSIUNITTEST_ASSERT_ERROR(eq(lhsrr[4],15.0-3.0), {}, "cbc", "row range after assignment"); |
---|
517 | OSIUNITTEST_ASSERT_ERROR(eq(lhsrr[5],0.0), {}, "cbc", "row range after assignment"); |
---|
518 | |
---|
519 | const CoinPackedMatrix * lhsmbr = lhs.getMatrixByRow(); |
---|
520 | OSIUNITTEST_ASSERT_ERROR(lhsmbr != NULL, {}, "cbc", "matrix by row after assignment"); |
---|
521 | OSIUNITTEST_ASSERT_ERROR(lhsmbr->getMajorDim() == 6, return, "cbc", "matrix by row after assignment: major dim"); |
---|
522 | OSIUNITTEST_ASSERT_ERROR(lhsmbr->getNumElements() == 14, return, "cbc", "matrix by row after assignment: num elements"); |
---|
523 | |
---|
524 | |
---|
525 | #ifdef OSICBC_TEST_MTX_STRUCTURE |
---|
526 | const double * ev = lhsmbr->getElements(); |
---|
527 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 0], 3.0), {}, "cbc", "matrix by row after assignment: elements"); |
---|
528 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 1], 1.0), {}, "cbc", "matrix by row after assignment: elements"); |
---|
529 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 2],-2.0), {}, "cbc", "matrix by row after assignment: elements"); |
---|
530 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 3],-1.0), {}, "cbc", "matrix by row after assignment: elements"); |
---|
531 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 4],-1.0), {}, "cbc", "matrix by row after assignment: elements"); |
---|
532 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 5], 2.0), {}, "cbc", "matrix by row after assignment: elements"); |
---|
533 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 6], 1.1), {}, "cbc", "matrix by row after assignment: elements"); |
---|
534 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 7], 1.0), {}, "cbc", "matrix by row after assignment: elements"); |
---|
535 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 8], 1.0), {}, "cbc", "matrix by row after assignment: elements"); |
---|
536 | OSIUNITTEST_ASSERT_ERROR(eq(ev[ 9], 2.8), {}, "cbc", "matrix by row after assignment: elements"); |
---|
537 | OSIUNITTEST_ASSERT_ERROR(eq(ev[10],-1.2), {}, "cbc", "matrix by row after assignment: elements"); |
---|
538 | OSIUNITTEST_ASSERT_ERROR(eq(ev[11], 5.6), {}, "cbc", "matrix by row after assignment: elements"); |
---|
539 | OSIUNITTEST_ASSERT_ERROR(eq(ev[12], 1.0), {}, "cbc", "matrix by row after assignment: elements"); |
---|
540 | OSIUNITTEST_ASSERT_ERROR(eq(ev[13], 1.9), {}, "cbc", "matrix by row after assignment: elements"); |
---|
541 | |
---|
542 | const CoinBigIndex * mi = lhsmbr->getVectorStarts(); |
---|
543 | OSIUNITTEST_ASSERT_ERROR(mi[0] == 0, {}, "cbc", "matrix by row after assignment: vector starts"); |
---|
544 | OSIUNITTEST_ASSERT_ERROR(mi[1] == 5, {}, "cbc", "matrix by row after assignment: vector starts"); |
---|
545 | OSIUNITTEST_ASSERT_ERROR(mi[2] == 7, {}, "cbc", "matrix by row after assignment: vector starts"); |
---|
546 | OSIUNITTEST_ASSERT_ERROR(mi[3] == 9, {}, "cbc", "matrix by row after assignment: vector starts"); |
---|
547 | OSIUNITTEST_ASSERT_ERROR(mi[4] == 11, {}, "cbc", "matrix by row after assignment: vector starts"); |
---|
548 | OSIUNITTEST_ASSERT_ERROR(mi[5] == 14, {}, "cbc", "matrix by row after assignment: vector starts"); |
---|
549 | |
---|
550 | const int * ei = lhsmbr->getIndices(); |
---|
551 | OSIUNITTEST_ASSERT_ERROR(ei[ 0] == 0, {}, "cbc", "matrix by row after assignment: indices"); |
---|
552 | OSIUNITTEST_ASSERT_ERROR(ei[ 1] == 1, {}, "cbc", "matrix by row after assignment: indices"); |
---|
553 | OSIUNITTEST_ASSERT_ERROR(ei[ 2] == 3, {}, "cbc", "matrix by row after assignment: indices"); |
---|
554 | OSIUNITTEST_ASSERT_ERROR(ei[ 3] == 4, {}, "cbc", "matrix by row after assignment: indices"); |
---|
555 | OSIUNITTEST_ASSERT_ERROR(ei[ 4] == 7, {}, "cbc", "matrix by row after assignment: indices"); |
---|
556 | OSIUNITTEST_ASSERT_ERROR(ei[ 5] == 1, {}, "cbc", "matrix by row after assignment: indices"); |
---|
557 | OSIUNITTEST_ASSERT_ERROR(ei[ 6] == 2, {}, "cbc", "matrix by row after assignment: indices"); |
---|
558 | OSIUNITTEST_ASSERT_ERROR(ei[ 7] == 2, {}, "cbc", "matrix by row after assignment: indices"); |
---|
559 | OSIUNITTEST_ASSERT_ERROR(ei[ 8] == 5, {}, "cbc", "matrix by row after assignment: indices"); |
---|
560 | OSIUNITTEST_ASSERT_ERROR(ei[ 9] == 3, {}, "cbc", "matrix by row after assignment: indices"); |
---|
561 | OSIUNITTEST_ASSERT_ERROR(ei[10] == 6, {}, "cbc", "matrix by row after assignment: indices"); |
---|
562 | OSIUNITTEST_ASSERT_ERROR(ei[11] == 0, {}, "cbc", "matrix by row after assignment: indices"); |
---|
563 | OSIUNITTEST_ASSERT_ERROR(ei[12] == 4, {}, "cbc", "matrix by row after assignment: indices"); |
---|
564 | OSIUNITTEST_ASSERT_ERROR(ei[13] == 7, {}, "cbc", "matrix by row after assignment: indices"); |
---|
565 | #else // OSICBC_TEST_MTX_STRUCTURE |
---|
566 | |
---|
567 | /* |
---|
568 | This admittedly looks bogus, but it's the equivalent operation on the matrix |
---|
569 | for inserting a cut of the form -Inf <= +Inf (i.e., a cut with no |
---|
570 | coefficients). |
---|
571 | */ |
---|
572 | CoinPackedMatrix exmip1Mtx ; |
---|
573 | exmip1Mtx.reverseOrderedCopyOf(BuildExmip1Mtx()) ; |
---|
574 | CoinPackedVector freeRow ; |
---|
575 | exmip1Mtx.appendRow(freeRow) ; |
---|
576 | OSIUNITTEST_ASSERT_ERROR(exmip1Mtx.isEquivalent(*lhsmbr), {}, "cbc", "matrix by row after assignment"); |
---|
577 | #endif // OSICBC_TEST_MTX_STRUCTURE |
---|
578 | } |
---|
579 | } |
---|
580 | |
---|
581 | // Test add/delete columns |
---|
582 | { |
---|
583 | OsiCbcSolverInterface m; |
---|
584 | std::string fn = mpsDir+"p0033"; |
---|
585 | m.readMps(fn.c_str(),"mps"); |
---|
586 | double inf = m.getInfinity(); |
---|
587 | |
---|
588 | CoinPackedVector c0; |
---|
589 | c0.insert(0, 4); |
---|
590 | c0.insert(1, 1); |
---|
591 | m.addCol(c0, 0, inf, 3); |
---|
592 | m.initialSolve(); |
---|
593 | double objValue = m.getObjValue(); |
---|
594 | CoinRelFltEq eq(1.0e-2); |
---|
595 | OSIUNITTEST_ASSERT_ERROR(eq(objValue,2520.57), {}, "cbc", "objvalue after adding col"); |
---|
596 | |
---|
597 | // Try deleting first column that's nonbasic at lower bound (0). |
---|
598 | int * d = new int[1]; |
---|
599 | CoinWarmStartBasis *cwsb = dynamic_cast<CoinWarmStartBasis *>(m.getWarmStart()) ; |
---|
600 | OSIUNITTEST_ASSERT_ERROR(cwsb != NULL, {}, "cbc", "get warmstart basis"); |
---|
601 | CoinWarmStartBasis::Status stati ; |
---|
602 | int iCol ; |
---|
603 | for (iCol = 0 ; iCol < cwsb->getNumStructural() ; iCol++) |
---|
604 | { stati = cwsb->getStructStatus(iCol) ; |
---|
605 | if (stati == CoinWarmStartBasis::atLowerBound) break ; } |
---|
606 | d[0]=iCol; |
---|
607 | m.deleteCols(1,d); |
---|
608 | delete [] d; |
---|
609 | delete cwsb; |
---|
610 | d=NULL; |
---|
611 | m.resolve(); |
---|
612 | objValue = m.getObjValue(); |
---|
613 | OSIUNITTEST_ASSERT_ERROR(eq(objValue,2520.57), {}, "clp", "objvalue after deleting first col"); |
---|
614 | |
---|
615 | // Try deleting column we added. If basic, go to initialSolve as deleting |
---|
616 | // basic variable trashes basis required for warm start. |
---|
617 | iCol = m.getNumCols()-1; |
---|
618 | cwsb = dynamic_cast<CoinWarmStartBasis *>(m.getWarmStart()) ; |
---|
619 | stati = cwsb->getStructStatus(iCol) ; |
---|
620 | delete cwsb; |
---|
621 | m.deleteCols(1,&iCol); |
---|
622 | if (stati == CoinWarmStartBasis::basic) |
---|
623 | { m.initialSolve() ; } |
---|
624 | else |
---|
625 | { m.resolve(); } |
---|
626 | objValue = m.getObjValue(); |
---|
627 | OSIUNITTEST_ASSERT_ERROR(eq(objValue,2520.57), {}, "clp", "objvalue after deleting added col"); |
---|
628 | } |
---|
629 | |
---|
630 | // Build a model |
---|
631 | { |
---|
632 | OsiCbcSolverInterface model; |
---|
633 | std::string fn = mpsDir+"p0033"; |
---|
634 | model.readMps(fn.c_str(),"mps"); |
---|
635 | // Point to data |
---|
636 | int numberRows = model.getNumRows(); |
---|
637 | const double * rowLower = model.getRowLower(); |
---|
638 | const double * rowUpper = model.getRowUpper(); |
---|
639 | int numberColumns = model.getNumCols(); |
---|
640 | const double * columnLower = model.getColLower(); |
---|
641 | const double * columnUpper = model.getColUpper(); |
---|
642 | const double * columnObjective = model.getObjCoefficients(); |
---|
643 | // get row copy |
---|
644 | CoinPackedMatrix rowCopy = *model.getMatrixByRow(); |
---|
645 | const int * column = rowCopy.getIndices(); |
---|
646 | const int * rowLength = rowCopy.getVectorLengths(); |
---|
647 | const CoinBigIndex * rowStart = rowCopy.getVectorStarts(); |
---|
648 | const double * element = rowCopy.getElements(); |
---|
649 | |
---|
650 | // solve |
---|
651 | model.initialSolve(); |
---|
652 | // Now build new model |
---|
653 | CoinModel build; |
---|
654 | // Row bounds |
---|
655 | int iRow; |
---|
656 | for (iRow=0;iRow<numberRows;iRow++) { |
---|
657 | build.setRowBounds(iRow,rowLower[iRow],rowUpper[iRow]); |
---|
658 | } |
---|
659 | // Column bounds and objective |
---|
660 | int iColumn; |
---|
661 | for (iColumn=0;iColumn<numberColumns;iColumn++) { |
---|
662 | build.setColumnLower(iColumn,columnLower[iColumn]); |
---|
663 | build.setColumnUpper(iColumn,columnUpper[iColumn]); |
---|
664 | build.setObjective(iColumn,columnObjective[iColumn]); |
---|
665 | } |
---|
666 | // Adds elements one by one by row (backwards by row) |
---|
667 | for (iRow=numberRows-1;iRow>=0;iRow--) { |
---|
668 | int start = rowStart[iRow]; |
---|
669 | for (int j=start;j<start+rowLength[iRow];j++) |
---|
670 | build(iRow,column[j],element[j]); |
---|
671 | } |
---|
672 | // Now create Model |
---|
673 | OsiCbcSolverInterface model2; |
---|
674 | model2.loadFromCoinModel(build); |
---|
675 | model2.initialSolve(); |
---|
676 | // Save - should be continuous |
---|
677 | model2.writeMps("continuous"); |
---|
678 | int * whichInteger = new int[numberColumns]; |
---|
679 | for (iColumn=0;iColumn<numberColumns;iColumn++) |
---|
680 | whichInteger[iColumn]=iColumn; |
---|
681 | // mark as integer |
---|
682 | model2.setInteger(whichInteger,numberColumns); |
---|
683 | delete [] whichInteger; |
---|
684 | // save - should be integer |
---|
685 | model2.writeMps("integer"); |
---|
686 | |
---|
687 | // Now do with strings attached |
---|
688 | // Save build to show how to go over rows |
---|
689 | CoinModel saveBuild = build; |
---|
690 | build = CoinModel(); |
---|
691 | // Column bounds |
---|
692 | for (iColumn=0;iColumn<numberColumns;iColumn++) { |
---|
693 | build.setColumnLower(iColumn,columnLower[iColumn]); |
---|
694 | build.setColumnUpper(iColumn,columnUpper[iColumn]); |
---|
695 | } |
---|
696 | // Objective - half the columns as is and half with multiplier of "1.0+multiplier" |
---|
697 | // Pick up from saveBuild (for no reason at all) |
---|
698 | for (iColumn=0;iColumn<numberColumns;iColumn++) { |
---|
699 | double value = saveBuild.objective(iColumn); |
---|
700 | if (iColumn*2<numberColumns) { |
---|
701 | build.setObjective(iColumn,columnObjective[iColumn]); |
---|
702 | } else { |
---|
703 | // create as string |
---|
704 | char temp[100]; |
---|
705 | sprintf(temp,"%g + abs(%g*multiplier)",value,value); |
---|
706 | build.setObjective(iColumn,temp); |
---|
707 | } |
---|
708 | } |
---|
709 | // It then adds rows one by one but for half the rows sets their values |
---|
710 | // with multiplier of "1.0+1.5*multiplier" |
---|
711 | for (iRow=0;iRow<numberRows;iRow++) { |
---|
712 | if (iRow*2<numberRows) { |
---|
713 | // add row in simple way |
---|
714 | int start = rowStart[iRow]; |
---|
715 | build.addRow(rowLength[iRow],column+start,element+start, |
---|
716 | rowLower[iRow],rowUpper[iRow]); |
---|
717 | } else { |
---|
718 | // As we have to add one by one let's get from saveBuild |
---|
719 | CoinModelLink triple=saveBuild.firstInRow(iRow); |
---|
720 | while (triple.column()>=0) { |
---|
721 | int iColumn = triple.column(); |
---|
722 | if (iColumn*2<numberColumns) { |
---|
723 | // just value as normal |
---|
724 | build(iRow,triple.column(),triple.value()); |
---|
725 | } else { |
---|
726 | // create as string |
---|
727 | char temp[100]; |
---|
728 | sprintf(temp,"%g + (1.5*%g*multiplier)",triple.value(), triple.value()); |
---|
729 | build(iRow,iColumn,temp); |
---|
730 | } |
---|
731 | triple=saveBuild.next(triple); |
---|
732 | } |
---|
733 | // but remember to do rhs |
---|
734 | build.setRowLower(iRow,rowLower[iRow]); |
---|
735 | build.setRowUpper(iRow,rowUpper[iRow]); |
---|
736 | } |
---|
737 | } |
---|
738 | // If small switch on error printing |
---|
739 | if (numberColumns<50) |
---|
740 | build.setLogLevel(1); |
---|
741 | // should fail as we never set multiplier |
---|
742 | OSIUNITTEST_ASSERT_ERROR(model2.loadFromCoinModel(build) != 0, {}, "cbc", "build model with missing multipliers"); |
---|
743 | build.associateElement("multiplier",0.0); |
---|
744 | OSIUNITTEST_ASSERT_ERROR(model2.loadFromCoinModel(build) == 0, {}, "cbc", "build model"); |
---|
745 | model2.initialSolve(); |
---|
746 | // It then loops with multiplier going from 0.0 to 2.0 in increments of 0.1 |
---|
747 | for (double multiplier=0.0;multiplier<2.0;multiplier+= 0.1) { |
---|
748 | build.associateElement("multiplier",multiplier); |
---|
749 | OSIUNITTEST_ASSERT_ERROR(model2.loadFromCoinModel(build,true) == 0, {}, "cbc", "build model with increasing multiplier"); |
---|
750 | model2.resolve(); |
---|
751 | } |
---|
752 | } |
---|
753 | |
---|
754 | // branch and bound |
---|
755 | { |
---|
756 | OsiCbcSolverInterface m; |
---|
757 | std::string fn = mpsDir+"p0033"; |
---|
758 | m.readMps(fn.c_str(),"mps"); |
---|
759 | m.initialSolve(); |
---|
760 | //m.messageHandler()->setLogLevel(0); |
---|
761 | m.getModelPtr()->messageHandler()->setLogLevel(0); |
---|
762 | m.branchAndBound(); |
---|
763 | } |
---|
764 | |
---|
765 | // branch and bound using CbcModel!!!!!!! |
---|
766 | { |
---|
767 | OsiCbcSolverInterface mm; |
---|
768 | OsiCbcSolverInterface m(&mm); |
---|
769 | std::string fn = mpsDir+"p0033"; |
---|
770 | m.readMps(fn.c_str(),"mps"); |
---|
771 | m.initialSolve(); |
---|
772 | m.branchAndBound(); |
---|
773 | } |
---|
774 | |
---|
775 | // Do common solverInterface testing |
---|
776 | { |
---|
777 | OsiCbcSolverInterface m; |
---|
778 | OsiSolverInterfaceCommonUnitTest(&m, mpsDir,netlibDir); |
---|
779 | } |
---|
780 | { |
---|
781 | OsiCbcSolverInterface mm; |
---|
782 | OsiCbcSolverInterface m(&mm); |
---|
783 | OsiSolverInterfaceCommonUnitTest(&m, mpsDir,netlibDir); |
---|
784 | } |
---|
785 | } |
---|