1 //-----------------------------------------------------------------------------
2 // name: OSI Interface for GUROBI
3 // template: OSI Cplex Interface written by T. Achterberg
4 // author: Stefan Vigerske
5 // Humboldt University Berlin
6 // license: this file may be freely distributed under the terms of EPL
7 // comments: please scan this file for '???' and 'TODO' and read the comments
8 //-----------------------------------------------------------------------------
9 // Copyright (C) 2009 Humboldt University Berlin and others.
10 // Corporation and others. All Rights Reserved.
11
12 #include "CoinPragma.hpp"
13 #include "OsiConfig.h"
14
15 //#include <cassert>
16 //#include <iostream>
17
18 #include "OsiUnitTests.hpp"
19 #include "OsiGrbSolverInterface.hpp"
20 #include "OsiCuts.hpp"
21 #include "OsiRowCut.hpp"
22 #include "OsiColCut.hpp"
23 #include "CoinPackedMatrix.hpp"
24
25 // Added so build windows build with dsp files works,
26 // when not building with gurobi.
27 #ifdef COIN_HAS_GRB
28 #include "gurobi_c.h"
29
30 //--------------------------------------------------------------------------
OsiGrbSolverInterfaceUnitTest(const std::string & mpsDir,const std::string & netlibDir)31 void OsiGrbSolverInterfaceUnitTest( const std::string & mpsDir, const std::string & netlibDir )
32 {
33 // Test default constructor
34 {
35 OsiGrbSolverInterface m;
36 OSIUNITTEST_ASSERT_ERROR(m.obj_ == NULL, {}, "gurobi", "default constructor");
37 OSIUNITTEST_ASSERT_ERROR(m.collower_ == NULL, {}, "gurobi", "default constructor");
38 OSIUNITTEST_ASSERT_ERROR(m.colupper_ == NULL, {}, "gurobi", "default constructor");
39 OSIUNITTEST_ASSERT_ERROR(m.coltype_ == NULL, {}, "gurobi", "default constructor");
40 OSIUNITTEST_ASSERT_ERROR(m.colspace_ == 0, {}, "gurobi", "default constructor");
41 OSIUNITTEST_ASSERT_ERROR(m.rowsense_ == NULL, {}, "gurobi", "default constructor");
42 OSIUNITTEST_ASSERT_ERROR(m.rhs_ == NULL, {}, "gurobi", "default constructor");
43 OSIUNITTEST_ASSERT_ERROR(m.rowrange_ == NULL, {}, "gurobi", "default constructor");
44 OSIUNITTEST_ASSERT_ERROR(m.rowlower_ == NULL, {}, "gurobi", "default constructor");
45 OSIUNITTEST_ASSERT_ERROR(m.rowupper_ == NULL, {}, "gurobi", "default constructor");
46 OSIUNITTEST_ASSERT_ERROR(m.colsol_ == NULL, {}, "gurobi", "default constructor");
47 OSIUNITTEST_ASSERT_ERROR(m.rowsol_ == NULL, {}, "gurobi", "default constructor");
48 OSIUNITTEST_ASSERT_ERROR(m.matrixByRow_ == NULL, {}, "gurobi", "default constructor");
49 OSIUNITTEST_ASSERT_ERROR(m.matrixByCol_ == NULL, {}, "gurobi", "default constructor");
50 OSIUNITTEST_ASSERT_ERROR(m.getNumCols() == 0, {}, "gurobi", "default constructor");
51 OSIUNITTEST_ASSERT_ERROR(m.getApplicationData() == NULL, {}, "gurobi", "default constructor");
52 int i=2346;
53 m.setApplicationData(&i);
54 OSIUNITTEST_ASSERT_ERROR(*((int *)(m.getApplicationData())) == i, {}, "gurobi", "default constructor");
55 }
56
57 {
58 CoinRelFltEq eq;
59 OsiGrbSolverInterface m;
60 std::string fn = mpsDir+"exmip1";
61 m.readMps(fn.c_str(),"mps");
62
63 {
64 OSIUNITTEST_ASSERT_ERROR(m.getNumCols() == 8, {}, "gurobi", "exmip1 read");
65 const CoinPackedMatrix * colCopy = m.getMatrixByCol();
66 OSIUNITTEST_ASSERT_ERROR(colCopy->getNumCols() == 8, {}, "gurobi", "exmip1 matrix");
67 OSIUNITTEST_ASSERT_ERROR(colCopy->getMajorDim() == 8, {}, "gurobi", "exmip1 matrix");
68 OSIUNITTEST_ASSERT_ERROR(colCopy->getNumRows() == 5, {}, "gurobi", "exmip1 matrix");
69 OSIUNITTEST_ASSERT_ERROR(colCopy->getMinorDim() == 5, {}, "gurobi", "exmip1 matrix");
70 OSIUNITTEST_ASSERT_ERROR(colCopy->getVectorLengths()[7] == 2, {}, "gurobi", "exmip1 matrix");
71 CoinPackedMatrix revColCopy;
72 revColCopy.reverseOrderedCopyOf(*colCopy);
73 CoinPackedMatrix rev2ColCopy;
74 rev2ColCopy.reverseOrderedCopyOf(revColCopy);
75 OSIUNITTEST_ASSERT_ERROR(rev2ColCopy.getNumCols() == 8, {}, "gurobi", "twice reverse matrix copy");
76 OSIUNITTEST_ASSERT_ERROR(rev2ColCopy.getMajorDim() == 8, {}, "gurobi", "twice reverse matrix copy");
77 OSIUNITTEST_ASSERT_ERROR(rev2ColCopy.getNumRows() == 5, {}, "gurobi", "twice reverse matrix copy");
78 OSIUNITTEST_ASSERT_ERROR(rev2ColCopy.getMinorDim() == 5, {}, "gurobi", "twice reverse matrix copy");
79 OSIUNITTEST_ASSERT_ERROR(rev2ColCopy.getVectorLengths()[7] == 2, {}, "gurobi", "twice reverse matrix copy");
80 }
81
82 // Test copy constructor and assignment operator
83 {
84 OsiGrbSolverInterface lhs;
85 {
86 OsiGrbSolverInterface im(m);
87
88 OsiGrbSolverInterface imC1(im);
89 OSIUNITTEST_ASSERT_ERROR(imC1.lp_ != im.lp_, {}, "gurobi", "copy constructor");
90 OSIUNITTEST_ASSERT_ERROR(imC1.getNumCols() == im.getNumCols(), {}, "gurobi", "copy constructor");
91 OSIUNITTEST_ASSERT_ERROR(imC1.getNumRows() == im.getNumRows(), {}, "gurobi", "copy constructor");
92
93 OsiGrbSolverInterface imC2(im);
94 OSIUNITTEST_ASSERT_ERROR(imC2.lp_ != im.lp_, {}, "gurobi", "copy constructor");
95 OSIUNITTEST_ASSERT_ERROR(imC2.getNumCols() == im.getNumCols(), {}, "gurobi", "copy constructor");
96 OSIUNITTEST_ASSERT_ERROR(imC2.getNumRows() == im.getNumRows(), {}, "gurobi", "copy constructor");
97
98 OSIUNITTEST_ASSERT_ERROR(imC1.lp_ != imC2.lp_, {}, "gurobi", "copy constructor");
99
100 lhs = imC2;
101 }
102
103 // Test that lhs has correct values even though rhs has gone out of scope
104 OSIUNITTEST_ASSERT_ERROR(lhs.lp_ != m.lp_, {}, "gurobi", "assignment operator");
105 OSIUNITTEST_ASSERT_ERROR(lhs.getNumCols() == m.getNumCols(), {}, "gurobi", "copy constructor");
106 OSIUNITTEST_ASSERT_ERROR(lhs.getNumRows() == m.getNumRows(), {}, "gurobi", "copy constructor");
107 }
108
109 // Test clone
110 {
111 OsiGrbSolverInterface gurobiSi(m);
112 OsiSolverInterface * siPtr = &gurobiSi;
113 OsiSolverInterface * siClone = siPtr->clone();
114 OsiGrbSolverInterface * gurobiClone = dynamic_cast<OsiGrbSolverInterface*>(siClone);
115 OSIUNITTEST_ASSERT_ERROR(gurobiClone != NULL, {}, "gurobi", "clone");
116 OSIUNITTEST_ASSERT_ERROR(gurobiClone->lp_ != gurobiSi.lp_, {}, "gurobi", "clone");
117 OSIUNITTEST_ASSERT_ERROR(gurobiClone->getNumRows() == gurobiSi.getNumRows(), {}, "gurobi", "clone");
118 OSIUNITTEST_ASSERT_ERROR(gurobiClone->getNumCols() == m.getNumCols(), {}, "gurobi", "clone");
119
120 delete siClone;
121 }
122
123 // test infinity
124 {
125 OsiGrbSolverInterface si;
126 OSIUNITTEST_ASSERT_ERROR(si.getInfinity() == GRB_INFINITY, {}, "gurobi", "value for infinity");
127 }
128
129
130 {
131 OsiGrbSolverInterface gurobiSi(m);
132 int nc = gurobiSi.getNumCols();
133 int nr = gurobiSi.getNumRows();
134 const double * cl = gurobiSi.getColLower();
135 const double * cu = gurobiSi.getColUpper();
136 const double * rl = gurobiSi.getRowLower();
137 const double * ru = gurobiSi.getRowUpper();
138
139 OSIUNITTEST_ASSERT_ERROR(nc == 8, return, "gurobi", "read and copy exmip1");
140 OSIUNITTEST_ASSERT_ERROR(nr == 5, return, "gurobi", "read and copy exmip1");
141 OSIUNITTEST_ASSERT_ERROR(eq(cl[0],2.5), {}, "gurobi", "read and copy exmip1");
142 OSIUNITTEST_ASSERT_ERROR(eq(cl[1],0.0), {}, "gurobi", "read and copy exmip1");
143 OSIUNITTEST_ASSERT_ERROR(eq(cu[1],4.1), {}, "gurobi", "read and copy exmip1");
144 OSIUNITTEST_ASSERT_ERROR(eq(cu[2],1.0), {}, "gurobi", "read and copy exmip1");
145 OSIUNITTEST_ASSERT_ERROR(eq(rl[0],2.5), {}, "gurobi", "read and copy exmip1");
146 OSIUNITTEST_ASSERT_ERROR(eq(rl[4],3.0), {}, "gurobi", "read and copy exmip1");
147 OSIUNITTEST_ASSERT_ERROR(eq(ru[1],2.1), {}, "gurobi", "read and copy exmip1");
148 OSIUNITTEST_ASSERT_ERROR(eq(ru[4],15.), {}, "gurobi", "read and copy exmip1");
149
150 double newCs[8] = {1., 2., 3., 4., 5., 6., 7., 8.};
151 gurobiSi.setColSolution(newCs);
152 const double * cs = gurobiSi.getColSolution();
153 OSIUNITTEST_ASSERT_ERROR(eq(cs[0],1.0), {}, "gurobi", "set col solution");
154 OSIUNITTEST_ASSERT_ERROR(eq(cs[7],8.0), {}, "gurobi", "set col solution");
155 #if 0 // TODO set and copy of solutions not supported by OsiGrb currently
156 {
157 OsiGrbSolverInterface solnSi(gurobiSi);
158 const double * cs = solnSi.getColSolution();
159 OSIUNITTEST_ASSERT_ERROR(eq(cs[0],1.0), {}, "gurobi", "set col solution and copy");
160 OSIUNITTEST_ASSERT_ERROR(eq(cs[7],8.0), {}, "gurobi", "set col solution and copy");
161 }
162 #endif
163
164 OSIUNITTEST_ASSERT_ERROR(!eq(cl[3],1.2345), {}, "gurobi", "set col lower");
165 gurobiSi.setColLower( 3, 1.2345 );
166 OSIUNITTEST_ASSERT_ERROR( eq(cl[3],1.2345), {}, "gurobi", "set col lower");
167
168 OSIUNITTEST_ASSERT_ERROR(!eq(cu[4],10.2345), {}, "gurobi", "set col upper");
169 gurobiSi.setColUpper( 4, 10.2345 );
170 OSIUNITTEST_ASSERT_ERROR( eq(cu[4],10.2345), {}, "gurobi", "set col upper");
171
172 OSIUNITTEST_ASSERT_ERROR(eq(gurobiSi.getObjCoefficients()[0], 1.0), {}, "gurobi", "read and copy exmip1");
173 OSIUNITTEST_ASSERT_ERROR(eq(gurobiSi.getObjCoefficients()[1], 0.0), {}, "gurobi", "read and copy exmip1");
174 OSIUNITTEST_ASSERT_ERROR(eq(gurobiSi.getObjCoefficients()[2], 0.0), {}, "gurobi", "read and copy exmip1");
175 OSIUNITTEST_ASSERT_ERROR(eq(gurobiSi.getObjCoefficients()[3], 0.0), {}, "gurobi", "read and copy exmip1");
176 OSIUNITTEST_ASSERT_ERROR(eq(gurobiSi.getObjCoefficients()[4], 2.0), {}, "gurobi", "read and copy exmip1");
177 OSIUNITTEST_ASSERT_ERROR(eq(gurobiSi.getObjCoefficients()[5], 0.0), {}, "gurobi", "read and copy exmip1");
178 OSIUNITTEST_ASSERT_ERROR(eq(gurobiSi.getObjCoefficients()[6], 0.0), {}, "gurobi", "read and copy exmip1");
179 OSIUNITTEST_ASSERT_ERROR(eq(gurobiSi.getObjCoefficients()[7],-1.0), {}, "gurobi", "read and copy exmip1");
180 }
181
182 // Test getMatrixByRow method
183 {
184 const OsiGrbSolverInterface si(m);
185 const CoinPackedMatrix * smP = si.getMatrixByRow();
186
187 OSIUNITTEST_ASSERT_ERROR(smP->getMajorDim() == 5, return, "gurobi", "getMatrixByRow: major dim");
188 OSIUNITTEST_ASSERT_ERROR(smP->getNumElements() == 14, return, "gurobi", "getMatrixByRow: num elements");
189
190 CoinRelFltEq eq;
191 const double * ev = smP->getElements();
192 OSIUNITTEST_ASSERT_ERROR(eq(ev[0], 3.0), {}, "gurobi", "getMatrixByRow: elements");
193 OSIUNITTEST_ASSERT_ERROR(eq(ev[1], 1.0), {}, "gurobi", "getMatrixByRow: elements");
194 OSIUNITTEST_ASSERT_ERROR(eq(ev[2], -2.0), {}, "gurobi", "getMatrixByRow: elements");
195 OSIUNITTEST_ASSERT_ERROR(eq(ev[3], -1.0), {}, "gurobi", "getMatrixByRow: elements");
196 OSIUNITTEST_ASSERT_ERROR(eq(ev[4], -1.0), {}, "gurobi", "getMatrixByRow: elements");
197 OSIUNITTEST_ASSERT_ERROR(eq(ev[5], 2.0), {}, "gurobi", "getMatrixByRow: elements");
198 OSIUNITTEST_ASSERT_ERROR(eq(ev[6], 1.1), {}, "gurobi", "getMatrixByRow: elements");
199 OSIUNITTEST_ASSERT_ERROR(eq(ev[7], 1.0), {}, "gurobi", "getMatrixByRow: elements");
200 OSIUNITTEST_ASSERT_ERROR(eq(ev[8], 1.0), {}, "gurobi", "getMatrixByRow: elements");
201 OSIUNITTEST_ASSERT_ERROR(eq(ev[9], 2.8), {}, "gurobi", "getMatrixByRow: elements");
202 OSIUNITTEST_ASSERT_ERROR(eq(ev[10], -1.2), {}, "gurobi", "getMatrixByRow: elements");
203 OSIUNITTEST_ASSERT_ERROR(eq(ev[11], 5.6), {}, "gurobi", "getMatrixByRow: elements");
204 OSIUNITTEST_ASSERT_ERROR(eq(ev[12], 1.0), {}, "gurobi", "getMatrixByRow: elements");
205 OSIUNITTEST_ASSERT_ERROR(eq(ev[13], 1.9), {}, "gurobi", "getMatrixByRow: elements");
206
207 const int * mi = smP->getVectorStarts();
208 OSIUNITTEST_ASSERT_ERROR(mi[0] == 0, {}, "gurobi", "getMatrixByRow: vector starts");
209 OSIUNITTEST_ASSERT_ERROR(mi[1] == 5, {}, "gurobi", "getMatrixByRow: vector starts");
210 OSIUNITTEST_ASSERT_ERROR(mi[2] == 7, {}, "gurobi", "getMatrixByRow: vector starts");
211 OSIUNITTEST_ASSERT_ERROR(mi[3] == 9, {}, "gurobi", "getMatrixByRow: vector starts");
212 OSIUNITTEST_ASSERT_ERROR(mi[4] == 11, {}, "gurobi", "getMatrixByRow: vector starts");
213 OSIUNITTEST_ASSERT_ERROR(mi[5] == 14, {}, "gurobi", "getMatrixByRow: vector starts");
214
215 const int * ei = smP->getIndices();
216 OSIUNITTEST_ASSERT_ERROR(ei[ 0] == 0, {}, "gurobi", "getMatrixByRow: indices");
217 OSIUNITTEST_ASSERT_ERROR(ei[ 1] == 1, {}, "gurobi", "getMatrixByRow: indices");
218 OSIUNITTEST_ASSERT_ERROR(ei[ 2] == 3, {}, "gurobi", "getMatrixByRow: indices");
219 OSIUNITTEST_ASSERT_ERROR(ei[ 3] == 4, {}, "gurobi", "getMatrixByRow: indices");
220 OSIUNITTEST_ASSERT_ERROR(ei[ 4] == 7, {}, "gurobi", "getMatrixByRow: indices");
221 OSIUNITTEST_ASSERT_ERROR(ei[ 5] == 1, {}, "gurobi", "getMatrixByRow: indices");
222 OSIUNITTEST_ASSERT_ERROR(ei[ 6] == 2, {}, "gurobi", "getMatrixByRow: indices");
223 OSIUNITTEST_ASSERT_ERROR(ei[ 7] == 2, {}, "gurobi", "getMatrixByRow: indices");
224 OSIUNITTEST_ASSERT_ERROR(ei[ 8] == 5, {}, "gurobi", "getMatrixByRow: indices");
225 OSIUNITTEST_ASSERT_ERROR(ei[ 9] == 3, {}, "gurobi", "getMatrixByRow: indices");
226 OSIUNITTEST_ASSERT_ERROR(ei[10] == 6, {}, "gurobi", "getMatrixByRow: indices");
227 OSIUNITTEST_ASSERT_ERROR(ei[11] == 0, {}, "gurobi", "getMatrixByRow: indices");
228 OSIUNITTEST_ASSERT_ERROR(ei[12] == 4, {}, "gurobi", "getMatrixByRow: indices");
229 OSIUNITTEST_ASSERT_ERROR(ei[13] == 7, {}, "gurobi", "getMatrixByRow: indices");
230 }
231 //--------------
232 // Test rowsense, rhs, rowrange, getMatrixByRow
233 {
234 OsiGrbSolverInterface lhs;
235 {
236 OsiGrbSolverInterface siC1(m);
237 OSIUNITTEST_ASSERT_WARNING(siC1.obj_ == NULL, {}, "gurobi", "objective");
238 OSIUNITTEST_ASSERT_WARNING(siC1.collower_ == NULL, {}, "gurobi", "col lower");
239 OSIUNITTEST_ASSERT_WARNING(siC1.colupper_ == NULL, {}, "gurobi", "col upper");
240 OSIUNITTEST_ASSERT_WARNING(siC1.rowrange_ == NULL, {}, "gurobi", "row range");
241 OSIUNITTEST_ASSERT_WARNING(siC1.rowsense_ == NULL, {}, "gurobi", "row sense");
242 OSIUNITTEST_ASSERT_WARNING(siC1.rowlower_ == NULL, {}, "gurobi", "row lower");
243 OSIUNITTEST_ASSERT_WARNING(siC1.rowupper_ == NULL, {}, "gurobi", "row upper");
244 OSIUNITTEST_ASSERT_WARNING(siC1.rhs_ == NULL, {}, "gurobi", "right hand side");
245 OSIUNITTEST_ASSERT_WARNING(siC1.matrixByRow_ == NULL, {}, "gurobi", "matrix by row");
246 //TODO OSIUNITTEST_ASSERT_WARNING(siC1.colsol_ != NULL, {}, "gurobi", "col solution");
247 //TODO OSIUNITTEST_ASSERT_WARNING(siC1.rowsol_ != NULL, {}, "gurobi", "row solution");
248
249 const char * siC1rs = siC1.getRowSense();
250 OSIUNITTEST_ASSERT_ERROR(siC1rs[0] == 'G', {}, "gurobi", "row sense");
251 OSIUNITTEST_ASSERT_ERROR(siC1rs[1] == 'L', {}, "gurobi", "row sense");
252 OSIUNITTEST_ASSERT_ERROR(siC1rs[2] == 'E', {}, "gurobi", "row sense");
253 OSIUNITTEST_ASSERT_ERROR(siC1rs[3] == 'R', {}, "gurobi", "row sense");
254 OSIUNITTEST_ASSERT_ERROR(siC1rs[4] == 'R', {}, "gurobi", "row sense");
255
256 const double * siC1rhs = siC1.getRightHandSide();
257 OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[0],2.5), {}, "gurobi", "right hand side");
258 OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[1],2.1), {}, "gurobi", "right hand side");
259 OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[2],4.0), {}, "gurobi", "right hand side");
260 OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[3],5.0), {}, "gurobi", "right hand side");
261 OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[4],15.), {}, "gurobi", "right hand side");
262
263 const double * siC1rr = siC1.getRowRange();
264 OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[0],0.0), {}, "gurobi", "row range");
265 OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[1],0.0), {}, "gurobi", "row range");
266 OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[2],0.0), {}, "gurobi", "row range");
267 OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[3],5.0-1.8), {}, "gurobi", "row range");
268 OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[4],15.0-3.0), {}, "gurobi", "row range");
269
270 const CoinPackedMatrix * siC1mbr = siC1.getMatrixByRow();
271 OSIUNITTEST_ASSERT_ERROR(siC1mbr != NULL, {}, "gurobi", "matrix by row");
272 OSIUNITTEST_ASSERT_ERROR(siC1mbr->getMajorDim() == 5, return, "gurobi", "matrix by row: major dim");
273 OSIUNITTEST_ASSERT_ERROR(siC1mbr->getNumElements() == 14, return, "gurobi", "matrix by row: num elements");
274
275 const double * ev = siC1mbr->getElements();
276 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 0], 3.0), {}, "gurobi", "matrix by row: elements");
277 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 1], 1.0), {}, "gurobi", "matrix by row: elements");
278 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 2],-2.0), {}, "gurobi", "matrix by row: elements");
279 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 3],-1.0), {}, "gurobi", "matrix by row: elements");
280 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 4],-1.0), {}, "gurobi", "matrix by row: elements");
281 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 5], 2.0), {}, "gurobi", "matrix by row: elements");
282 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 6], 1.1), {}, "gurobi", "matrix by row: elements");
283 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 7], 1.0), {}, "gurobi", "matrix by row: elements");
284 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 8], 1.0), {}, "gurobi", "matrix by row: elements");
285 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 9], 2.8), {}, "gurobi", "matrix by row: elements");
286 OSIUNITTEST_ASSERT_ERROR(eq(ev[10],-1.2), {}, "gurobi", "matrix by row: elements");
287 OSIUNITTEST_ASSERT_ERROR(eq(ev[11], 5.6), {}, "gurobi", "matrix by row: elements");
288 OSIUNITTEST_ASSERT_ERROR(eq(ev[12], 1.0), {}, "gurobi", "matrix by row: elements");
289 OSIUNITTEST_ASSERT_ERROR(eq(ev[13], 1.9), {}, "gurobi", "matrix by row: elements");
290
291 const CoinBigIndex * mi = siC1mbr->getVectorStarts();
292 OSIUNITTEST_ASSERT_ERROR(mi[0] == 0, {}, "gurobi", "matrix by row: vector starts");
293 OSIUNITTEST_ASSERT_ERROR(mi[1] == 5, {}, "gurobi", "matrix by row: vector starts");
294 OSIUNITTEST_ASSERT_ERROR(mi[2] == 7, {}, "gurobi", "matrix by row: vector starts");
295 OSIUNITTEST_ASSERT_ERROR(mi[3] == 9, {}, "gurobi", "matrix by row: vector starts");
296 OSIUNITTEST_ASSERT_ERROR(mi[4] == 11, {}, "gurobi", "matrix by row: vector starts");
297 OSIUNITTEST_ASSERT_ERROR(mi[5] == 14, {}, "gurobi", "matrix by row: vector starts");
298
299 const int * ei = siC1mbr->getIndices();
300 OSIUNITTEST_ASSERT_ERROR(ei[ 0] == 0, {}, "gurobi", "matrix by row: indices");
301 OSIUNITTEST_ASSERT_ERROR(ei[ 1] == 1, {}, "gurobi", "matrix by row: indices");
302 OSIUNITTEST_ASSERT_ERROR(ei[ 2] == 3, {}, "gurobi", "matrix by row: indices");
303 OSIUNITTEST_ASSERT_ERROR(ei[ 3] == 4, {}, "gurobi", "matrix by row: indices");
304 OSIUNITTEST_ASSERT_ERROR(ei[ 4] == 7, {}, "gurobi", "matrix by row: indices");
305 OSIUNITTEST_ASSERT_ERROR(ei[ 5] == 1, {}, "gurobi", "matrix by row: indices");
306 OSIUNITTEST_ASSERT_ERROR(ei[ 6] == 2, {}, "gurobi", "matrix by row: indices");
307 OSIUNITTEST_ASSERT_ERROR(ei[ 7] == 2, {}, "gurobi", "matrix by row: indices");
308 OSIUNITTEST_ASSERT_ERROR(ei[ 8] == 5, {}, "gurobi", "matrix by row: indices");
309 OSIUNITTEST_ASSERT_ERROR(ei[ 9] == 3, {}, "gurobi", "matrix by row: indices");
310 OSIUNITTEST_ASSERT_ERROR(ei[10] == 6, {}, "gurobi", "matrix by row: indices");
311 OSIUNITTEST_ASSERT_ERROR(ei[11] == 0, {}, "gurobi", "matrix by row: indices");
312 OSIUNITTEST_ASSERT_ERROR(ei[12] == 4, {}, "gurobi", "matrix by row: indices");
313 OSIUNITTEST_ASSERT_ERROR(ei[13] == 7, {}, "gurobi", "matrix by row: indices");
314
315 OSIUNITTEST_ASSERT_WARNING(siC1rs == siC1.getRowSense(), {}, "gurobi", "row sense");
316 OSIUNITTEST_ASSERT_WARNING(siC1rhs == siC1.getRightHandSide(), {}, "gurobi", "right hand side");
317 OSIUNITTEST_ASSERT_WARNING(siC1rr == siC1.getRowRange(), {}, "gurobi", "row range");
318
319 #if 0 // TODO: free rows not really supported by OsiGrb
320 // Change GUROBI Model by adding free row
321 OsiRowCut rc;
322 rc.setLb(-COIN_DBL_MAX);
323 rc.setUb( COIN_DBL_MAX);
324 OsiCuts cuts;
325 cuts.insert(rc);
326 siC1.applyCuts(cuts);
327
328 // Since model was changed, test that cached data is now freed.
329 OSIUNITTEST_ASSERT_ERROR(siC1.obj_ == NULL, {}, "gurobi", "objective");
330 OSIUNITTEST_ASSERT_ERROR(siC1.collower_ == NULL, {}, "gurobi", "col lower");
331 OSIUNITTEST_ASSERT_ERROR(siC1.colupper_ == NULL, {}, "gurobi", "col upper");
332 OSIUNITTEST_ASSERT_ERROR(siC1.rowrange_ == NULL, {}, "gurobi", "free cached data after adding row");
333 OSIUNITTEST_ASSERT_ERROR(siC1.rowsense_ == NULL, {}, "gurobi", "free cached data after adding row");
334 OSIUNITTEST_ASSERT_ERROR(siC1.rowlower_ == NULL, {}, "gurobi", "row lower");
335 OSIUNITTEST_ASSERT_ERROR(siC1.rowupper_ == NULL, {}, "gurobi", "row upper");
336 OSIUNITTEST_ASSERT_ERROR(siC1.rhs_ == NULL, {}, "gurobi", "free cached data after adding row");
337 OSIUNITTEST_ASSERT_ERROR(siC1.matrixByRow_ == NULL, {}, "gurobi", "free cached data after adding row");
338 OSIUNITTEST_ASSERT_ERROR(siC1.matrixByCol_ == NULL, {}, "gurobi", "free cached data after adding row");
339 OSIUNITTEST_ASSERT_ERROR(siC1.colsol_ == NULL, {}, "gurobi", "free cached data after adding row");
340 OSIUNITTEST_ASSERT_ERROR(siC1.rowsol_ == NULL, {}, "gurobi", "free cached data after adding row");
341
342 siC1rs = siC1.getRowSense();
343 OSIUNITTEST_ASSERT_ERROR(siC1rs[0] == 'G', {}, "gurobi", "row sense after adding row");
344 OSIUNITTEST_ASSERT_ERROR(siC1rs[1] == 'L', {}, "gurobi", "row sense after adding row");
345 OSIUNITTEST_ASSERT_ERROR(siC1rs[2] == 'E', {}, "gurobi", "row sense after adding row");
346 OSIUNITTEST_ASSERT_ERROR(siC1rs[3] == 'R', {}, "gurobi", "row sense after adding row");
347 OSIUNITTEST_ASSERT_ERROR(siC1rs[4] == 'R', {}, "gurobi", "row sense after adding row");
348 OSIUNITTEST_ASSERT_ERROR(siC1rs[5] == 'N', {}, "gurobi", "row sense after adding row");
349
350 siC1rhs = siC1.getRightHandSide();
351 OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[0],2.5), {}, "gurobi", "right hand side after adding row");
352 OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[1],2.1), {}, "gurobi", "right hand side after adding row");
353 OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[2],4.0), {}, "gurobi", "right hand side after adding row");
354 OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[3],5.0), {}, "gurobi", "right hand side after adding row");
355 OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[4],15.), {}, "gurobi", "right hand side after adding row");
356 OSIUNITTEST_ASSERT_ERROR(eq(siC1rhs[5],0.0), {}, "gurobi", "right hand side after adding row");
357
358 siC1rr = siC1.getRowRange();
359 OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[0],0.0), {}, "gurobi", "row range after adding row");
360 OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[1],0.0), {}, "gurobi", "row range after adding row");
361 OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[2],0.0), {}, "gurobi", "row range after adding row");
362 OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[3],5.0-1.8), {}, "gurobi", "row range after adding row");
363 OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[4],15.0-3.0), {}, "gurobi", "row range after adding row");
364 OSIUNITTEST_ASSERT_ERROR(eq(siC1rr[5],0.0), {}, "gurobi", "row range after adding row");
365 #endif
366 lhs = siC1;
367 }
368 // Test that lhs has correct values even though siC1 has gone out of scope
369 OSIUNITTEST_ASSERT_ERROR(lhs.obj_ == NULL, {}, "gurobi", "freed origin after assignment");
370 OSIUNITTEST_ASSERT_ERROR(lhs.collower_ == NULL, {}, "gurobi", "freed origin after assignment");
371 OSIUNITTEST_ASSERT_ERROR(lhs.colupper_ == NULL, {}, "gurobi", "freed origin after assignment");
372 OSIUNITTEST_ASSERT_ERROR(lhs.rowrange_ == NULL, {}, "gurobi", "freed origin after assignment");
373 OSIUNITTEST_ASSERT_ERROR(lhs.rowsense_ == NULL, {}, "gurobi", "freed origin after assignment");
374 OSIUNITTEST_ASSERT_ERROR(lhs.rowlower_ == NULL, {}, "gurobi", "freed origin after assignment");
375 OSIUNITTEST_ASSERT_ERROR(lhs.rowupper_ == NULL, {}, "gurobi", "freed origin after assignment");
376 OSIUNITTEST_ASSERT_ERROR(lhs.rhs_ == NULL, {}, "gurobi", "freed origin after assignment");
377 OSIUNITTEST_ASSERT_ERROR(lhs.matrixByRow_ == NULL, {}, "gurobi", "freed origin after assignment");
378 OSIUNITTEST_ASSERT_ERROR(lhs.matrixByCol_ == NULL, {}, "gurobi", "freed origin after assignment");
379 //TODO OSIUNITTEST_ASSERT_ERROR(lhs.colsol_ != NULL, {}, "gurobi", "freed origin after assignment");
380 //TODO OSIUNITTEST_ASSERT_ERROR(lhs.rowsol_ != NULL, {}, "gurobi", "freed origin after assignment");
381
382 #if 0 // TODO: free rows not really supported by OsiGrb
383 const char * lhsrs = lhs.getRowSense();
384 OSIUNITTEST_ASSERT_ERROR(lhsrs[0] == 'G', {}, "gurobi", "row sense after assignment");
385 OSIUNITTEST_ASSERT_ERROR(lhsrs[1] == 'L', {}, "gurobi", "row sense after assignment");
386 OSIUNITTEST_ASSERT_ERROR(lhsrs[2] == 'E', {}, "gurobi", "row sense after assignment");
387 OSIUNITTEST_ASSERT_ERROR(lhsrs[3] == 'R', {}, "gurobi", "row sense after assignment");
388 OSIUNITTEST_ASSERT_ERROR(lhsrs[4] == 'R', {}, "gurobi", "row sense after assignment");
389 OSIUNITTEST_ASSERT_ERROR(lhsrs[5] == 'N', {}, "gurobi", "row sense after assignment");
390
391 const double * lhsrhs = lhs.getRightHandSide();
392 OSIUNITTEST_ASSERT_ERROR(eq(lhsrhs[0],2.5), {}, "gurobi", "right hand side after assignment");
393 OSIUNITTEST_ASSERT_ERROR(eq(lhsrhs[1],2.1), {}, "gurobi", "right hand side after assignment");
394 OSIUNITTEST_ASSERT_ERROR(eq(lhsrhs[2],4.0), {}, "gurobi", "right hand side after assignment");
395 OSIUNITTEST_ASSERT_ERROR(eq(lhsrhs[3],5.0), {}, "gurobi", "right hand side after assignment");
396 OSIUNITTEST_ASSERT_ERROR(eq(lhsrhs[4],15.), {}, "gurobi", "right hand side after assignment");
397 OSIUNITTEST_ASSERT_ERROR(eq(lhsrhs[5],0.0), {}, "gurobi", "right hand side after assignment");
398
399 const double *lhsrr = lhs.getRowRange();
400 OSIUNITTEST_ASSERT_ERROR(eq(lhsrr[0],0.0), {}, "gurobi", "row range after assignment");
401 OSIUNITTEST_ASSERT_ERROR(eq(lhsrr[1],0.0), {}, "gurobi", "row range after assignment");
402 OSIUNITTEST_ASSERT_ERROR(eq(lhsrr[2],0.0), {}, "gurobi", "row range after assignment");
403 OSIUNITTEST_ASSERT_ERROR(eq(lhsrr[3],5.0-1.8), {}, "gurobi", "row range after assignment");
404 OSIUNITTEST_ASSERT_ERROR(eq(lhsrr[4],15.0-3.0), {}, "gurobi", "row range after assignment");
405 OSIUNITTEST_ASSERT_ERROR(eq(lhsrr[5],0.0), {}, "gurobi", "row range after assignment");
406
407 const CoinPackedMatrix * lhsmbr = lhs.getMatrixByRow();
408 OSIUNITTEST_ASSERT_ERROR(lhsmbr != NULL, {}, "gurobi", "matrix by row after assignment");
409 OSIUNITTEST_ASSERT_ERROR(lhsmbr->getMajorDim() == 6, return, "gurobi", "matrix by row after assignment: major dim");
410 OSIUNITTEST_ASSERT_ERROR(lhsmbr->getNumElements() == 14, return, "gurobi", "matrix by row after assignment: num elements");
411
412 const double * ev = lhsmbr->getElements();
413 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 0], 3.0), {}, "gurobi", "matrix by row after assignment: elements");
414 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 1], 1.0), {}, "gurobi", "matrix by row after assignment: elements");
415 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 2],-2.0), {}, "gurobi", "matrix by row after assignment: elements");
416 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 3],-1.0), {}, "gurobi", "matrix by row after assignment: elements");
417 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 4],-1.0), {}, "gurobi", "matrix by row after assignment: elements");
418 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 5], 2.0), {}, "gurobi", "matrix by row after assignment: elements");
419 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 6], 1.1), {}, "gurobi", "matrix by row after assignment: elements");
420 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 7], 1.0), {}, "gurobi", "matrix by row after assignment: elements");
421 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 8], 1.0), {}, "gurobi", "matrix by row after assignment: elements");
422 OSIUNITTEST_ASSERT_ERROR(eq(ev[ 9], 2.8), {}, "gurobi", "matrix by row after assignment: elements");
423 OSIUNITTEST_ASSERT_ERROR(eq(ev[10],-1.2), {}, "gurobi", "matrix by row after assignment: elements");
424 OSIUNITTEST_ASSERT_ERROR(eq(ev[11], 5.6), {}, "gurobi", "matrix by row after assignment: elements");
425 OSIUNITTEST_ASSERT_ERROR(eq(ev[12], 1.0), {}, "gurobi", "matrix by row after assignment: elements");
426 OSIUNITTEST_ASSERT_ERROR(eq(ev[13], 1.9), {}, "gurobi", "matrix by row after assignment: elements");
427
428 const CoinBigIndex * mi = lhsmbr->getVectorStarts();
429 OSIUNITTEST_ASSERT_ERROR(mi[0] == 0, {}, "gurobi", "matrix by row after assignment: vector starts");
430 OSIUNITTEST_ASSERT_ERROR(mi[1] == 5, {}, "gurobi", "matrix by row after assignment: vector starts");
431 OSIUNITTEST_ASSERT_ERROR(mi[2] == 7, {}, "gurobi", "matrix by row after assignment: vector starts");
432 OSIUNITTEST_ASSERT_ERROR(mi[3] == 9, {}, "gurobi", "matrix by row after assignment: vector starts");
433 OSIUNITTEST_ASSERT_ERROR(mi[4] == 11, {}, "gurobi", "matrix by row after assignment: vector starts");
434 OSIUNITTEST_ASSERT_ERROR(mi[5] == 14, {}, "gurobi", "matrix by row after assignment: vector starts");
435
436 const int * ei = lhsmbr->getIndices();
437 OSIUNITTEST_ASSERT_ERROR(ei[ 0] == 0, {}, "gurobi", "matrix by row after assignment: indices");
438 OSIUNITTEST_ASSERT_ERROR(ei[ 1] == 1, {}, "gurobi", "matrix by row after assignment: indices");
439 OSIUNITTEST_ASSERT_ERROR(ei[ 2] == 3, {}, "gurobi", "matrix by row after assignment: indices");
440 OSIUNITTEST_ASSERT_ERROR(ei[ 3] == 4, {}, "gurobi", "matrix by row after assignment: indices");
441 OSIUNITTEST_ASSERT_ERROR(ei[ 4] == 7, {}, "gurobi", "matrix by row after assignment: indices");
442 OSIUNITTEST_ASSERT_ERROR(ei[ 5] == 1, {}, "gurobi", "matrix by row after assignment: indices");
443 OSIUNITTEST_ASSERT_ERROR(ei[ 6] == 2, {}, "gurobi", "matrix by row after assignment: indices");
444 OSIUNITTEST_ASSERT_ERROR(ei[ 7] == 2, {}, "gurobi", "matrix by row after assignment: indices");
445 OSIUNITTEST_ASSERT_ERROR(ei[ 8] == 5, {}, "gurobi", "matrix by row after assignment: indices");
446 OSIUNITTEST_ASSERT_ERROR(ei[ 9] == 3, {}, "gurobi", "matrix by row after assignment: indices");
447 OSIUNITTEST_ASSERT_ERROR(ei[10] == 6, {}, "gurobi", "matrix by row after assignment: indices");
448 OSIUNITTEST_ASSERT_ERROR(ei[11] == 0, {}, "gurobi", "matrix by row after assignment: indices");
449 OSIUNITTEST_ASSERT_ERROR(ei[12] == 4, {}, "gurobi", "matrix by row after assignment: indices");
450 OSIUNITTEST_ASSERT_ERROR(ei[13] == 7, {}, "gurobi", "matrix by row after assignment: indices");
451 #endif
452 }
453 }
454
455 // Do common solverInterface testing by calling the
456 // base class testing method.
457 {
458 OsiGrbSolverInterface m;
459 OsiSolverInterfaceCommonUnitTest(&m, mpsDir, netlibDir);
460 }
461 }
462 #endif
463