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

Last change on this file since 1464 was 1464, checked in by stefan, 9 years ago

merge split branch into trunk; fix some examples

File size: 31.8 KB
Line 
1// Copyright (C) 2005, International Business Machines
2// Corporation and others.  All Rights Reserved.
3
4#if defined(_MSC_VER)
5// Turn off compiler warning about long names
6#  pragma warning(disable:4786)
7#endif
8
9#ifdef NDEBUG
10#undef NDEBUG
11#endif
12
13#include "OsiConfig.h"
14
15#include <cassert>
16//#include <cstdlib>
17//#include <cstdio>
18//#include <iostream>
19
20#include "OsiCbcSolverInterface.hpp"
21#include "OsiCuts.hpp"
22#include "OsiRowCut.hpp"
23#include "OsiColCut.hpp"
24#include "CoinMessage.hpp"
25#include "CoinModel.hpp"
26#ifdef COIN_HAS_OSL
27#include "OsiOslSolverInterface.hpp"
28#endif
29
30//#############################################################################
31
32namespace {
33CoinPackedMatrix &BuildExmip1Mtx ()
34/*
35  Simple function to build a packed matrix for the exmip1 example used in
36  tests. The function exists solely to hide the intermediate variables.
37  Probably could be written as an initialised declaration.
38  See COIN/Mps/Sample/exmip1.mps for a human-readable presentation.
39
40  Ordered triples seem easiest. They're listed in row-major order.
41*/
42
43{ int rowndxs[] = { 0, 0, 0, 0, 0,
44                    1, 1,
45                    2, 2,
46                    3, 3,
47                    4, 4, 4 } ;
48  int colndxs[] = { 0, 1, 3, 4, 7,
49                    1, 2,
50                    2, 5,
51                    3, 6,
52                    0, 4, 7 } ;
53  double coeffs[] = { 3.0, 1.0, -2.0, -1.0, -1.0,
54                      2.0, 1.1,
55                      1.0, 1.0,
56                      2.8, -1.2,
57                      5.6, 1.0, 1.9 } ;
58
59  static CoinPackedMatrix exmip1mtx =
60    CoinPackedMatrix(true,&rowndxs[0],&colndxs[0],&coeffs[0],14) ;
61
62  return (exmip1mtx) ; }
63}
64
65//--------------------------------------------------------------------------
66// test solution methods.
67int
68OsiCbcSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir)
69{
70 
71 
72  {   
73    CoinRelFltEq eq;
74    OsiCbcSolverInterface m;
75    std::string fn = mpsDir+"exmip1";
76    m.readMps(fn.c_str(),"mps");
77
78    {
79      OsiCbcSolverInterface im;   
80     
81      assert( im.getNumCols() == 0 ); 
82     
83      assert( im.getModelPtr()!=NULL );
84    }
85   
86    // Test copy constructor and assignment operator
87    {
88      OsiCbcSolverInterface lhs;
89      {     
90        OsiCbcSolverInterface im(m);       
91       
92        OsiCbcSolverInterface imC1(im);
93        assert( imC1.getModelPtr()!=im.getModelPtr() );
94        assert( imC1.getNumCols() == im.getNumCols() );
95        assert( imC1.getNumRows() == im.getNumRows() );   
96       
97        OsiCbcSolverInterface imC2(im);
98        assert( imC2.getModelPtr()!=im.getModelPtr() );
99        assert( imC2.getNumCols() == im.getNumCols() );
100        assert( imC2.getNumRows() == im.getNumRows() ); 
101       
102        assert( imC2.getModelPtr()!=imC1.getModelPtr() );
103       
104        lhs=imC2;
105      }
106      // Test that lhs has correct values even though rhs has gone out of scope
107     
108      assert( lhs.getModelPtr() != m.getModelPtr() );
109      assert( lhs.getNumCols() == m.getNumCols() );
110      assert( lhs.getNumRows() == m.getNumRows() );     
111    }
112    // Test clone
113    {
114      OsiCbcSolverInterface oslSi(m);
115      OsiSolverInterface * siPtr = &oslSi;
116      OsiSolverInterface * siClone = siPtr->clone();
117      OsiCbcSolverInterface * oslClone = dynamic_cast<OsiCbcSolverInterface*>(siClone);
118      assert( oslClone != NULL );
119      assert( oslClone->getModelPtr() != oslSi.getModelPtr() );
120      assert( oslClone->getNumRows() == oslSi.getNumRows() );
121      assert( oslClone->getNumCols() == m.getNumCols() );
122     
123      delete siClone;
124    }
125 
126    // test infinity
127    {
128      OsiCbcSolverInterface si;
129      assert( eq(si.getInfinity(),OsiCbcInfinity));
130    }     
131   
132    // Test setting solution
133    {
134      OsiCbcSolverInterface m1(m);
135      int i;
136
137      double * cs = new double[m1.getNumCols()];
138      for ( i = 0;  i < m1.getNumCols();  i++ ) 
139        cs[i] = i + .5;
140      m1.setColSolution(cs);
141      for ( i = 0;  i < m1.getNumCols();  i++ ) 
142        assert(m1.getColSolution()[i] == i + .5);
143     
144      double * rs = new double[m1.getNumRows()];
145      for ( i = 0;  i < m1.getNumRows();  i++ ) 
146        rs[i] = i - .5;
147      m1.setRowPrice(rs);
148      for ( i = 0;  i < m1.getNumRows();  i++ ) 
149        assert(m1.getRowPrice()[i] == i - .5);
150
151      delete [] cs;
152      delete [] rs;
153    }
154   
155   
156    // Test fraction Indices
157    {
158      OsiCbcSolverInterface fim;
159      std::string fn = mpsDir+"exmip1";
160      fim.readMps(fn.c_str(),"mps");
161      // exmip1.mps has 2 integer variables with index 2 & 3
162      assert(  fim.isContinuous(0) );
163      assert(  fim.isContinuous(1) );
164      assert( !fim.isContinuous(2) );
165      assert( !fim.isContinuous(3) );
166      assert(  fim.isContinuous(4) );
167     
168      assert( !fim.isInteger(0) );
169      assert( !fim.isInteger(1) );
170      assert(  fim.isInteger(2) );
171      assert(  fim.isInteger(3) );
172      assert( !fim.isInteger(4) );
173     
174      assert( !fim.isBinary(0) );
175      assert( !fim.isBinary(1) );
176      assert(  fim.isBinary(2) );
177      assert(  fim.isBinary(3) );
178      assert( !fim.isBinary(4) );
179     
180      assert( !fim.isIntegerNonBinary(0) );
181      assert( !fim.isIntegerNonBinary(1) );
182      assert( !fim.isIntegerNonBinary(2) );
183      assert( !fim.isIntegerNonBinary(3) );
184      assert( !fim.isIntegerNonBinary(4) );
185
186    }
187    // Test some catches
188      if (!OsiCbcHasNDEBUG())
189    { bool thrown ;
190
191      thrown = false ;
192      OsiCbcSolverInterface solver;
193      try {
194        solver.setObjCoeff(0,0.0);
195      }
196      catch (CoinError e) {
197        std::cout<<"Correct throw"<<std::endl;
198        thrown = true ;
199      }
200      assert( thrown == true ) ;
201
202      std::string fn = mpsDir+"exmip1";
203      solver.readMps(fn.c_str(),"mps");
204      try {
205        solver.setObjCoeff(0,0.0);
206      }
207      catch (CoinError e) {
208        std::cout<<"** Incorrect throw"<<std::endl;
209        abort();
210      }
211
212      thrown = false ;
213      try {
214        int index[]={0,20};
215        double value[]={0.0,0.0,0.0,0.0};
216        solver.setColSetBounds(index,index+2,value);
217      }
218      catch (CoinError e) {
219        std::cout<<"Correct throw"<<std::endl;
220        thrown = true ;
221      }
222      assert( thrown == true ) ;
223    }
224    // Test apply cuts method
225    {     
226      OsiCbcSolverInterface im(m);
227      OsiCuts cuts;
228     
229      // Generate some cuts
230      {
231        // Get number of rows and columns in model
232        int nr=im.getNumRows();
233        int nc=im.getNumCols();
234        assert( nr == 5 );
235        assert( nc == 8 );
236       
237        // Generate a valid row cut from thin air
238        int c;
239        {
240          int *inx = new int[nc];
241          for (c=0;c<nc;c++) inx[c]=c;
242          double *el = new double[nc];
243          for (c=0;c<nc;c++) el[c]=((double)c)*((double)c);
244         
245          OsiRowCut rc;
246          rc.setRow(nc,inx,el);
247          rc.setLb(-100.);
248          rc.setUb(100.);
249          rc.setEffectiveness(22);
250         
251          cuts.insert(rc);
252          delete[]el;
253          delete[]inx;
254        }
255       
256        // Generate valid col cut from thin air
257        {
258          const double * oslColLB = im.getColLower();
259          const double * oslColUB = im.getColUpper();
260          int *inx = new int[nc];
261          for (c=0;c<nc;c++) inx[c]=c;
262          double *lb = new double[nc];
263          double *ub = new double[nc];
264          for (c=0;c<nc;c++) lb[c]=oslColLB[c]+0.001;
265          for (c=0;c<nc;c++) ub[c]=oslColUB[c]-0.001;
266         
267          OsiColCut cc;
268          cc.setLbs(nc,inx,lb);
269          cc.setUbs(nc,inx,ub);
270         
271          cuts.insert(cc);
272          delete [] ub;
273          delete [] lb;
274          delete [] inx;
275        }
276       
277        {
278          // Generate a row and column cut which are ineffective
279          OsiRowCut * rcP= new OsiRowCut;
280          rcP->setEffectiveness(-1.);
281          cuts.insert(rcP);
282          assert(rcP==NULL);
283         
284          OsiColCut * ccP= new OsiColCut;
285          ccP->setEffectiveness(-12.);
286          cuts.insert(ccP);
287          assert(ccP==NULL);
288        }
289        {
290          //Generate inconsistent Row cut
291          OsiRowCut rc;
292          const int ne=1;
293          int inx[ne]={-10};
294          double el[ne]={2.5};
295          rc.setRow(ne,inx,el);
296          rc.setLb(3.);
297          rc.setUb(4.);
298          assert(!rc.consistent());
299          cuts.insert(rc);
300        }
301        {
302          //Generate inconsistent col cut
303          OsiColCut cc;
304          const int ne=1;
305          int inx[ne]={-10};
306          double el[ne]={2.5};
307          cc.setUbs(ne,inx,el);
308          assert(!cc.consistent());
309          cuts.insert(cc);
310        }
311        {
312          // Generate row cut which is inconsistent for model m
313          OsiRowCut rc;
314          const int ne=1;
315          int inx[ne]={10};
316          double el[ne]={2.5};
317          rc.setRow(ne,inx,el);
318          assert(rc.consistent());
319          assert(!rc.consistent(im));
320          cuts.insert(rc);
321        }
322        {
323          // Generate col cut which is inconsistent for model m
324          OsiColCut cc;
325          const int ne=1;
326          int inx[ne]={30};
327          double el[ne]={2.0};
328          cc.setLbs(ne,inx,el);
329          assert(cc.consistent());
330          assert(!cc.consistent(im));
331          cuts.insert(cc);
332        }
333        {
334          // Generate col cut which is infeasible
335          OsiColCut cc;
336          const int ne=1;
337          int inx[ne]={0};
338          double el[ne]={2.0};
339          cc.setUbs(ne,inx,el);
340          cc.setEffectiveness(1000.);
341          assert(cc.consistent());
342          assert(cc.consistent(im));
343          assert(cc.infeasible(im));
344          cuts.insert(cc);
345        }
346      }
347      assert(cuts.sizeRowCuts()==4);
348      assert(cuts.sizeColCuts()==5);
349     
350      OsiSolverInterface::ApplyCutsReturnCode rc = im.applyCuts(cuts);
351      assert( rc.getNumIneffective() == 2 );
352      assert( rc.getNumApplied() == 2 );
353      assert( rc.getNumInfeasible() == 1 );
354      assert( rc.getNumInconsistentWrtIntegerModel() == 2 );
355      assert( rc.getNumInconsistent() == 2 );
356      assert( cuts.sizeCuts() == rc.getNumIneffective() +
357        rc.getNumApplied() +
358        rc.getNumInfeasible() +
359        rc.getNumInconsistentWrtIntegerModel() +
360        rc.getNumInconsistent() );
361    }
362   
363    {   
364      OsiCbcSolverInterface oslSi(m);
365      int nc = oslSi.getNumCols();
366      int nr = oslSi.getNumRows();
367      const double * cl = oslSi.getColLower();
368      const double * cu = oslSi.getColUpper();
369      const double * rl = oslSi.getRowLower();
370      const double * ru = oslSi.getRowUpper();
371      assert( nc == 8 );
372      assert( nr == 5 );
373      assert( eq(cl[0],2.5) );
374      assert( eq(cl[1],0.0) );
375      assert( eq(cu[1],4.1) );
376      assert( eq(cu[2],1.0) );
377      assert( eq(rl[0],2.5) );
378      assert( eq(rl[4],3.0) );
379      assert( eq(ru[1],2.1) );
380      assert( eq(ru[4],15.0) );
381     
382      const double * cs = oslSi.getColSolution();
383      assert( eq(cs[0],2.5) );
384      assert( eq(cs[7],0.0) );
385     
386      assert( !eq(cl[3],1.2345) );
387      oslSi.setColLower( 3, 1.2345 );
388      assert( eq(oslSi.getColLower()[3],1.2345) );
389     
390      assert( !eq(cu[4],10.2345) );
391      oslSi.setColUpper( 4, 10.2345 );
392      assert( eq(oslSi.getColUpper()[4],10.2345) );
393      // LH: Objective will depend on how underlying solver constructs and
394      // LH: maintains initial solution.
395      double objValue = oslSi.getObjValue();
396      assert( eq(objValue,3.5) || eq(objValue,10.5) );
397
398      assert( eq( oslSi.getObjCoefficients()[0],  1.0) );
399      assert( eq( oslSi.getObjCoefficients()[1],  0.0) );
400      assert( eq( oslSi.getObjCoefficients()[2],  0.0) );
401      assert( eq( oslSi.getObjCoefficients()[3],  0.0) );
402      assert( eq( oslSi.getObjCoefficients()[4],  2.0) );
403      assert( eq( oslSi.getObjCoefficients()[5],  0.0) );
404      assert( eq( oslSi.getObjCoefficients()[6],  0.0) );
405      assert( eq( oslSi.getObjCoefficients()[7], -1.0) );
406    }
407   
408    // Test matrixByRow method
409    { 
410      const OsiCbcSolverInterface si(m);
411      const CoinPackedMatrix * smP = si.getMatrixByRow();
412      // LL:      const OsiCbcPackedMatrix * osmP = dynamic_cast<const OsiCbcPackedMatrix*>(smP);
413      // LL: assert( osmP!=NULL );
414
415#ifdef OSICBC_TEST_MTX_STRUCTURE
416
417      CoinRelFltEq eq;
418      const double * ev = smP->getElements();
419      assert( eq(ev[0],   3.0) );
420      assert( eq(ev[1],   1.0) );
421      assert( eq(ev[2],  -2.0) );
422      assert( eq(ev[3],  -1.0) );
423      assert( eq(ev[4],  -1.0) );
424      assert( eq(ev[5],   2.0) );
425      assert( eq(ev[6],   1.1) );
426      assert( eq(ev[7],   1.0) );
427      assert( eq(ev[8],   1.0) );
428      assert( eq(ev[9],   2.8) );
429      assert( eq(ev[10], -1.2) );
430      assert( eq(ev[11],  5.6) );
431      assert( eq(ev[12],  1.0) );
432      assert( eq(ev[13],  1.9) );
433     
434      const CoinBigIndex * mi = smP->getVectorStarts();
435      assert( mi[0]==0 );
436      assert( mi[1]==5 );
437      assert( mi[2]==7 );
438      assert( mi[3]==9 );
439      assert( mi[4]==11 );
440      assert( mi[5]==14 );
441     
442      const int * ei = smP->getIndices();
443      assert( ei[0]  ==  0 );
444      assert( ei[1]  ==  1 );
445      assert( ei[2]  ==  3 );
446      assert( ei[3]  ==  4 );
447      assert( ei[4]  ==  7 );
448      assert( ei[5]  ==  1 );
449      assert( ei[6]  ==  2 );
450      assert( ei[7]  ==  2 );
451      assert( ei[8]  ==  5 );
452      assert( ei[9]  ==  3 );
453      assert( ei[10] ==  6 );
454      assert( ei[11] ==  0 );
455      assert( ei[12] ==  4 );
456      assert( ei[13] ==  7 );   
457
458#else   // OSICBC_TEST_MTX_STRUCTURE
459
460      CoinPackedMatrix exmip1Mtx ;
461      exmip1Mtx.reverseOrderedCopyOf(BuildExmip1Mtx()) ;
462      assert( exmip1Mtx.isEquivalent(*smP) ) ;
463
464#endif  // OSICBC_TEST_MTX_STRUCTURE
465
466      assert( smP->getMajorDim() == 5 );
467      assert( smP->getMinorDim() == 8 );
468      assert( smP->getNumElements() == 14 );
469      assert( smP->getSizeVectorStarts() == 6 );
470    }
471
472    // Test adding several cuts, and handling of a coefficient of infinity
473    // in the constraint matrix.
474    {
475      OsiCbcSolverInterface fim;
476      std::string fn = mpsDir+"exmip1";
477      fim.readMps(fn.c_str(),"mps");
478      // exmip1.mps has 2 integer variables with index 2 & 3
479      fim.initialSolve();
480      OsiRowCut cuts[3];
481     
482     
483      // Generate one ineffective cut plus two trivial cuts
484      int c;
485      int nc = fim.getNumCols();
486      int *inx = new int[nc];
487      for (c=0;c<nc;c++) inx[c]=c;
488      double *el = new double[nc];
489      for (c=0;c<nc;c++) el[c]=1.0e-50+((double)c)*((double)c);
490     
491      cuts[0].setRow(nc,inx,el);
492      cuts[0].setLb(-100.);
493      cuts[0].setUb(500.);
494      cuts[0].setEffectiveness(22);
495      el[4]=0.0; // to get inf later
496     
497      for (c=2;c<4;c++) {
498        el[0]=1.0;
499        inx[0]=c;
500        cuts[c-1].setRow(1,inx,el);
501        cuts[c-1].setLb(1.);
502        cuts[c-1].setUb(100.);
503        cuts[c-1].setEffectiveness(c);
504      }
505      fim.writeMps("x1.mps");
506      fim.applyRowCuts(3,cuts);
507      fim.writeMps("x2.mps");
508      // resolve - should get message about zero elements
509      fim.resolve();
510      fim.writeMps("x3.mps");
511      // check integer solution
512      const double * cs = fim.getColSolution();
513      CoinRelFltEq eq;
514      assert( eq(cs[2],   1.0) );
515      assert( eq(cs[3],   1.0) );
516      // check will find invalid matrix
517      el[0]=1.0/el[4];
518      inx[0]=0;
519      cuts[0].setRow(nc,inx,el);
520      cuts[0].setLb(-100.);
521      cuts[0].setUb(500.);
522      cuts[0].setEffectiveness(22);
523      fim.applyRowCut(cuts[0]);
524      // resolve - should get message about zero elements
525      fim.resolve();
526      assert (fim.isAbandoned());
527      delete[]el;
528      delete[]inx;
529    }
530
531        // Test matrixByCol method
532    {
533 
534      const OsiCbcSolverInterface si(m);
535      const CoinPackedMatrix * smP = si.getMatrixByCol();
536      // LL:      const OsiCbcPackedMatrix * osmP = dynamic_cast<const OsiCbcPackedMatrix*>(smP);
537      // LL: assert( osmP!=NULL );
538     
539#ifdef OSICBC_TEST_MTX_STRUCTURE
540
541      CoinRelFltEq eq;
542      const double * ev = smP->getElements();
543      assert( eq(ev[0],   3.0) );
544      assert( eq(ev[1],   5.6) );
545      assert( eq(ev[2],   1.0) );
546      assert( eq(ev[3],   2.0) );
547      assert( eq(ev[4],   1.1) );
548      assert( eq(ev[5],   1.0) );
549      assert( eq(ev[6],  -2.0) );
550      assert( eq(ev[7],   2.8) );
551      assert( eq(ev[8],  -1.0) );
552      assert( eq(ev[9],   1.0) );
553      assert( eq(ev[10],  1.0) );
554      assert( eq(ev[11], -1.2) );
555      assert( eq(ev[12], -1.0) );
556      assert( eq(ev[13],  1.9) );
557     
558      const CoinBigIndex * mi = smP->getVectorStarts();
559      assert( mi[0]==0 );
560      assert( mi[1]==2 );
561      assert( mi[2]==4 );
562      assert( mi[3]==6 );
563      assert( mi[4]==8 );
564      assert( mi[5]==10 );
565      assert( mi[6]==11 );
566      assert( mi[7]==12 );
567      assert( mi[8]==14 );
568     
569      const int * ei = smP->getIndices();
570      assert( ei[0]  ==  0 );
571      assert( ei[1]  ==  4 );
572      assert( ei[2]  ==  0 );
573      assert( ei[3]  ==  1 );
574      assert( ei[4]  ==  1 );
575      assert( ei[5]  ==  2 );
576      assert( ei[6]  ==  0 );
577      assert( ei[7]  ==  3 );
578      assert( ei[8]  ==  0 );
579      assert( ei[9]  ==  4 );
580      assert( ei[10] ==  2 );
581      assert( ei[11] ==  3 );
582      assert( ei[12] ==  0 );
583      assert( ei[13] ==  4 );   
584     
585#else // OSICBC_TEST_MTX_STRUCTURE
586
587      CoinPackedMatrix &exmip1Mtx = BuildExmip1Mtx() ;
588      assert( exmip1Mtx.isEquivalent(*smP) ) ;
589
590#endif  // OSICBC_TEST_MTX_STRUCTURE     
591
592      assert( smP->getMajorDim() == 8 ); 
593      assert( smP->getMinorDim() == 5 );
594      assert( smP->getNumElements() == 14 );
595      assert( smP->getSizeVectorStarts() == 9 );
596    }
597
598    //--------------
599    // Test rowsense, rhs, rowrange, matrixByRow, solver assignment
600    {
601      OsiCbcSolverInterface lhs;
602      {     
603
604        OsiCbcSolverInterface siC1(m);     
605        const char   * siC1rs  = siC1.getRowSense();
606        assert( siC1rs[0]=='G' );
607        assert( siC1rs[1]=='L' );
608        assert( siC1rs[2]=='E' );
609        assert( siC1rs[3]=='R' );
610        assert( siC1rs[4]=='R' );
611       
612        const double * siC1rhs = siC1.getRightHandSide();
613        assert( eq(siC1rhs[0],2.5) );
614        assert( eq(siC1rhs[1],2.1) );
615        assert( eq(siC1rhs[2],4.0) );
616        assert( eq(siC1rhs[3],5.0) );
617        assert( eq(siC1rhs[4],15.) ); 
618       
619        const double * siC1rr  = siC1.getRowRange();
620        assert( eq(siC1rr[0],0.0) );
621        assert( eq(siC1rr[1],0.0) );
622        assert( eq(siC1rr[2],0.0) );
623        assert( eq(siC1rr[3],5.0-1.8) );
624        assert( eq(siC1rr[4],15.0-3.0) );
625       
626        const CoinPackedMatrix * siC1mbr = siC1.getMatrixByRow();
627        assert( siC1mbr != NULL );
628
629#ifdef OSICBC_TEST_MTX_STRUCTURE
630
631        const double * ev = siC1mbr->getElements();
632        assert( eq(ev[0],   3.0) );
633        assert( eq(ev[1],   1.0) );
634        assert( eq(ev[2],  -2.0) );
635        assert( eq(ev[3],  -1.0) );
636        assert( eq(ev[4],  -1.0) );
637        assert( eq(ev[5],   2.0) );
638        assert( eq(ev[6],   1.1) );
639        assert( eq(ev[7],   1.0) );
640        assert( eq(ev[8],   1.0) );
641        assert( eq(ev[9],   2.8) );
642        assert( eq(ev[10], -1.2) );
643        assert( eq(ev[11],  5.6) );
644        assert( eq(ev[12],  1.0) );
645        assert( eq(ev[13],  1.9) );
646       
647        const CoinBigIndex * mi = siC1mbr->getVectorStarts();
648        assert( mi[0]==0 );
649        assert( mi[1]==5 );
650        assert( mi[2]==7 );
651        assert( mi[3]==9 );
652        assert( mi[4]==11 );
653        assert( mi[5]==14 );
654       
655        const int * ei = siC1mbr->getIndices();
656        assert( ei[0]  ==  0 );
657        assert( ei[1]  ==  1 );
658        assert( ei[2]  ==  3 );
659        assert( ei[3]  ==  4 );
660        assert( ei[4]  ==  7 );
661        assert( ei[5]  ==  1 );
662        assert( ei[6]  ==  2 );
663        assert( ei[7]  ==  2 );
664        assert( ei[8]  ==  5 );
665        assert( ei[9]  ==  3 );
666        assert( ei[10] ==  6 );
667        assert( ei[11] ==  0 );
668        assert( ei[12] ==  4 );
669        assert( ei[13] ==  7 );   
670
671#else   // OSICBC_TEST_MTX_STRUCTURE
672
673        CoinPackedMatrix exmip1Mtx ;
674        exmip1Mtx.reverseOrderedCopyOf(BuildExmip1Mtx()) ;
675        assert( exmip1Mtx.isEquivalent(*siC1mbr) ) ;
676
677#endif  // OSICBC_TEST_MTX_STRUCTURE
678
679        assert( siC1mbr->getMajorDim() == 5 ); 
680        assert( siC1mbr->getMinorDim() == 8 );
681        assert( siC1mbr->getNumElements() == 14 );
682        assert( siC1mbr->getSizeVectorStarts()==6 );
683
684        assert( siC1rs  == siC1.getRowSense() );
685        assert( siC1rhs == siC1.getRightHandSide() );
686        assert( siC1rr  == siC1.getRowRange() );
687
688        // Change OSL Model by adding free row
689        OsiRowCut rc;
690        rc.setLb(-DBL_MAX);
691        rc.setUb( DBL_MAX);
692        OsiCuts cuts;
693        cuts.insert(rc);
694        siC1.applyCuts(cuts);
695             
696       
697        siC1rs  = siC1.getRowSense();
698        assert( siC1rs[0]=='G' );
699        assert( siC1rs[1]=='L' );
700        assert( siC1rs[2]=='E' );
701        assert( siC1rs[3]=='R' );
702        assert( siC1rs[4]=='R' );
703        assert( siC1rs[5]=='N' );
704
705        siC1rhs = siC1.getRightHandSide();
706        assert( eq(siC1rhs[0],2.5) );
707        assert( eq(siC1rhs[1],2.1) );
708        assert( eq(siC1rhs[2],4.0) );
709        assert( eq(siC1rhs[3],5.0) );
710        assert( eq(siC1rhs[4],15.) ); 
711        assert( eq(siC1rhs[5],0.0 ) ); 
712
713        siC1rr  = siC1.getRowRange();
714        assert( eq(siC1rr[0],0.0) );
715        assert( eq(siC1rr[1],0.0) );
716        assert( eq(siC1rr[2],0.0) );
717        assert( eq(siC1rr[3],5.0-1.8) );
718        assert( eq(siC1rr[4],15.0-3.0) );
719        assert( eq(siC1rr[5],0.0) );
720   
721        lhs=siC1;
722      }
723      // Test that lhs has correct values even though siC1 has gone out of scope   
724     
725      const char * lhsrs  = lhs.getRowSense();
726      assert( lhsrs[0]=='G' );
727      assert( lhsrs[1]=='L' );
728      assert( lhsrs[2]=='E' );
729      assert( lhsrs[3]=='R' );
730      assert( lhsrs[4]=='R' );
731      assert( lhsrs[5]=='N' );
732     
733      const double * lhsrhs = lhs.getRightHandSide();
734      assert( eq(lhsrhs[0],2.5) );
735      assert( eq(lhsrhs[1],2.1) );
736      assert( eq(lhsrhs[2],4.0) );
737      assert( eq(lhsrhs[3],5.0) );
738      assert( eq(lhsrhs[4],15.) ); 
739      assert( eq(lhsrhs[5],0.0) ); 
740     
741      const double *lhsrr  = lhs.getRowRange();
742      assert( eq(lhsrr[0],0.0) );
743      assert( eq(lhsrr[1],0.0) );
744      assert( eq(lhsrr[2],0.0) );
745      assert( eq(lhsrr[3],5.0-1.8) );
746      assert( eq(lhsrr[4],15.0-3.0) );
747      assert( eq(lhsrr[5],0.0) );     
748     
749      const CoinPackedMatrix * lhsmbr = lhs.getMatrixByRow();
750      assert( lhsmbr != NULL );       
751
752#ifdef OSICBC_TEST_MTX_STRUCTURE
753
754      const double * ev = lhsmbr->getElements();
755      assert( eq(ev[0],   3.0) );
756      assert( eq(ev[1],   1.0) );
757      assert( eq(ev[2],  -2.0) );
758      assert( eq(ev[3],  -1.0) );
759      assert( eq(ev[4],  -1.0) );
760      assert( eq(ev[5],   2.0) );
761      assert( eq(ev[6],   1.1) );
762      assert( eq(ev[7],   1.0) );
763      assert( eq(ev[8],   1.0) );
764      assert( eq(ev[9],   2.8) );
765      assert( eq(ev[10], -1.2) );
766      assert( eq(ev[11],  5.6) );
767      assert( eq(ev[12],  1.0) );
768      assert( eq(ev[13],  1.9) );
769     
770      const CoinBigIndex * mi = lhsmbr->getVectorStarts();
771      assert( mi[0]==0 );
772      assert( mi[1]==5 );
773      assert( mi[2]==7 );
774      assert( mi[3]==9 );
775      assert( mi[4]==11 );
776      assert( mi[5]==14 );
777     
778      const int * ei = lhsmbr->getIndices();
779      assert( ei[0]  ==  0 );
780      assert( ei[1]  ==  1 );
781      assert( ei[2]  ==  3 );
782      assert( ei[3]  ==  4 );
783      assert( ei[4]  ==  7 );
784      assert( ei[5]  ==  1 );
785      assert( ei[6]  ==  2 );
786      assert( ei[7]  ==  2 );
787      assert( ei[8]  ==  5 );
788      assert( ei[9]  ==  3 );
789      assert( ei[10] ==  6 );
790      assert( ei[11] ==  0 );
791      assert( ei[12] ==  4 );
792      assert( ei[13] ==  7 );   
793
794#else   // OSICBC_TEST_MTX_STRUCTURE
795
796/*
797  This admittedly looks bogus, but it's the equivalent operation on the matrix
798  for inserting a cut of the form -Inf <= +Inf (i.e., a cut with no
799  coefficients).
800*/
801      CoinPackedMatrix exmip1Mtx ;
802      exmip1Mtx.reverseOrderedCopyOf(BuildExmip1Mtx()) ;
803      CoinPackedVector freeRow ;
804      exmip1Mtx.appendRow(freeRow) ;
805      assert( exmip1Mtx.isEquivalent(*lhsmbr) ) ;
806
807#endif  // OSICBC_TEST_MTX_STRUCTURE
808     
809      int md = lhsmbr->getMajorDim();
810      assert(  md == 6 ); 
811      assert( lhsmbr->getNumElements() == 14 );
812    }
813   
814  }
815
816  // Test add/delete columns
817  {   
818    OsiCbcSolverInterface m;
819    std::string fn = mpsDir+"p0033";
820    m.readMps(fn.c_str(),"mps");
821    double inf = m.getInfinity();
822
823    CoinPackedVector c0;
824    c0.insert(0, 4);
825    c0.insert(1, 1);
826    m.addCol(c0, 0, inf, 3);
827    m.initialSolve();
828    double objValue = m.getObjValue();
829    CoinRelFltEq eq(1.0e-2);
830    assert( eq(objValue,2520.57) );
831    // Try deleting first column that's nonbasic at lower bound (0).
832    int * d = new int[1];
833    CoinWarmStartBasis *cwsb =
834        dynamic_cast<CoinWarmStartBasis *>(m.getWarmStart()) ;
835    assert(cwsb) ;
836    CoinWarmStartBasis::Status stati ;
837    int iCol ;
838    for (iCol = 0 ;  iCol < cwsb->getNumStructural() ; iCol++)
839    { stati = cwsb->getStructStatus(iCol) ;
840      if (stati == CoinWarmStartBasis::atLowerBound) break ; }
841    d[0]=iCol;
842    m.deleteCols(1,d);
843    delete [] d;
844    delete cwsb;
845    d=NULL;
846    m.resolve();
847    objValue = m.getObjValue();
848    assert( eq(objValue,2520.57) );
849    // Try deleting column we added. If basic, go to initialSolve as deleting
850    // basic variable trashes basis required for warm start.
851    iCol = m.getNumCols()-1;
852    cwsb = dynamic_cast<CoinWarmStartBasis *>(m.getWarmStart()) ;
853    stati =  cwsb->getStructStatus(iCol) ;
854    delete cwsb;
855    m.deleteCols(1,&iCol);
856    if (stati == CoinWarmStartBasis::basic)
857    { m.initialSolve() ; }
858    else
859    { m.resolve(); }
860    objValue = m.getObjValue();
861    assert( eq(objValue,2520.57) );
862
863  }
864  // Test matt
865  if (fopen("../Cbc/matt.mps","r")) {   
866    OsiCbcSolverInterface m;
867    m.readMps("../Cbc/matt","mps");
868    m.setHintParam(OsiDoPresolveInResolve, true, OsiHintDo);
869    m.resolve();
870   
871    std::vector<double *> rays = m.getDualRays(1);
872    std::cout << "Dual Ray: " << std::endl;
873    for(int i = 0; i < m.getNumRows(); i++){
874      if(fabs(rays[0][i]) > 0.00001)
875        std::cout << i << " : " << rays[0][i] << std::endl;
876    }
877   
878    std::cout << "isProvenOptimal = " << m.isProvenOptimal() << std::endl;
879    std::cout << "isProvenPrimalInfeasible = " << m.isProvenPrimalInfeasible()
880         << std::endl;
881   
882    delete [] rays[0];
883   
884  }
885
886  // Build a model
887  {   
888    OsiCbcSolverInterface model;
889    std::string fn = mpsDir+"p0033";
890    model.readMps(fn.c_str(),"mps");
891    // Point to data
892    int numberRows = model.getNumRows();
893    const double * rowLower = model.getRowLower();
894    const double * rowUpper = model.getRowUpper();
895    int numberColumns = model.getNumCols();
896    const double * columnLower = model.getColLower();
897    const double * columnUpper = model.getColUpper();
898    const double * columnObjective = model.getObjCoefficients();
899    // get row copy
900    CoinPackedMatrix rowCopy = *model.getMatrixByRow();
901    const int * column = rowCopy.getIndices();
902    const int * rowLength = rowCopy.getVectorLengths();
903    const CoinBigIndex * rowStart = rowCopy.getVectorStarts();
904    const double * element = rowCopy.getElements();
905   
906    // solve
907    model.initialSolve();
908    // Now build new model
909    CoinModel build;
910    // Row bounds
911    int iRow;
912    for (iRow=0;iRow<numberRows;iRow++) {
913      build.setRowBounds(iRow,rowLower[iRow],rowUpper[iRow]);
914    }
915    // Column bounds and objective
916    int iColumn;
917    for (iColumn=0;iColumn<numberColumns;iColumn++) {
918      build.setColumnLower(iColumn,columnLower[iColumn]);
919      build.setColumnUpper(iColumn,columnUpper[iColumn]);
920      build.setObjective(iColumn,columnObjective[iColumn]);
921    }
922    // Adds elements one by one by row (backwards by row)
923    for (iRow=numberRows-1;iRow>=0;iRow--) {
924      int start = rowStart[iRow];
925      for (int j=start;j<start+rowLength[iRow];j++) 
926        build(iRow,column[j],element[j]);
927    }
928    // Now create Model
929    OsiCbcSolverInterface model2;
930    model2.loadFromCoinModel(build);
931    model2.initialSolve();
932    // Save - should be continuous
933    model2.writeMps("continuous");
934    int * whichInteger = new int[numberColumns];
935    for (iColumn=0;iColumn<numberColumns;iColumn++) 
936      whichInteger[iColumn]=iColumn;
937    // mark as integer
938    model2.setInteger(whichInteger,numberColumns);
939    delete [] whichInteger;
940    // save - should be integer
941    model2.writeMps("integer");
942   
943    // Now do with strings attached
944    // Save build to show how to go over rows
945    CoinModel saveBuild = build;
946    build = CoinModel();
947    // Column bounds
948    for (iColumn=0;iColumn<numberColumns;iColumn++) {
949      build.setColumnLower(iColumn,columnLower[iColumn]);
950      build.setColumnUpper(iColumn,columnUpper[iColumn]);
951    }
952    // Objective - half the columns as is and half with multiplier of "1.0+multiplier"
953    // Pick up from saveBuild (for no reason at all)
954    for (iColumn=0;iColumn<numberColumns;iColumn++) {
955      double value = saveBuild.objective(iColumn);
956      if (iColumn*2<numberColumns) {
957        build.setObjective(iColumn,columnObjective[iColumn]);
958      } else {
959        // create as string
960        char temp[100];
961        sprintf(temp,"%g + abs(%g*multiplier)",value,value);
962        build.setObjective(iColumn,temp);
963      }
964    }
965    // It then adds rows one by one but for half the rows sets their values
966    //      with multiplier of "1.0+1.5*multiplier"
967    for (iRow=0;iRow<numberRows;iRow++) {
968      if (iRow*2<numberRows) {
969        // add row in simple way
970        int start = rowStart[iRow];
971        build.addRow(rowLength[iRow],column+start,element+start,
972                     rowLower[iRow],rowUpper[iRow]);
973      } else {
974        // As we have to add one by one let's get from saveBuild
975        CoinModelLink triple=saveBuild.firstInRow(iRow);
976        while (triple.column()>=0) {
977          int iColumn = triple.column();
978          if (iColumn*2<numberColumns) {
979            // just value as normal
980            build(iRow,triple.column(),triple.value());
981          } else {
982            // create as string
983            char temp[100];
984            sprintf(temp,"%g + (1.5*%g*multiplier)",triple.value(), triple.value());
985            build(iRow,iColumn,temp);
986          }
987          triple=saveBuild.next(triple);
988        }
989        // but remember to do rhs
990        build.setRowLower(iRow,rowLower[iRow]);
991        build.setRowUpper(iRow,rowUpper[iRow]);
992      }
993    }
994    // If small switch on error printing
995    if (numberColumns<50)
996      build.setLogLevel(1);
997    int numberErrors=model2.loadFromCoinModel(build);
998    // should fail as we never set multiplier
999    assert (numberErrors);
1000    build.associateElement("multiplier",0.0);
1001    numberErrors=model2.loadFromCoinModel(build);
1002    assert (!numberErrors);
1003    model2.initialSolve();
1004    // It then loops with multiplier going from 0.0 to 2.0 in increments of 0.1
1005    for (double multiplier=0.0;multiplier<2.0;multiplier+= 0.1) {
1006      build.associateElement("multiplier",multiplier);
1007      numberErrors=model2.loadFromCoinModel(build,true);
1008      assert (!numberErrors);
1009      model2.resolve();
1010    }
1011  }
1012  // branch and bound
1013  {   
1014    OsiCbcSolverInterface m;
1015    std::string fn = mpsDir+"p0033";
1016    m.readMps(fn.c_str(),"mps");
1017    m.initialSolve();
1018    //m.messageHandler()->setLogLevel(0);
1019    m.getModelPtr()->messageHandler()->setLogLevel(0);
1020    m.branchAndBound();
1021  }
1022  // branch and bound using CbcModel!!!!!!!
1023  {   
1024    OsiCbcSolverInterface mm;
1025    OsiCbcSolverInterface m(&mm);
1026    std::string fn = mpsDir+"p0033";
1027    m.readMps(fn.c_str(),"mps");
1028    m.initialSolve();
1029    m.branchAndBound();
1030  }
1031#ifdef COIN_HAS_OSL
1032  // branch and bound using OSL
1033  {   
1034    OsiOslSolverInterface mmm;
1035    OsiCbcSolverInterface mm(&mmm);
1036    CbcStrategyNull strategy;
1037    OsiCbcSolverInterface m(&mm,&strategy);
1038    std::string fn = mpsDir+"p0033";
1039    m.readMps(fn.c_str(),"mps");
1040    //m.initialSolve();
1041    m.branchAndBound();
1042  }
1043#endif
1044  int errCnt = 0;
1045  // Do common solverInterface testing
1046  {
1047    OsiCbcSolverInterface m;
1048    errCnt += OsiSolverInterfaceCommonUnitTest(&m, mpsDir,netlibDir);
1049  }
1050  {
1051    OsiCbcSolverInterface mm;
1052    OsiCbcSolverInterface m(&mm);
1053    errCnt += OsiSolverInterfaceCommonUnitTest(&m, mpsDir,netlibDir);
1054  }
1055#ifdef COIN_HAS_OSL
1056  {
1057    OsiOslSolverInterface mm;
1058    OsiCbcSolverInterface m(&mm);
1059    errCnt += OsiSolverInterfaceCommonUnitTest(&m, mpsDir,netlibDir);
1060  }
1061#endif
1062  return errCnt;
1063}
Note: See TracBrowser for help on using the repository browser.