00001
00002
00003
00004 #if defined(_MSC_VER)
00005
00006 # pragma warning(disable:4786)
00007 #endif
00008
00009 #include <cassert>
00010
00011 #include "OsiOslSolverInterface.hpp"
00012 #include "OsiCuts.hpp"
00013 #include "OsiRowCut.hpp"
00014 #include "OsiColCut.hpp"
00015 #include "CoinMessage.hpp"
00016
00017
00018 #include <vector>
00019 #include <map>
00020 #ifndef _MSC_VER
00021 using std::max;
00022 using std::min;
00023 #endif
00024
00025
00026 class OsiNodeSimple {
00027
00028 public:
00029
00030
00031 OsiNodeSimple ();
00032
00033
00034
00035 OsiNodeSimple (OsiSolverInterface &model,
00036 int numberIntegers, int * integer);
00037
00038
00039 OsiNodeSimple ( const OsiNodeSimple &);
00040
00041
00042 OsiNodeSimple & operator=( const OsiNodeSimple& rhs);
00043
00044
00045 ~OsiNodeSimple ();
00046
00047
00048
00049 CoinWarmStartBasis basis_;
00050
00051 double objectiveValue_;
00052
00053 int variable_;
00054
00055 int way_;
00056
00057 int numberIntegers_;
00058
00059 double value_;
00060
00061
00062 int * lower_;
00063 int * upper_;
00064 };
00065
00066
00067 OsiNodeSimple::OsiNodeSimple() :
00068 basis_(CoinWarmStartBasis()),
00069 objectiveValue_(1.0e100),
00070 variable_(-100),
00071 way_(-1),
00072 numberIntegers_(0),
00073 value_(0.5),
00074 lower_(NULL),
00075 upper_(NULL)
00076 {
00077 }
00078 OsiNodeSimple::OsiNodeSimple(OsiSolverInterface & model,
00079 int numberIntegers, int * integer)
00080 {
00081 const CoinWarmStartBasis* ws =
00082 dynamic_cast<const CoinWarmStartBasis*>(model.getWarmStart());
00083
00084 assert (ws!=NULL);
00085 basis_ = CoinWarmStartBasis(*ws);
00086 variable_=-1;
00087 way_=-1;
00088 numberIntegers_=numberIntegers;
00089 value_=0.0;
00090 if (model.isProvenOptimal()&&!model.isDualObjectiveLimitReached()) {
00091 objectiveValue_ = model.getObjSense()*model.getObjValue();
00092 } else {
00093 objectiveValue_ = 1.0e100;
00094 lower_ = NULL;
00095 upper_ = NULL;
00096 return;
00097 }
00098 lower_ = new int [numberIntegers_];
00099 upper_ = new int [numberIntegers_];
00100 assert (upper_!=NULL);
00101 const double * lower = model.getColLower();
00102 const double * upper = model.getColUpper();
00103 const double * solution = model.getColSolution();
00104 int i;
00105
00106 #define INTEGER_TOLERANCE 1.0e-6
00107
00108 #define STRONG_BRANCHING 5
00109 #ifdef STRONG_BRANCHING
00110 double upMovement[STRONG_BRANCHING];
00111 double downMovement[STRONG_BRANCHING];
00112 double solutionValue[STRONG_BRANCHING];
00113 int chosen[STRONG_BRANCHING];
00114 int iSmallest=0;
00115
00116 for (i=0;i<STRONG_BRANCHING;i++) {
00117 upMovement[i]=0.0;
00118 chosen[i]=-1;
00119 }
00120 #endif
00121 variable_=-1;
00122
00123 double mostAway=INTEGER_TOLERANCE;
00124 for (i=0;i<numberIntegers;i++) {
00125 int iColumn = integer[i];
00126 lower_[i]=(int)lower[iColumn];
00127 upper_[i]=(int)upper[iColumn];
00128 double value = solution[iColumn];
00129 value = max(value,(double) lower_[i]);
00130 value = min(value,(double) upper_[i]);
00131 double nearest = floor(value+0.5);
00132 if (fabs(value-nearest)>mostAway) {
00133 #ifdef STRONG_BRANCHING
00134 double away = fabs(value-nearest);
00135 if (away>upMovement[iSmallest]) {
00136
00137 upMovement[iSmallest]=away;
00138 solutionValue[iSmallest]=value;
00139 chosen[iSmallest]=i;
00140 int j;
00141 iSmallest=-1;
00142 double smallest = 1.0;
00143 for (j=0;j<STRONG_BRANCHING;j++) {
00144 if (upMovement[j]<smallest) {
00145 smallest=upMovement[j];
00146 iSmallest=j;
00147 }
00148 }
00149 }
00150 #else
00151 mostAway=fabs(value-nearest);
00152 variable_=i;
00153 value_=value;
00154 if (value<=nearest)
00155 way_=1;
00156 else
00157 way_=-1;
00158 #endif
00159 }
00160 }
00161 #ifdef STRONG_BRANCHING
00162 int numberStrong=0;
00163 for (i=0;i<STRONG_BRANCHING;i++) {
00164 if (chosen[i]>=0) {
00165 numberStrong ++;
00166 variable_ = chosen[i];
00167 }
00168 }
00169 if (numberStrong==1) {
00170
00171 int iColumn = integer[variable_];
00172 double value = solution[iColumn];
00173 value = max(value,(double) lower_[variable_]);
00174 value = min(value,(double) upper_[variable_]);
00175 double nearest = floor(value+0.5);
00176 value_=value;
00177 if (value<=nearest)
00178 way_=1;
00179 else
00180 way_=-1;
00181 } else if (numberStrong) {
00182
00183 bool chooseOne=true;
00184 model.markHotStart();
00185 for (i=0;i<STRONG_BRANCHING;i++) {
00186 int iInt = chosen[i];
00187 if (iInt>=0) {
00188 int iColumn = integer[iInt];
00189 double value = solutionValue[i];
00190 double objectiveChange;
00191 value = max(value,(double) lower_[iInt]);
00192 value = min(value,(double) upper_[iInt]);
00193
00194
00195
00196 model.setColUpper(iColumn,floor(value));
00197 model.solveFromHotStart();
00198 model.setColUpper(iColumn,upper_[iInt]);
00199 if (model.isProvenOptimal()&&!model.isDualObjectiveLimitReached()) {
00200 objectiveChange = model.getObjSense()*model.getObjValue()
00201 - objectiveValue_;
00202 } else {
00203 objectiveChange = 1.0e100;
00204 }
00205 downMovement[i]=objectiveChange;
00206
00207
00208
00209 model.setColLower(iColumn,ceil(value));
00210 model.solveFromHotStart();
00211 model.setColLower(iColumn,lower_[iInt]);
00212 if (model.isProvenOptimal()&&!model.isDualObjectiveLimitReached()) {
00213 objectiveChange = model.getObjSense()*model.getObjValue()
00214 - objectiveValue_;
00215 } else {
00216 objectiveChange = 1.0e100;
00217 }
00218 upMovement[i]=objectiveChange;
00219
00220
00221
00222
00223
00224
00225 bool solveAgain=false;
00226 if (upMovement[i]<1.0e100) {
00227 if(downMovement[i]<1.0e100) {
00228
00229 } else {
00230
00231 solveAgain = true;
00232 model.setColLower(iColumn,ceil(value));
00233 }
00234 } else {
00235 if(downMovement[i]<1.0e100) {
00236
00237 solveAgain = true;
00238 model.setColUpper(iColumn,floor(value));
00239 } else {
00240
00241 objectiveValue_=1.0e100;
00242 chooseOne=false;
00243 break;
00244 }
00245 }
00246 if (solveAgain) {
00247
00248 variable_ = numberIntegers;
00249 chooseOne=false;
00250 break;
00251 }
00252 }
00253 }
00254 if (chooseOne) {
00255
00256 double best = -1.0;
00257 double best2 = -1.0;
00258 for (i=0;i<STRONG_BRANCHING;i++) {
00259 int iInt = chosen[i];
00260 if (iInt>=0) {
00261 std::cout<<"Strong branching on "
00262 <<i<<""<<iInt<<" down "<<downMovement[i]
00263 <<" up "<<upMovement[i]
00264 <<" value "<<solutionValue[i]
00265 <<std::endl;
00266 bool better = false;
00267 if (min(upMovement[i],downMovement[i])>best) {
00268
00269 better=true;
00270 } else if (min(upMovement[i],downMovement[i])>best-1.0e-5) {
00271 if (max(upMovement[i],downMovement[i])>best2+1.0e-5) {
00272
00273 better=true;
00274 }
00275 }
00276 if (better) {
00277 best = min(upMovement[i],downMovement[i]);
00278 best2 = max(upMovement[i],downMovement[i]);
00279 variable_ = iInt;
00280 double value = solutionValue[i];
00281 value = max(value,(double) lower_[variable_]);
00282 value = min(value,(double) upper_[variable_]);
00283 value_=value;
00284 if (upMovement[i]<=downMovement[i])
00285 way_=1;
00286 else
00287 way_=-1;
00288 }
00289 }
00290 }
00291 }
00292
00293 model.unmarkHotStart();
00294 }
00295 #endif
00296 }
00297
00298 OsiNodeSimple::OsiNodeSimple(const OsiNodeSimple & rhs)
00299 {
00300 basis_=rhs.basis_;
00301 objectiveValue_=rhs.objectiveValue_;
00302 variable_=rhs.variable_;
00303 way_=rhs.way_;
00304 numberIntegers_=rhs.numberIntegers_;
00305 value_=rhs.value_;
00306 lower_=NULL;
00307 upper_=NULL;
00308 if (rhs.lower_!=NULL) {
00309 lower_ = new int [numberIntegers_];
00310 upper_ = new int [numberIntegers_];
00311 assert (upper_!=NULL);
00312 memcpy(lower_,rhs.lower_,numberIntegers_*sizeof(int));
00313 memcpy(upper_,rhs.upper_,numberIntegers_*sizeof(int));
00314 }
00315 }
00316
00317 OsiNodeSimple &
00318 OsiNodeSimple::operator=(const OsiNodeSimple & rhs)
00319 {
00320 if (this != &rhs) {
00321 basis_=rhs.basis_;
00322 objectiveValue_=rhs.objectiveValue_;
00323 variable_=rhs.variable_;
00324 way_=rhs.way_;
00325 numberIntegers_=rhs.numberIntegers_;
00326 value_=rhs.value_;
00327 delete [] lower_;
00328 delete [] upper_;
00329 lower_=NULL;
00330 upper_=NULL;
00331 if (rhs.lower_!=NULL) {
00332 lower_ = new int [numberIntegers_];
00333 upper_ = new int [numberIntegers_];
00334 assert (upper_!=NULL);
00335 memcpy(lower_,rhs.lower_,numberIntegers_*sizeof(int));
00336 memcpy(upper_,rhs.upper_,numberIntegers_*sizeof(int));
00337 }
00338 }
00339 return *this;
00340 }
00341
00342
00343 OsiNodeSimple::~OsiNodeSimple ()
00344 {
00345 delete [] lower_;
00346 delete [] upper_;
00347 }
00348
00349 #include <vector>
00350
00351
00352 typedef std::vector<OsiNodeSimple> OsiVectorNode;
00353
00354
00355
00356 #ifdef NDEBUG
00357 #undef NDEBUG
00358 #endif
00359 class OsiOslMessageTest :
00360 public CoinMessageHandler {
00361
00362 public:
00363 virtual int print() ;
00364 };
00365
00366 int
00367 OsiOslMessageTest::print()
00368 {
00369 static int numberOptimal=0,numberInfeasible=0;
00370 if (currentSource()=="Osl") {
00371 if (currentMessage().externalNumber()==1) {
00372 numberOptimal++;
00373 if (numberOptimal%100==0)
00374 return CoinMessageHandler::print();
00375 } else if (currentMessage().externalNumber()==3000) {
00376 numberInfeasible++;
00377 }
00378 } else if (currentSource()=="Osi") {
00379 if (currentMessage().externalNumber()==5)
00380 std::cout<<"End of search trapped, "
00381 <<numberOptimal<<" optimal Lp's, "
00382 <<numberInfeasible
00383 <<" infeasible (including strong branching)"<<std::endl;
00384 return CoinMessageHandler::print();
00385 }
00386 return 0;
00387 }
00388 #include <stdio.h>
00389
00390 extern "C" void trapMessages(EKKModel * model, int msgno, int nreal,
00391 double * rvec, int nint, int * ivec,
00392 int nchar, char * cvec)
00393 {
00394
00395 char severity = cvec[nchar*128+8];
00396 char mainPart[153];
00397 strncpy(mainPart,cvec+nchar*128+9,152);
00398 mainPart[152]='\0';
00399 int length = strlen(mainPart);
00400 int i;
00401 for (i=length-1;i>=0;i--) {
00402 if (mainPart[i]!=' '&&mainPart[i]!='\t')
00403 break;
00404 }
00405 if (i>=0) {
00406 mainPart[i+1]='\0';
00407 CoinMessageHandler * handler = (CoinMessageHandler *) ekk_userData(model);
00408 handler->message(msgno,"Osl",mainPart,severity);
00409 for (i=0;i<nreal;i++)
00410 *handler<<rvec[i];
00411 for (i=0;i<nint;i++)
00412 *handler<<ivec[i];
00413 for (i=0;i<nchar;i++)
00414 *handler<<cvec+128*i;
00415 handler->finish();
00416 }
00417 return;
00418 }
00419
00420
00421 void
00422 OsiOslSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir)
00423 {
00424
00425
00426 {
00427 assert( OsiOslSolverInterface::getNumInstances()==0 );
00428 OsiOslSolverInterface m;
00429 assert( m.modelPtr_==NULL );
00430 assert( m.rowsense_==NULL );
00431 assert( m.rhs_==NULL );
00432 assert( m.rowrange_==NULL );
00433 assert( m.matrixByRow_==NULL );
00434 assert( m.matrixByColumn_==NULL );
00435 assert( OsiOslSolverInterface::getNumInstances()==1 );
00436 assert( m.getApplicationData() == NULL );
00437 int i=2346;
00438 m.setApplicationData(&i);
00439 assert( *((int *)(m.getApplicationData())) == i );
00440 }
00441 assert( OsiOslSolverInterface::getNumInstances()==0 );
00442
00443
00444 {
00445 CoinRelFltEq eq;
00446 OsiOslSolverInterface m;
00447 assert( OsiOslSolverInterface::getNumInstances()==1 );
00448 std::string fn = mpsDir+"exmip1";
00449 m.readMps(fn.c_str(),"mps");
00450 int ad = 13579;
00451 m.setApplicationData(&ad);
00452 assert( *((int *)(m.getApplicationData())) == ad );
00453
00454 {
00455 OsiOslSolverInterface im;
00456 assert( im.modelPtr_==NULL );
00457
00458 assert( im.getNumCols() == 0 );
00459
00460 assert( im.getModelPtr()!=NULL );
00461 assert( im.getMutableModelPtr()!=NULL );
00462 assert( im.getModelPtr() == im.getMutableModelPtr() );
00463 }
00464
00465
00466 {
00467 OsiOslSolverInterface lhs;
00468 {
00469 assert( *((int *)(m.getApplicationData())) == ad );
00470 OsiOslSolverInterface im(m);
00471 assert( *((int *)(im.getApplicationData())) == ad );
00472
00473 OsiOslSolverInterface imC1(im);
00474 assert( imC1.getMutableModelPtr()!=im.getMutableModelPtr() );
00475 assert( imC1.getModelPtr()!=im.getModelPtr() );
00476 assert( imC1.getNumCols() == im.getNumCols() );
00477 assert( imC1.getNumRows() == im.getNumRows() );
00478 assert( *((int *)(imC1.getApplicationData())) == ad );
00479
00480
00481
00482
00483 OsiOslSolverInterface imC2(im);
00484 assert( imC2.getMutableModelPtr()!=im.getMutableModelPtr() );
00485 assert( imC2.getModelPtr()!=im.getModelPtr() );
00486 assert( imC2.getNumCols() == im.getNumCols() );
00487 assert( imC2.getNumRows() == im.getNumRows() );
00488 assert( *((int *)(imC2.getApplicationData())) == ad );
00489
00490 assert( imC2.getMutableModelPtr()!=imC1.getMutableModelPtr() );
00491 assert( imC2.getModelPtr()!=imC1.getModelPtr() );
00492
00493 lhs=imC2;
00494 }
00495
00496
00497 assert( lhs.getMutableModelPtr() != m.getMutableModelPtr() );
00498 assert( lhs.getModelPtr() != m.getModelPtr() );
00499 assert( lhs.getNumCols() == m.getNumCols() );
00500 assert( lhs.getNumRows() == m.getNumRows() );
00501 assert( *((int *)(lhs.getApplicationData())) == ad );
00502 }
00503
00504
00505 {
00506 OsiOslSolverInterface oslSi(m);
00507 OsiSolverInterface * siPtr = &oslSi;
00508 OsiSolverInterface * siClone = siPtr->clone();
00509 OsiOslSolverInterface * oslClone = dynamic_cast<OsiOslSolverInterface*>(siClone);
00510 assert( oslClone != NULL );
00511 assert( oslClone->getModelPtr() != oslSi.getModelPtr() );
00512 assert( oslClone->getModelPtr() != m.getModelPtr() );
00513 assert( oslClone->getNumRows() == oslSi.getNumRows() );
00514 assert( oslClone->getNumCols() == m.getNumCols() );
00515
00516 assert( *((int *)(oslClone->getApplicationData())) == ad );
00517
00518 siClone->reset();
00519 assert( oslClone->rowsense_==NULL );
00520 assert( oslClone->rhs_==NULL );
00521 assert( oslClone->rowrange_==NULL );
00522 assert( oslClone->matrixByRow_==NULL );
00523 assert( oslClone->ws_==NULL);
00524 assert( oslClone->itlimOrig_==9999999);
00525 delete siClone;
00526 }
00527
00528
00529 {
00530 OsiOslSolverInterface si;
00531 assert( eq(si.getInfinity(),OSL_INFINITY));
00532 }
00533
00534
00535
00536 {
00537 OsiOslSolverInterface lhs;
00538 {
00539 assert( m.rowrange_==NULL );
00540 assert( m.rowsense_==NULL );
00541 assert( m.rhs_==NULL );
00542 assert( m.matrixByRow_==NULL );
00543
00544 OsiOslSolverInterface siC1(m);
00545 assert( siC1.rowrange_==NULL );
00546 assert( siC1.rowsense_==NULL );
00547 assert( siC1.rhs_==NULL );
00548 assert( siC1.matrixByRow_==NULL );
00549
00550 const char * siC1rs = siC1.getRowSense();
00551 assert( siC1rs[0]=='G' );
00552 assert( siC1rs[1]=='L' );
00553 assert( siC1rs[2]=='E' );
00554 assert( siC1rs[3]=='R' );
00555 assert( siC1rs[4]=='R' );
00556
00557 const double * siC1rhs = siC1.getRightHandSide();
00558 assert( eq(siC1rhs[0],2.5) );
00559 assert( eq(siC1rhs[1],2.1) );
00560 assert( eq(siC1rhs[2],4.0) );
00561 assert( eq(siC1rhs[3],5.0) );
00562 assert( eq(siC1rhs[4],15.) );
00563
00564 const double * siC1rr = siC1.getRowRange();
00565 assert( eq(siC1rr[0],0.0) );
00566 assert( eq(siC1rr[1],0.0) );
00567 assert( eq(siC1rr[2],0.0) );
00568 assert( eq(siC1rr[3],5.0-1.8) );
00569 assert( eq(siC1rr[4],15.0-3.0) );
00570
00571 const CoinPackedMatrix * siC1mbr = siC1.getMatrixByRow();
00572 assert( siC1mbr != NULL );
00573
00574 const double * ev = siC1mbr->getElements();
00575 assert( eq(ev[0], 3.0) );
00576 assert( eq(ev[1], 1.0) );
00577 assert( eq(ev[2], -2.0) );
00578 assert( eq(ev[3], -1.0) );
00579 assert( eq(ev[4], -1.0) );
00580 assert( eq(ev[5], 2.0) );
00581 assert( eq(ev[6], 1.1) );
00582 assert( eq(ev[7], 1.0) );
00583 assert( eq(ev[8], 1.0) );
00584 assert( eq(ev[9], 2.8) );
00585 assert( eq(ev[10], -1.2) );
00586 assert( eq(ev[11], 5.6) );
00587 assert( eq(ev[12], 1.0) );
00588 assert( eq(ev[13], 1.9) );
00589
00590 const int * mi = siC1mbr->getVectorStarts();
00591 assert( mi[0]==0 );
00592 assert( mi[1]==5 );
00593 assert( mi[2]==7 );
00594 assert( mi[3]==9 );
00595 assert( mi[4]==11 );
00596 assert( mi[5]==14 );
00597
00598 const int * ei = siC1mbr->getIndices();
00599 assert( ei[0] == 0 );
00600 assert( ei[1] == 1 );
00601 assert( ei[2] == 3 );
00602 assert( ei[3] == 4 );
00603 assert( ei[4] == 7 );
00604 assert( ei[5] == 1 );
00605 assert( ei[6] == 2 );
00606 assert( ei[7] == 2 );
00607 assert( ei[8] == 5 );
00608 assert( ei[9] == 3 );
00609 assert( ei[10] == 6 );
00610 assert( ei[11] == 0 );
00611 assert( ei[12] == 4 );
00612 assert( ei[13] == 7 );
00613
00614 assert( siC1mbr->getMajorDim() == 5 );
00615 assert( siC1mbr->getNumElements() == 14 );
00616
00617
00618 assert( siC1rs == siC1.getRowSense() );
00619 assert( siC1rhs == siC1.getRightHandSide() );
00620 assert( siC1rr == siC1.getRowRange() );
00621
00622
00623 OsiRowCut rc;
00624 rc.setLb(-DBL_MAX);
00625 rc.setUb( DBL_MAX);
00626 OsiCuts cuts;
00627 cuts.insert(rc);
00628 siC1.applyCuts(cuts);
00629
00630
00631
00632 assert( siC1.rowrange_==NULL );
00633 assert( siC1.rowsense_==NULL );
00634 assert( siC1.rhs_==NULL );
00635 assert( siC1.matrixByRow_==NULL );
00636
00637 siC1rs = siC1.getRowSense();
00638 assert( siC1rs[0]=='G' );
00639 assert( siC1rs[1]=='L' );
00640 assert( siC1rs[2]=='E' );
00641 assert( siC1rs[3]=='R' );
00642 assert( siC1rs[4]=='R' );
00643 assert( siC1rs[5]=='N' );
00644
00645 siC1rhs = siC1.getRightHandSide();
00646 assert( eq(siC1rhs[0],2.5) );
00647 assert( eq(siC1rhs[1],2.1) );
00648 assert( eq(siC1rhs[2],4.0) );
00649 assert( eq(siC1rhs[3],5.0) );
00650 assert( eq(siC1rhs[4],15.) );
00651 assert( eq(siC1rhs[5],0.0 ) );
00652
00653 siC1rr = siC1.getRowRange();
00654 assert( eq(siC1rr[0],0.0) );
00655 assert( eq(siC1rr[1],0.0) );
00656 assert( eq(siC1rr[2],0.0) );
00657 assert( eq(siC1rr[3],5.0-1.8) );
00658 assert( eq(siC1rr[4],15.0-3.0) );
00659 assert( eq(siC1rr[5],0.0) );
00660
00661 lhs=siC1;
00662 }
00663
00664 assert( lhs.rowrange_==NULL );
00665 assert( lhs.rowsense_==NULL );
00666 assert( lhs.rhs_==NULL );
00667 assert( lhs.matrixByRow_==NULL );
00668
00669 const char * lhsrs = lhs.getRowSense();
00670 assert( lhsrs[0]=='G' );
00671 assert( lhsrs[1]=='L' );
00672 assert( lhsrs[2]=='E' );
00673 assert( lhsrs[3]=='R' );
00674 assert( lhsrs[4]=='R' );
00675 assert( lhsrs[5]=='N' );
00676
00677 const double * lhsrhs = lhs.getRightHandSide();
00678 assert( eq(lhsrhs[0],2.5) );
00679 assert( eq(lhsrhs[1],2.1) );
00680 assert( eq(lhsrhs[2],4.0) );
00681 assert( eq(lhsrhs[3],5.0) );
00682 assert( eq(lhsrhs[4],15.) );
00683 assert( eq(lhsrhs[5],0.0) );
00684
00685 const double *lhsrr = lhs.getRowRange();
00686 assert( eq(lhsrr[0],0.0) );
00687 assert( eq(lhsrr[1],0.0) );
00688 assert( eq(lhsrr[2],0.0) );
00689 assert( eq(lhsrr[3],5.0-1.8) );
00690 assert( eq(lhsrr[4],15.0-3.0) );
00691 assert( eq(lhsrr[5],0.0) );
00692
00693 const CoinPackedMatrix * lhsmbr = lhs.getMatrixByRow();
00694 assert( lhsmbr != NULL );
00695 const double * ev = lhsmbr->getElements();
00696 assert( eq(ev[0], 3.0) );
00697 assert( eq(ev[1], 1.0) );
00698 assert( eq(ev[2], -2.0) );
00699 assert( eq(ev[3], -1.0) );
00700 assert( eq(ev[4], -1.0) );
00701 assert( eq(ev[5], 2.0) );
00702 assert( eq(ev[6], 1.1) );
00703 assert( eq(ev[7], 1.0) );
00704 assert( eq(ev[8], 1.0) );
00705 assert( eq(ev[9], 2.8) );
00706 assert( eq(ev[10], -1.2) );
00707 assert( eq(ev[11], 5.6) );
00708 assert( eq(ev[12], 1.0) );
00709 assert( eq(ev[13], 1.9) );
00710
00711 const int * mi = lhsmbr->getVectorStarts();
00712 assert( mi[0]==0 );
00713 assert( mi[1]==5 );
00714 assert( mi[2]==7 );
00715 assert( mi[3]==9 );
00716 assert( mi[4]==11 );
00717 assert( mi[5]==14 );
00718
00719 const int * ei = lhsmbr->getIndices();
00720 assert( ei[0] == 0 );
00721 assert( ei[1] == 1 );
00722 assert( ei[2] == 3 );
00723 assert( ei[3] == 4 );
00724 assert( ei[4] == 7 );
00725 assert( ei[5] == 1 );
00726 assert( ei[6] == 2 );
00727 assert( ei[7] == 2 );
00728 assert( ei[8] == 5 );
00729 assert( ei[9] == 3 );
00730 assert( ei[10] == 6 );
00731 assert( ei[11] == 0 );
00732 assert( ei[12] == 4 );
00733 assert( ei[13] == 7 );
00734
00735 int md = lhsmbr->getMajorDim();
00736 assert( md == 6 );
00737 assert( lhsmbr->getNumElements() == 14 );
00738 }
00739
00740 assert(OsiOslSolverInterface::getNumInstances()==1);
00741 }
00742 assert(OsiOslSolverInterface::getNumInstances()==0);
00743
00744
00745 {
00746 OsiOslSolverInterface m;
00747 OsiSolverInterfaceCommonUnitTest(&m, mpsDir, netlibDir );
00748 }
00749
00750
00751
00752
00753
00754
00755 int iPass;
00756 for (iPass=0;iPass<2;iPass++) {
00757 OsiOslSolverInterface m;
00758 std::string fn = mpsDir+"p0033";
00759 m.readMps(fn.c_str(),"mps");
00760
00761 OsiOslMessageTest messageHandler;
00762 if (iPass) {
00763 std::cout<<"Testing derived message handler"<<std::endl;
00764 m.passInMessageHandler(&messageHandler);
00765 ekk_registerMsguCallBack(m.getModelPtr(),trapMessages);
00766
00767 ekk_mset(m.getModelPtr(),1,0,-1,2,9999,0);
00768
00769 ekk_setUserData(m.getModelPtr(),&messageHandler);
00770 }
00771
00772 m.initialSolve();
00773
00774 ekk_messagePrintOff(m.getModelPtr() ,317);
00775 ekk_messagePrintOff(m.getModelPtr() ,318);
00776 ekk_messagePrintOff(m.getModelPtr() ,3048);
00777 ekk_messagePrintOff(m.getModelPtr() ,85);
00778 ekk_messagePrintOff(m.getModelPtr() ,82);
00779 ekk_messagePrintOff(m.getModelPtr() ,38);
00780
00781 if (m.isProvenOptimal()&&!m.isDualObjectiveLimitReached()) {
00782
00783
00784
00785 int numberIntegers=0;
00786 int numberColumns = m.getNumCols();
00787 int iColumn;
00788 int i;
00789 for (iColumn=0;iColumn<numberColumns;iColumn++) {
00790 if( m.isInteger(iColumn))
00791 numberIntegers++;
00792 }
00793 if (!numberIntegers) {
00794 std::cout<<"No integer variables"
00795 <<std::endl;
00796 return;
00797 }
00798 int * which = new int[numberIntegers];
00799 numberIntegers=0;
00800 for (iColumn=0;iColumn<numberColumns;iColumn++) {
00801 if( m.isInteger(iColumn))
00802 which[numberIntegers++]=iColumn;
00803 }
00804
00805
00806 OsiVectorNode branchingTree;
00807
00808
00809 branchingTree.push_back(OsiNodeSimple(m,numberIntegers,which));
00810
00811
00812 int numberIterations=0;
00813 int numberNodes =0;
00814
00815 OsiNodeSimple bestNode;
00816
00817 while (branchingTree.size()) {
00818
00819 OsiNodeSimple node = branchingTree.back();
00820 branchingTree.pop_back();
00821 numberNodes++;
00822 if (node.variable_>=0) {
00823
00824 for (i=0;i<numberIntegers;i++) {
00825 iColumn=which[i];
00826 m.setColBounds( iColumn,node.lower_[i],node.upper_[i]);
00827 }
00828
00829 m.setWarmStart(&node.basis_);
00830
00831 if (node.way_<0) {
00832 m.setColUpper(which[node.variable_],floor(node.value_));
00833
00834 if (node.way_==-1) {
00835 node.way_=+2;
00836 branchingTree.push_back(node);
00837 }
00838 } else {
00839 m.setColLower(which[node.variable_],ceil(node.value_));
00840
00841 if (node.way_==1) {
00842 node.way_=-2;
00843 branchingTree.push_back(node);
00844 }
00845 }
00846
00847 m.resolve();
00848 numberIterations += m.getIterationCount();
00849 if (!m.isIterationLimitReached()) {
00850 OsiNodeSimple newNode(m,numberIntegers,which);
00851
00852
00853 while (newNode.variable_==numberIntegers) {
00854 m.resolve();
00855 newNode = OsiNodeSimple(m,numberIntegers,which);
00856 }
00857 if (newNode.objectiveValue_<1.0e100) {
00858
00859 branchingTree.push_back(newNode);
00860 }
00861 } else {
00862
00863 std::cout<<"Exiting on maximum iterations"
00864 <<std::endl;
00865 break;
00866 }
00867 } else {
00868
00869 bestNode = node;
00870
00871 m.setDblParam(OsiDualObjectiveLimit,bestNode.objectiveValue_-1.0e-5);
00872 std::cout<<"Integer solution of "
00873 <<bestNode.objectiveValue_
00874 <<" found after "<<numberIterations
00875 <<" iterations and "<<numberNodes<<" nodes"
00876 <<std::endl;
00877 }
00878 }
00879 std::cout<<"Search took "
00880 <<numberIterations
00881 <<" iterations and "<<numberNodes<<" nodes"
00882 <<std::endl;
00883 if (bestNode.numberIntegers_) {
00884
00885
00886 for (i=0;i<numberIntegers;i++) {
00887 iColumn=which[i];
00888 m.setColBounds( iColumn,bestNode.lower_[i],bestNode.upper_[i]);
00889 }
00890
00891 m.setWarmStart(&bestNode.basis_);
00892 m.resolve();
00893 }
00894 delete [] which;
00895 } else {
00896 std::cout<<"The LP relaxation is infeasible"
00897 <<std::endl;
00898 throw CoinError("The LP relaxation is infeasible or too expensive",
00899 "branchAndBound", "OsiClpSolverInterface");
00900 }
00901 ekk_messagePrintOn(m.getModelPtr() ,317);
00902 ekk_messagePrintOn(m.getModelPtr() ,318);
00903 ekk_messagePrintOn(m.getModelPtr() ,3048);
00904 ekk_messagePrintOn(m.getModelPtr() ,85);
00905 ekk_messagePrintOn(m.getModelPtr() ,82);
00906 ekk_messagePrintOn(m.getModelPtr() ,38);
00907
00908 ekk_clearMsguCallBack(m.getModelPtr());
00909 ekk_setUserData(m.getModelPtr(),NULL);
00910 }
00911
00912 assert(OsiOslSolverInterface::getNumInstances()==0);
00913
00914 }