# source:trunk/Cbc/test/OsiCbcSolverInterfaceTest.cpp@1796

Last change on this file since 1796 was 1667, checked in by stefan, 10 years ago

remove now redundant counting of test failures; a bit more cleanup

File size: 39.2 KB
Line
1// \$Id\$
2// Copyright (C) 2005, International Business Machines
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
23namespace {
24CoinPackedMatrix &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.
58void OsiCbcSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir)
59{
60  {
61    CoinRelFltEq eq;
62    OsiCbcSolverInterface m;
63    std::string fn = mpsDir+"exmip1";
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";
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";
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";
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";
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;
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];
716                     rowLower[iRow],rowUpper[iRow]);
717      } else {
718        // As we have to add one by one let's get from saveBuild
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";
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";
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}
Note: See TracBrowser for help on using the repository browser.