source: trunk/Cbc/test/OsiCbcSolverInterfaceTest.cpp @ 1666

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

use new osi unittest macros and functions in osicbc test

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