00001
00002
00003
00004 #include <cassert>
00005
00006 #include "CoinTime.hpp"
00007
00008 #include "CoinHelperFunctions.hpp"
00009 #include "CoinIndexedVector.hpp"
00010 #include "ClpDualRowSteepest.hpp"
00011 #include "ClpPrimalColumnSteepest.hpp"
00012 #include "ClpDualRowDantzig.hpp"
00013 #include "ClpPrimalColumnDantzig.hpp"
00014 #include "ClpFactorization.hpp"
00015 #include "ClpObjective.hpp"
00016 #include "ClpSimplex.hpp"
00017 #include "OsiClpSolverInterface.hpp"
00018 #include "OsiCuts.hpp"
00019 #include "OsiRowCut.hpp"
00020 #include "OsiColCut.hpp"
00021 #include "ClpPresolve.hpp"
00022
00023 static double totalTime=0.0;
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 void OsiClpSolverInterface::initialSolve()
00046 {
00047 ClpSimplex solver;
00048 double time1 = CoinCpuTime();
00049 solver.borrowModel(*modelPtr_);
00050
00051 solver.passInMessageHandler(handler_);
00052
00053 bool takeHint;
00054 OsiHintStrength strength;
00055
00056 bool gotHint = (getHintParam(OsiDoReducePrint,takeHint,strength));
00057 assert (gotHint);
00058 int saveMessageLevel=messageHandler()->logLevel();
00059 if (strength!=OsiHintIgnore&&takeHint) {
00060 if (saveMessageLevel)
00061 solver.messageHandler()->setLogLevel(saveMessageLevel-1);
00062 }
00063
00064 if (modelPtr_->solveType()==1) {
00065 gotHint = (getHintParam(OsiDoScale,takeHint,strength));
00066 assert (gotHint);
00067 if (strength==OsiHintIgnore||takeHint)
00068 solver.scaling(1);
00069 else
00070 solver.scaling(0);
00071 } else {
00072 solver.scaling(0);
00073 }
00074
00075
00076
00077 ClpDualRowSteepest steep;
00078 solver.setDualRowPivotAlgorithm(steep);
00079
00080 ClpPrimalColumnSteepest steepP;
00081 solver.setPrimalColumnPivotAlgorithm(steepP);
00082
00083
00084
00085
00086 bool doPrimal = (basis_.numberBasicStructurals()>0);
00087 setBasis(basis_,&solver);
00088
00089
00090
00091 int algorithm = 0;
00092 gotHint = (getHintParam(OsiDoDualInInitial,takeHint,strength));
00093 assert (gotHint);
00094 if (strength!=OsiHintIgnore)
00095 algorithm = takeHint ? -1 : 1;
00096
00097 int doCrash=0;
00098 gotHint = (getHintParam(OsiDoCrash,takeHint,strength));
00099 assert (gotHint);
00100 if (strength!=OsiHintIgnore)
00101 doCrash = takeHint ? 1 : -1;
00102
00103
00104 gotHint = (getHintParam(OsiDoPresolveInInitial,takeHint,strength));
00105 assert (gotHint);
00106 if (strength!=OsiHintIgnore&&takeHint) {
00107 ClpPresolve pinfo;
00108 ClpSimplex * model2 = pinfo.presolvedModel(solver,1.0e-8);
00109 if (!model2) {
00110
00111 model2 = &solver;
00112 }
00113
00114
00115 if (model2->factorization()->maximumPivots()==200)
00116 model2->factorization()->maximumPivots(100+model2->numberRows()/50);
00117 int savePerturbation = model2->perturbation();
00118 if (savePerturbation==100)
00119 model2->setPerturbation(50);
00120 if (!doPrimal) {
00121
00122
00123 model2->tightenPrimalBounds();
00124
00125 bool crashResult=false;
00126 if (doCrash>0)
00127 crashResult = (solver.crash(1000.0,1)>0);
00128 else if (doCrash==0&&algorithm>0)
00129 crashResult = (solver.crash(1000.0,1)>0);
00130 doPrimal=crashResult;
00131 }
00132 if (algorithm<0)
00133 doPrimal=false;
00134 else if (algorithm>0)
00135 doPrimal=true;
00136 if (!doPrimal) {
00137
00138
00139
00140
00141
00142 model2->dual();
00143
00144 if (model2->status()==3&&
00145 model2->numberIterations()<model2->maximumIterations()) {
00146
00147 model2->primal();
00148 }
00149 } else {
00150
00151
00152 model2->primal();
00153
00154 if (model2->status()==3
00155 &&model2->numberIterations()<model2->maximumIterations()) {
00156
00157 model2->dual();
00158 }
00159 }
00160 model2->setPerturbation(savePerturbation);
00161 if (model2!=&solver) {
00162 pinfo.postsolve(true);
00163
00164 delete model2;
00165
00166
00167 solver.primal(1);
00168 }
00169 lastAlgorithm_=1;
00170
00171
00172 } else {
00173 if (doPrimal) {
00174 if (doCrash>0)
00175 solver.crash(1000.0,2);
00176 else if (doCrash==0)
00177 solver.crash(1000.0,0);
00178 }
00179 if (algorithm<0)
00180 doPrimal=false;
00181 else if (algorithm>0)
00182 doPrimal=true;
00183 if (!doPrimal) {
00184
00185 solver.dual();
00186 lastAlgorithm_=2;
00187
00188 if (solver.status()==3&&solver.numberIterations()<solver.maximumIterations()) {
00189
00190 solver.primal();
00191 lastAlgorithm_=1;
00192 }
00193 } else {
00194
00195 solver.primal();
00196 lastAlgorithm_=1;
00197
00198 if (solver.status()==3&&solver.numberIterations()<solver.maximumIterations()) {
00199
00200 solver.dual();
00201 lastAlgorithm_=2;
00202 }
00203 }
00204 }
00205 basis_ = getBasis(&solver);
00206
00207 solver.messageHandler()->setLogLevel(saveMessageLevel);
00208 solver.returnModel(*modelPtr_);
00209 time1 = CoinCpuTime()-time1;
00210 totalTime += time1;
00211
00212 }
00213
00214
00215 void OsiClpSolverInterface::resolve()
00216 {
00217 ClpSimplex solver;
00218 solver.borrowModel(*modelPtr_);
00219
00220 solver.passInMessageHandler(handler_);
00221
00222 setBasis(basis_,&solver);
00223
00224 bool takeHint;
00225 OsiHintStrength strength;
00226
00227 bool gotHint = (getHintParam(OsiDoReducePrint,takeHint,strength));
00228 assert (gotHint);
00229 int saveMessageLevel=messageHandler()->logLevel();
00230 if (strength!=OsiHintIgnore&&takeHint) {
00231 if (saveMessageLevel)
00232 solver.messageHandler()->setLogLevel(saveMessageLevel-1);
00233 }
00234
00235 if (modelPtr_->solveType()==1) {
00236 gotHint = (getHintParam(OsiDoScale,takeHint,strength));
00237 assert (gotHint);
00238 if (strength==OsiHintIgnore||takeHint)
00239 solver.scaling(1);
00240 else
00241 solver.scaling(0);
00242 } else {
00243 solver.scaling(0);
00244 }
00245 ClpDualRowSteepest steep;
00246 solver.setDualRowPivotAlgorithm(steep);
00247
00248
00249 int algorithm = -1;
00250 gotHint = (getHintParam(OsiDoDualInResolve,takeHint,strength));
00251 assert (gotHint);
00252 if (strength!=OsiHintIgnore)
00253 algorithm = takeHint ? -1 : 1;
00254
00255
00256 gotHint = (getHintParam(OsiDoPresolveInResolve,takeHint,strength));
00257 assert (gotHint);
00258 if (strength!=OsiHintIgnore&&takeHint) {
00259 ClpPresolve pinfo;
00260 ClpSimplex * model2 = pinfo.presolvedModel(solver,1.0e-8);
00261 if (!model2) {
00262
00263 model2 = &solver;
00264 }
00265
00266 model2->factorization()->maximumPivots(100+model2->numberRows()/50);
00267 if (algorithm<0) {
00268
00269
00270 model2->dual();
00271
00272 if (model2->status()==3&&
00273 model2->numberIterations()<model2->maximumIterations()) {
00274
00275 model2->primal();
00276 }
00277 } else {
00278
00279
00280 model2->primal();
00281
00282 if (model2->status()==3
00283 &&model2->numberIterations()<model2->maximumIterations()) {
00284
00285 model2->dual();
00286 }
00287 }
00288 if (model2!=&solver) {
00289 pinfo.postsolve(true);
00290
00291 delete model2;
00292
00293 solver.primal(1);
00294 lastAlgorithm_=1;
00295 }
00296
00297
00298 } else {
00299 if (algorithm<0) {
00300
00301 solver.dual();
00302 lastAlgorithm_=2;
00303
00304 if (solver.status()==3&&solver.numberIterations()<solver.maximumIterations()) {
00305
00306 solver.primal();
00307 lastAlgorithm_=1;
00308 if (solver.status()==3&&
00309 solver.numberIterations()<solver.maximumIterations()) {
00310 printf("in trouble - try all slack\n");
00311 CoinWarmStartBasis allSlack;
00312 setBasis(allSlack,&solver);
00313 solver.primal();
00314 if (solver.status()==3&&
00315 solver.numberIterations()<solver.maximumIterations()) {
00316 printf("Real real trouble - treat as infeasible\n");
00317 solver.setProblemStatus(1);
00318 }
00319 }
00320 }
00321 } else {
00322
00323 solver.primal();
00324 lastAlgorithm_=1;
00325
00326 if (solver.status()==3&&solver.numberIterations()<solver.maximumIterations()) {
00327
00328 solver.dual();
00329 lastAlgorithm_=2;
00330 }
00331 }
00332 }
00333 basis_ = getBasis(&solver);
00334
00335 solver.messageHandler()->setLogLevel(saveMessageLevel);
00336 solver.returnModel(*modelPtr_);
00337 }
00338
00339
00340
00341
00342
00343 bool
00344 OsiClpSolverInterface::setIntParam(OsiIntParam key, int value)
00345 {
00346 std::map<OsiIntParam, ClpIntParam>::const_iterator clpkey =
00347 intParamMap_.find(key);
00348 if (clpkey != intParamMap_.end() ) {
00349 return modelPtr_->setIntParam(clpkey->second, value);
00350 }
00351 return false;
00352 }
00353
00354
00355
00356 bool
00357 OsiClpSolverInterface::setDblParam(OsiDblParam key, double value)
00358 {
00359 std::map<OsiDblParam, ClpDblParam>::const_iterator clpkey =
00360 dblParamMap_.find(key);
00361 if (clpkey != dblParamMap_.end() ) {
00362 if (key==OsiDualObjectiveLimit||key==OsiPrimalObjectiveLimit)
00363 value = modelPtr_->optimizationDirection()*value;
00364 return modelPtr_->setDblParam(clpkey->second, value);
00365 }
00366 return false;
00367 }
00368
00369
00370
00371 bool
00372 OsiClpSolverInterface::setStrParam(OsiStrParam key, const std::string & value)
00373 {
00374 std::map<OsiStrParam, ClpStrParam>::const_iterator clpkey =
00375 strParamMap_.find(key);
00376 if (clpkey != strParamMap_.end() ) {
00377 return modelPtr_->setStrParam(clpkey->second, value);
00378 }
00379 return false;
00380 }
00381
00382
00383
00384
00385 bool
00386 OsiClpSolverInterface::getIntParam(OsiIntParam key, int& value) const
00387 {
00388 std::map<OsiIntParam, ClpIntParam>::const_iterator clpkey =
00389 intParamMap_.find(key);
00390 if (clpkey != intParamMap_.end() ) {
00391 return modelPtr_->getIntParam(clpkey->second, value);
00392 }
00393 return false;
00394 }
00395
00396
00397
00398 bool
00399 OsiClpSolverInterface::getDblParam(OsiDblParam key, double& value) const
00400 {
00401 std::map<OsiDblParam, ClpDblParam>::const_iterator clpkey =
00402 dblParamMap_.find(key);
00403 if (clpkey != dblParamMap_.end() ) {
00404 bool condition = modelPtr_->getDblParam(clpkey->second, value);
00405 if (key==OsiDualObjectiveLimit||key==OsiPrimalObjectiveLimit)
00406 value = modelPtr_->optimizationDirection()*value;
00407 return condition;
00408 }
00409 return false;
00410 }
00411
00412
00413
00414 bool
00415 OsiClpSolverInterface::getStrParam(OsiStrParam key, std::string & value) const
00416 {
00417 if ( key==OsiSolverName ) {
00418 value = "clp";
00419 return true;
00420 }
00421 std::map<OsiStrParam, ClpStrParam>::const_iterator clpkey =
00422 strParamMap_.find(key);
00423 if (clpkey != strParamMap_.end() ) {
00424 return modelPtr_->getStrParam(clpkey->second, value);
00425 }
00426 return false;
00427 }
00428
00429
00430
00431
00432
00433
00434 bool OsiClpSolverInterface::isAbandoned() const
00435 {
00436
00437 return (modelPtr_->status()==4||modelPtr_->status()==-1);
00438 }
00439
00440 bool OsiClpSolverInterface::isProvenOptimal() const
00441 {
00442
00443 const int stat = modelPtr_->status();
00444 return (stat == 0);
00445 }
00446
00447 bool OsiClpSolverInterface::isProvenPrimalInfeasible() const
00448 {
00449
00450 const int stat = modelPtr_->status();
00451 if (stat != 1)
00452 return false;
00453 return true;
00454 }
00455
00456 bool OsiClpSolverInterface::isProvenDualInfeasible() const
00457 {
00458 const int stat = modelPtr_->status();
00459 return stat == 2;
00460 }
00461
00462
00463
00464
00465 bool OsiClpSolverInterface::isPrimalObjectiveLimitReached() const
00466 {
00467 double limit = 0.0;
00468 modelPtr_->getDblParam(ClpPrimalObjectiveLimit, limit);
00469 if (limit > 1e30) {
00470
00471 return false;
00472 }
00473
00474 const double obj = modelPtr_->objectiveValue();
00475 int maxmin = (int) modelPtr_->optimizationDirection();
00476
00477 switch (lastAlgorithm_) {
00478 case 0:
00479 return maxmin > 0 ? (obj < limit) : (-obj < limit) ;
00480 case 2:
00481 if (modelPtr_->status() == 0)
00482 return maxmin > 0 ? (obj < limit) : (-obj < limit) ;
00483 return false;
00484 case 1:
00485 return maxmin > 0 ? (obj < limit) : (-obj < limit) ;
00486 }
00487 return false;
00488 }
00489
00490 bool OsiClpSolverInterface::isDualObjectiveLimitReached() const
00491 {
00492
00493 double limit = 0.0;
00494 modelPtr_->getDblParam(ClpDualObjectiveLimit, limit);
00495 if (limit > 1e30) {
00496
00497 return false;
00498 }
00499
00500 const double obj = modelPtr_->objectiveValue();
00501 int maxmin = (int) modelPtr_->optimizationDirection();
00502
00503 switch (lastAlgorithm_) {
00504 case 0:
00505 return maxmin > 0 ? (obj > limit) : (-obj > limit) ;
00506 case 1:
00507 if (modelPtr_->status() == 0)
00508 return maxmin > 0 ? (obj > limit) : (-obj > limit) ;
00509 return false;
00510 case 2:
00511 if (modelPtr_->status() != 0 && modelPtr_->status() != 3)
00512
00513 return true;
00514 return maxmin > 0 ? (obj > limit) : (-obj > limit) ;
00515 }
00516 return false;
00517 }
00518
00519 bool OsiClpSolverInterface::isIterationLimitReached() const
00520 {
00521 const int stat = modelPtr_->status();
00522 return (stat == 3);
00523 }
00524
00525
00526
00527
00528 CoinWarmStart *OsiClpSolverInterface::getEmptyWarmStart () const
00529 { return (dynamic_cast<CoinWarmStart *>(new CoinWarmStartBasis())) ; }
00530
00531 CoinWarmStart* OsiClpSolverInterface::getWarmStart() const
00532 {
00533
00534 return new CoinWarmStartBasis(basis_);
00535 }
00536
00537
00538
00539 bool OsiClpSolverInterface::setWarmStart(const CoinWarmStart* warmstart)
00540 {
00541
00542 const CoinWarmStartBasis* ws =
00543 dynamic_cast<const CoinWarmStartBasis*>(warmstart);
00544
00545 if (! ws)
00546 return false;
00547 basis_ = CoinWarmStartBasis(*ws);
00548 return true;
00549
00550 }
00551
00552
00553
00554
00555
00556 void OsiClpSolverInterface::markHotStart()
00557 {
00558 delete ws_;
00559 ws_ = dynamic_cast<CoinWarmStartBasis*>(getWarmStart());
00560 int numberRows = modelPtr_->numberRows();
00561 rowActivity_= new double[numberRows];
00562 memcpy(rowActivity_,modelPtr_->primalRowSolution(),
00563 numberRows*sizeof(double));
00564 int numberColumns = modelPtr_->numberColumns();
00565 columnActivity_= new double[numberColumns];
00566 memcpy(columnActivity_,modelPtr_->primalColumnSolution(),
00567 numberColumns*sizeof(double));
00568
00569 }
00570
00571 void OsiClpSolverInterface::solveFromHotStart()
00572 {
00573 setWarmStart(ws_);
00574 int numberRows = modelPtr_->numberRows();
00575 memcpy(modelPtr_->primalRowSolution(),
00576 rowActivity_,numberRows*sizeof(double));
00577 int numberColumns = modelPtr_->numberColumns();
00578 memcpy(modelPtr_->primalColumnSolution(),columnActivity_,
00579 numberColumns*sizeof(double));
00580 bool takeHint;
00581 OsiHintStrength strength;
00582
00583 bool gotHint = (getHintParam(OsiDoReducePrint,takeHint,strength));
00584 assert (gotHint);
00585 int saveMessageLevel=messageHandler()->logLevel();
00586 if (strength!=OsiHintIgnore&&takeHint) {
00587 if (saveMessageLevel)
00588 messageHandler()->setLogLevel(saveMessageLevel-1);
00589 }
00590 messageHandler()->setLogLevel(saveMessageLevel);
00591
00592 modelPtr_->getIntParam(ClpMaxNumIteration,itlimOrig_);
00593 int itlim;
00594 modelPtr_->getIntParam(ClpMaxNumIterationHotStart, itlim);
00595 modelPtr_->setIntParam(ClpMaxNumIteration,itlim);
00596 resolve();
00597 modelPtr_->setIntParam(ClpMaxNumIteration,itlimOrig_);
00598 }
00599
00600 void OsiClpSolverInterface::unmarkHotStart()
00601 {
00602 delete ws_;
00603 ws_ = NULL;
00604 delete [] rowActivity_;
00605 delete [] columnActivity_;
00606 rowActivity_=NULL;
00607 columnActivity_=NULL;
00608 }
00609
00610
00611
00612
00613
00614
00615 const char * OsiClpSolverInterface::getRowSense() const
00616 {
00617 extractSenseRhsRange();
00618 return rowsense_;
00619 }
00620
00621 const double * OsiClpSolverInterface::getRightHandSide() const
00622 {
00623 extractSenseRhsRange();
00624 return rhs_;
00625 }
00626
00627 const double * OsiClpSolverInterface::getRowRange() const
00628 {
00629 extractSenseRhsRange();
00630 return rowrange_;
00631 }
00632
00633
00634
00635 bool OsiClpSolverInterface::isContinuous(int colNumber) const
00636 {
00637 if ( integerInformation_==NULL ) return true;
00638 if ( integerInformation_[colNumber]==0 ) return true;
00639 return false;
00640 }
00641
00642
00643
00644
00645
00646 const CoinPackedMatrix * OsiClpSolverInterface::getMatrixByRow() const
00647 {
00648 if ( matrixByRow_ == NULL ) {
00649 matrixByRow_ = new CoinPackedMatrix();
00650 matrixByRow_->reverseOrderedCopyOf(*modelPtr_->matrix());
00651 matrixByRow_->removeGaps();
00652 #if 0
00653 CoinPackedMatrix back;
00654 std::cout<<"start check"<<std::endl;
00655 back.reverseOrderedCopyOf(*matrixByRow_);
00656 modelPtr_->matrix()->isEquivalent2(back);
00657 std::cout<<"stop check"<<std::endl;
00658 #endif
00659 }
00660 return matrixByRow_;
00661 }
00662
00663 const CoinPackedMatrix * OsiClpSolverInterface::getMatrixByCol() const
00664 {
00665 return modelPtr_->matrix();
00666 }
00667
00668
00669 std::vector<double*> OsiClpSolverInterface::getDualRays(int maxNumRays) const
00670 {
00671 return std::vector<double*>(1, modelPtr_->infeasibilityRay());
00672 }
00673
00674 std::vector<double*> OsiClpSolverInterface::getPrimalRays(int maxNumRays) const
00675 {
00676 return std::vector<double*>(1, modelPtr_->unboundedRay());
00677 }
00678
00679
00680
00681 void OsiClpSolverInterface::setColSetBounds(const int* indexFirst,
00682 const int* indexLast,
00683 const double* boundList)
00684 {
00685 double * lower = modelPtr_->columnLower();
00686 double * upper = modelPtr_->columnUpper();
00687 while (indexFirst != indexLast) {
00688 const int iCol=*indexFirst++;
00689 lower[iCol]= forceIntoRange(*boundList++, -OsiClpInfinity, OsiClpInfinity);
00690 upper[iCol]= forceIntoRange(*boundList++, -OsiClpInfinity, OsiClpInfinity);
00691 }
00692 if (modelPtr_->solveType()==2) {
00693
00694 double * lower = modelPtr_->lowerRegion(1);
00695 double * upper = modelPtr_->upperRegion(1);
00696 while (indexFirst != indexLast) {
00697 const int iCol=*indexFirst++;
00698 lower[iCol]= forceIntoRange(*boundList++, -OsiClpInfinity, OsiClpInfinity);
00699 upper[iCol]= forceIntoRange(*boundList++, -OsiClpInfinity, OsiClpInfinity);
00700 }
00701
00702 }
00703 }
00704
00705 void
00706 OsiClpSolverInterface::setRowType(int i, char sense, double rightHandSide,
00707 double range)
00708 {
00709
00710 double lower, upper;
00711 convertSenseToBound(sense, rightHandSide, range, lower, upper);
00712 setRowBounds(i, lower, upper);
00713 }
00714
00715 void OsiClpSolverInterface::setRowSetBounds(const int* indexFirst,
00716 const int* indexLast,
00717 const double* boundList)
00718 {
00719 double * lower = modelPtr_->rowLower();
00720 double * upper = modelPtr_->rowUpper();
00721 const int len = indexLast - indexFirst;
00722 while (indexFirst != indexLast) {
00723 const int iRow=*indexFirst++;
00724 lower[iRow]= forceIntoRange(*boundList++, -OsiClpInfinity, OsiClpInfinity);
00725 upper[iRow]= forceIntoRange(*boundList++, -OsiClpInfinity, OsiClpInfinity);
00726 }
00727 if (rowsense_ != NULL) {
00728 assert ((rhs_ != NULL) && (rowrange_ != NULL));
00729 indexFirst -= len;
00730 while (indexFirst != indexLast) {
00731 const int iRow=*indexFirst++;
00732 convertBoundToSense(lower[iRow], upper[iRow],
00733 rowsense_[iRow], rhs_[iRow], rowrange_[iRow]);
00734 }
00735 }
00736 }
00737
00738 void
00739 OsiClpSolverInterface::setRowSetTypes(const int* indexFirst,
00740 const int* indexLast,
00741 const char* senseList,
00742 const double* rhsList,
00743 const double* rangeList)
00744 {
00745 double * lower = modelPtr_->rowLower();
00746 double * upper = modelPtr_->rowUpper();
00747 const int len = indexLast - indexFirst;
00748 while (indexFirst != indexLast) {
00749 const int iRow= *indexFirst++;
00750 if (rangeList){
00751 convertSenseToBound(*senseList++, *rhsList++, *rangeList++,
00752 lower[iRow], upper[iRow]);
00753 } else {
00754 convertSenseToBound(*senseList++, *rhsList++, 0,
00755 lower[iRow], upper[iRow]);
00756 }
00757 }
00758 if (rowsense_ != NULL) {
00759 assert ((rhs_ != NULL) && (rowrange_ != NULL));
00760 indexFirst -= len;
00761 senseList -= len;
00762 rhsList -= len;
00763 if (rangeList)
00764 rangeList -= len;
00765 while (indexFirst != indexLast) {
00766 const int iRow=*indexFirst++;
00767 rowsense_[iRow] = *senseList++;
00768 rhs_[iRow] = *rhsList++;
00769 if (rangeList)
00770 rowrange_[iRow] = *rangeList++;
00771 }
00772 }
00773 }
00774
00775 void
00776 OsiClpSolverInterface::setContinuous(int index)
00777 {
00778
00779 if (integerInformation_) {
00780 integerInformation_[index]=0;
00781 }
00782 }
00783
00784 void
00785 OsiClpSolverInterface::setInteger(int index)
00786 {
00787 if (!integerInformation_) {
00788 integerInformation_ = new char[modelPtr_->numberColumns()];
00789 CoinFillN ( integerInformation_, modelPtr_->numberColumns(),(char) 0);
00790 }
00791 integerInformation_[index]=1;
00792 }
00793
00794 void
00795 OsiClpSolverInterface::setContinuous(const int* indices, int len)
00796 {
00797 if (integerInformation_) {
00798 int i;
00799 for (i=0; i<len;i++) {
00800 integerInformation_[i]=0;
00801 }
00802 }
00803 }
00804
00805 void
00806 OsiClpSolverInterface::setInteger(const int* indices, int len)
00807 {
00808 if (!integerInformation_) {
00809 integerInformation_ = new char[modelPtr_->numberColumns()];
00810 CoinFillN ( integerInformation_, modelPtr_->numberColumns(),(char) 0);
00811 }
00812 int i;
00813 for (i=0; i<len;i++) {
00814 integerInformation_[indices[i]]=1;
00815 }
00816 }
00817
00818 void OsiClpSolverInterface::setColSolution(const double * cs)
00819 {
00820 CoinDisjointCopyN(cs,modelPtr_->numberColumns(),
00821 modelPtr_->primalColumnSolution());
00822 if (modelPtr_->solveType()==2) {
00823
00824 CoinDisjointCopyN(cs,modelPtr_->numberColumns(),
00825 modelPtr_->solutionRegion(1));
00826 }
00827 }
00828
00829 void OsiClpSolverInterface::setRowPrice(const double * rs)
00830 {
00831 CoinDisjointCopyN(rs,modelPtr_->numberRows(),
00832 modelPtr_->dualRowSolution());
00833 if (modelPtr_->solveType()==2) {
00834
00835 CoinDisjointCopyN(rs,modelPtr_->numberRows(),
00836 modelPtr_->djRegion(0));
00837 }
00838 }
00839
00840
00841
00842
00843 void
00844 OsiClpSolverInterface::addCol(const CoinPackedVectorBase& vec,
00845 const double collb, const double colub,
00846 const double obj)
00847 {
00848 int numberColumns = modelPtr_->numberColumns();
00849 modelPtr_->resize(modelPtr_->numberRows(),numberColumns+1);
00850 linearObjective_ = modelPtr_->objective();
00851 basis_.resize(modelPtr_->numberRows(),numberColumns+1);
00852 setColBounds(numberColumns,collb,colub);
00853 setObjCoeff(numberColumns,obj);
00854 if (!modelPtr_->clpMatrix())
00855 modelPtr_->createEmptyMatrix();
00856 modelPtr_->matrix()->appendCol(vec);
00857 if (integerInformation_) {
00858 char * temp = new char[numberColumns+1];
00859 memcpy(temp,integerInformation_,numberColumns*sizeof(char));
00860 delete [] integerInformation_;
00861 integerInformation_ = temp;
00862 integerInformation_[numberColumns]=0;
00863 }
00864 freeCachedResults();
00865 }
00866
00867 void
00868 OsiClpSolverInterface::addCols(const int numcols,
00869 const CoinPackedVectorBase * const * cols,
00870 const double* collb, const double* colub,
00871 const double* obj)
00872 {
00873 int numberColumns = modelPtr_->numberColumns();
00874 modelPtr_->resize(modelPtr_->numberRows(),numberColumns+numcols);
00875 linearObjective_ = modelPtr_->objective();
00876 basis_.resize(modelPtr_->numberRows(),numberColumns+numcols);
00877 double * lower = modelPtr_->columnLower()+numberColumns;
00878 double * upper = modelPtr_->columnUpper()+numberColumns;
00879 double * objective = modelPtr_->objective()+numberColumns;
00880 int iCol;
00881 for (iCol = 0; iCol < numcols; iCol++) {
00882 lower[iCol]= forceIntoRange(collb[iCol], -OsiClpInfinity, OsiClpInfinity);
00883 upper[iCol]= forceIntoRange(colub[iCol], -OsiClpInfinity, OsiClpInfinity);
00884 objective[iCol] = obj[iCol];
00885 }
00886 if (!modelPtr_->clpMatrix())
00887 modelPtr_->createEmptyMatrix();
00888 modelPtr_->matrix()->appendCols(numcols,cols);
00889 if (integerInformation_) {
00890 char * temp = new char[numberColumns+numcols];
00891 memcpy(temp,integerInformation_,numberColumns*sizeof(char));
00892 delete [] integerInformation_;
00893 integerInformation_ = temp;
00894 for (iCol = 0; iCol < numcols; iCol++)
00895 integerInformation_[numberColumns+iCol]=0;
00896 }
00897 freeCachedResults();
00898 }
00899
00900 void
00901 OsiClpSolverInterface::deleteCols(const int num, const int * columnIndices)
00902 {
00903 modelPtr_->deleteColumns(num,columnIndices);
00904 basis_.deleteColumns(num,columnIndices);
00905 linearObjective_ = modelPtr_->objective();
00906 freeCachedResults();
00907 }
00908
00909 void
00910 OsiClpSolverInterface::addRow(const CoinPackedVectorBase& vec,
00911 const double rowlb, const double rowub)
00912 {
00913 int numberRows = modelPtr_->numberRows();
00914 modelPtr_->resize(numberRows+1,modelPtr_->numberColumns());
00915 basis_.resize(numberRows+1,modelPtr_->numberColumns());
00916 setRowBounds(numberRows,rowlb,rowub);
00917 if (!modelPtr_->clpMatrix())
00918 modelPtr_->createEmptyMatrix();
00919 modelPtr_->matrix()->appendRow(vec);
00920 freeCachedResults();
00921 }
00922
00923 void
00924 OsiClpSolverInterface::addRow(const CoinPackedVectorBase& vec,
00925 const char rowsen, const double rowrhs,
00926 const double rowrng)
00927 {
00928 int numberRows = modelPtr_->numberRows();
00929 modelPtr_->resize(numberRows+1,modelPtr_->numberColumns());
00930 basis_.resize(numberRows+1,modelPtr_->numberColumns());
00931 double rowlb, rowub;
00932 convertSenseToBound(rowsen, rowrhs, rowrng, rowlb, rowub);
00933 setRowBounds(numberRows,rowlb,rowub);
00934 if (!modelPtr_->clpMatrix())
00935 modelPtr_->createEmptyMatrix();
00936 modelPtr_->matrix()->appendRow(vec);
00937 freeCachedResults();
00938 }
00939
00940 void
00941 OsiClpSolverInterface::addRows(const int numrows,
00942 const CoinPackedVectorBase * const * rows,
00943 const double* rowlb, const double* rowub)
00944 {
00945 int numberRows = modelPtr_->numberRows();
00946 modelPtr_->resize(numberRows+numrows,modelPtr_->numberColumns());
00947 basis_.resize(numberRows+numrows,modelPtr_->numberColumns());
00948 double * lower = modelPtr_->rowLower()+numberRows;
00949 double * upper = modelPtr_->rowUpper()+numberRows;
00950 int iRow;
00951 for (iRow = 0; iRow < numrows; iRow++) {
00952 lower[iRow]= forceIntoRange(rowlb[iRow], -OsiClpInfinity, OsiClpInfinity);
00953 upper[iRow]= forceIntoRange(rowub[iRow], -OsiClpInfinity, OsiClpInfinity);
00954 }
00955 if (!modelPtr_->clpMatrix())
00956 modelPtr_->createEmptyMatrix();
00957 modelPtr_->matrix()->appendRows(numrows,rows);
00958 freeCachedResults();
00959 }
00960
00961 void
00962 OsiClpSolverInterface::addRows(const int numrows,
00963 const CoinPackedVectorBase * const * rows,
00964 const char* rowsen, const double* rowrhs,
00965 const double* rowrng)
00966 {
00967 int numberRows = modelPtr_->numberRows();
00968 modelPtr_->resize(numberRows+numrows,modelPtr_->numberColumns());
00969 basis_.resize(numberRows+numrows,modelPtr_->numberColumns());
00970 double * lower = modelPtr_->rowLower()+numberRows;
00971 double * upper = modelPtr_->rowUpper()+numberRows;
00972 int iRow;
00973 for (iRow = 0; iRow < numrows; iRow++) {
00974 double rowlb, rowub;
00975 convertSenseToBound(rowsen[iRow], rowrhs[iRow], rowrng[iRow],
00976 rowlb, rowub);
00977 lower[iRow]= forceIntoRange(rowlb, -OsiClpInfinity, OsiClpInfinity);
00978 upper[iRow]= forceIntoRange(rowub, -OsiClpInfinity, OsiClpInfinity);
00979 }
00980 if (!modelPtr_->clpMatrix())
00981 modelPtr_->createEmptyMatrix();
00982 modelPtr_->matrix()->appendRows(numrows,rows);
00983 freeCachedResults();
00984 }
00985
00986 void
00987 OsiClpSolverInterface::deleteRows(const int num, const int * rowIndices)
00988 {
00989 modelPtr_->deleteRows(num,rowIndices);
00990 basis_.deleteRows(num,rowIndices);
00991 freeCachedResults();
00992 }
00993
00994
00995
00996
00997
00998 void
00999 OsiClpSolverInterface::loadProblem(const CoinPackedMatrix& matrix,
01000 const double* collb, const double* colub,
01001 const double* obj,
01002 const double* rowlb, const double* rowub)
01003 {
01004 modelPtr_->loadProblem(matrix, collb, colub, obj, rowlb, rowub);
01005 linearObjective_ = modelPtr_->objective();
01006 freeCachedResults();
01007
01008 }
01009
01010
01011
01012 void
01013 OsiClpSolverInterface::assignProblem(CoinPackedMatrix*& matrix,
01014 double*& collb, double*& colub,
01015 double*& obj,
01016 double*& rowlb, double*& rowub)
01017 {
01018 modelPtr_->loadProblem(*matrix, collb, colub, obj, rowlb, rowub);
01019 linearObjective_ = modelPtr_->objective();
01020
01021 freeCachedResults();
01022 delete matrix; matrix = NULL;
01023 delete[] collb; collb = NULL;
01024 delete[] colub; colub = NULL;
01025 delete[] obj; obj = NULL;
01026 delete[] rowlb; rowlb = NULL;
01027 delete[] rowub; rowub = NULL;
01028 }
01029
01030
01031
01032 void
01033 OsiClpSolverInterface::loadProblem(const CoinPackedMatrix& matrix,
01034 const double* collb, const double* colub,
01035 const double* obj,
01036 const char* rowsen, const double* rowrhs,
01037 const double* rowrng)
01038 {
01039 assert( rowsen != NULL );
01040 assert( rowrhs != NULL );
01041 int numrows = matrix.getNumRows();
01042 double * rowlb = new double[numrows];
01043 double * rowub = new double[numrows];
01044 for (int i = numrows-1; i >= 0; --i) {
01045 convertSenseToBound(rowsen[i],rowrhs[i],rowrng[i],rowlb[i],rowub[i]);
01046 }
01047 modelPtr_->loadProblem(matrix, collb, colub, obj, rowlb, rowub);
01048 linearObjective_ = modelPtr_->objective();
01049 freeCachedResults();
01050 delete [] rowlb;
01051 delete [] rowub;
01052 }
01053
01054
01055
01056 void
01057 OsiClpSolverInterface::assignProblem(CoinPackedMatrix*& matrix,
01058 double*& collb, double*& colub,
01059 double*& obj,
01060 char*& rowsen, double*& rowrhs,
01061 double*& rowrng)
01062 {
01063 loadProblem(*matrix, collb, colub, obj, rowsen, rowrhs, rowrng);
01064 linearObjective_ = modelPtr_->objective();
01065 delete matrix; matrix = NULL;
01066 delete[] collb; collb = NULL;
01067 delete[] colub; colub = NULL;
01068 delete[] obj; obj = NULL;
01069 delete[] rowsen; rowsen = NULL;
01070 delete[] rowrhs; rowrhs = NULL;
01071 delete[] rowrng; rowrng = NULL;
01072 }
01073
01074
01075
01076 void
01077 OsiClpSolverInterface::loadProblem(const int numcols, const int numrows,
01078 const int* start, const int* index,
01079 const double* value,
01080 const double* collb, const double* colub,
01081 const double* obj,
01082 const double* rowlb, const double* rowub)
01083 {
01084 modelPtr_->loadProblem(numcols, numrows, start, index,
01085 value, collb, colub, obj,
01086 rowlb, rowub);
01087 linearObjective_ = modelPtr_->objective();
01088 freeCachedResults();
01089 }
01090
01091
01092 void
01093 OsiClpSolverInterface::loadProblem(const int numcols, const int numrows,
01094 const int* start, const int* index,
01095 const double* value,
01096 const double* collb, const double* colub,
01097 const double* obj,
01098 const char* rowsen, const double* rowrhs,
01099 const double* rowrng)
01100 {
01101 assert( rowsen != NULL );
01102 assert( rowrhs != NULL );
01103 double * rowlb = new double[numrows];
01104 double * rowub = new double[numrows];
01105 for (int i = numrows-1; i >= 0; --i) {
01106 convertSenseToBound(rowsen[i],rowrhs[i],rowrng[i],rowlb[i],rowub[i]);
01107 }
01108 modelPtr_->loadProblem(numcols, numrows, start, index,
01109 value, collb, colub, obj,
01110 rowlb, rowub);
01111 linearObjective_ = modelPtr_->objective();
01112 freeCachedResults();
01113 delete[] rowlb;
01114 delete[] rowub;
01115 }
01116
01117
01118
01119
01120
01121 void OsiClpSolverInterface::writeMps(const char * filename,
01122 const char * extension,
01123 double objSense) const
01124 {
01125 std::string f(filename);
01126 std::string e(extension);
01127 std::string fullname;
01128 if (e!="") {
01129 fullname = f + "." + e;
01130 } else {
01131
01132 fullname = f;
01133 }
01134
01135 OsiSolverInterface::writeMpsNative(fullname.c_str(),
01136 NULL, NULL,0,2,objSense);
01137 }
01138
01139 int
01140 OsiClpSolverInterface::writeMpsNative(const char *filename,
01141 const char ** rowNames, const char ** columnNames,
01142 int formatType,int numberAcross,double objSense) const
01143 {
01144 return OsiSolverInterface::writeMpsNative(filename, rowNames, columnNames,
01145 formatType, numberAcross,objSense);
01146 }
01147
01148
01149
01150
01151
01152 ClpSimplex * OsiClpSolverInterface::getModelPtr() const
01153 {
01154 freeCachedResults();
01155 return modelPtr_;
01156 }
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167 OsiClpSolverInterface::OsiClpSolverInterface ()
01168 :
01169 OsiSolverInterface(),
01170 linearObjective_(NULL),
01171 rowsense_(NULL),
01172 rhs_(NULL),
01173 rowrange_(NULL),
01174 ws_(NULL),
01175 rowActivity_(NULL),
01176 columnActivity_(NULL),
01177 matrixByRow_(NULL),
01178 integerInformation_(NULL)
01179 {
01180 modelPtr_=NULL;
01181 notOwned_=false;
01182 reset();
01183 }
01184
01185
01186
01187
01188 OsiSolverInterface * OsiClpSolverInterface::clone(bool CopyData) const
01189 {
01190 if (CopyData) {
01191 return new OsiClpSolverInterface(*this);
01192 } else {
01193 return new OsiClpSolverInterface();
01194 }
01195 }
01196
01197
01198
01199
01200
01201 OsiClpSolverInterface::OsiClpSolverInterface (
01202 const OsiClpSolverInterface & rhs)
01203 :
01204 OsiSolverInterface(rhs),
01205 rowsense_(NULL),
01206 rhs_(NULL),
01207 rowrange_(NULL),
01208 ws_(NULL),
01209 rowActivity_(NULL),
01210 columnActivity_(NULL),
01211 basis_(),
01212 itlimOrig_(9999999),
01213 lastAlgorithm_(0),
01214 notOwned_(false),
01215 matrixByRow_(NULL),
01216 integerInformation_(NULL)
01217 {
01218 if ( rhs.modelPtr_ )
01219 modelPtr_ = new ClpSimplex(*rhs.modelPtr_);
01220 else
01221 modelPtr_ = new ClpSimplex();
01222 linearObjective_ = modelPtr_->objective();
01223 if ( rhs.ws_ )
01224 ws_ = new CoinWarmStartBasis(*rhs.ws_);
01225 basis_ = rhs.basis_;
01226 if (rhs.integerInformation_) {
01227 int numberColumns = modelPtr_->numberColumns();
01228 integerInformation_ = new char[numberColumns];
01229 memcpy(integerInformation_,rhs.integerInformation_,
01230 numberColumns*sizeof(char));
01231 }
01232 saveData_ = rhs.saveData_;
01233 fillParamMaps();
01234 messageHandler()->setLogLevel(rhs.messageHandler()->logLevel());
01235 }
01236
01237
01238 OsiClpSolverInterface::OsiClpSolverInterface (ClpSimplex * rhs)
01239 :
01240 OsiSolverInterface(),
01241 rowsense_(NULL),
01242 rhs_(NULL),
01243 rowrange_(NULL),
01244 ws_(NULL),
01245 rowActivity_(NULL),
01246 columnActivity_(NULL),
01247 basis_(),
01248 itlimOrig_(9999999),
01249 lastAlgorithm_(0),
01250 notOwned_(false),
01251 matrixByRow_(NULL),
01252 integerInformation_(NULL)
01253 {
01254 modelPtr_ = rhs;
01255 linearObjective_ = modelPtr_->objective();
01256 if (rhs) {
01257 notOwned_=true;
01258
01259 if (rhs->integerInformation()) {
01260 int numberColumns = modelPtr_->numberColumns();
01261 integerInformation_ = new char[numberColumns];
01262 memcpy(integerInformation_,rhs->integerInformation(),
01263 numberColumns*sizeof(char));
01264 }
01265 }
01266 fillParamMaps();
01267 }
01268
01269
01270 void
01271 OsiClpSolverInterface::releaseClp()
01272 {
01273 modelPtr_=NULL;
01274 notOwned_=false;
01275 }
01276
01277
01278
01279
01280
01281 OsiClpSolverInterface::~OsiClpSolverInterface ()
01282 {
01283 freeCachedResults();
01284 if (!notOwned_)
01285 delete modelPtr_;
01286 delete ws_;
01287 delete [] rowActivity_;
01288 delete [] columnActivity_;
01289 delete [] integerInformation_;
01290 }
01291
01292
01293
01294
01295 OsiClpSolverInterface &
01296 OsiClpSolverInterface::operator=(const OsiClpSolverInterface& rhs)
01297 {
01298 if (this != &rhs) {
01299 OsiSolverInterface::operator=(rhs);
01300 freeCachedResults();
01301 if (!notOwned_)
01302 delete modelPtr_;
01303 delete ws_;
01304 if ( rhs.modelPtr_ )
01305 modelPtr_ = new ClpSimplex(*rhs.modelPtr_);
01306 notOwned_=false;
01307 linearObjective_ = modelPtr_->objective();
01308
01309 if ( rhs.ws_ )
01310 ws_ = new CoinWarmStartBasis(*rhs.ws_);
01311 delete [] rowActivity_;
01312 delete [] columnActivity_;
01313 rowActivity_=NULL;
01314 columnActivity_=NULL;
01315 basis_ = rhs.basis_;
01316 intParamMap_ = rhs.intParamMap_;
01317 dblParamMap_ = rhs.dblParamMap_;
01318 strParamMap_ = rhs.strParamMap_;
01319 messageHandler()->setLogLevel(rhs.messageHandler()->logLevel());
01320 }
01321 return *this;
01322 }
01323
01324
01325
01326
01327
01328 void OsiClpSolverInterface::applyRowCut( const OsiRowCut & rowCut )
01329 {
01330 const CoinPackedVector & row=rowCut.row();
01331 addRow(row , rowCut.lb(),rowCut.ub());
01332 }
01333
01334
01335
01336 void
01337 OsiClpSolverInterface::applyRowCuts(int numberCuts, const OsiRowCut * cuts)
01338 {
01339 int i;
01340 if (!numberCuts)
01341 return;
01342
01343 const CoinPackedVectorBase * * rows
01344 = new const CoinPackedVectorBase * [numberCuts];
01345 double * rowlb = new double [numberCuts];
01346 double * rowub = new double [numberCuts];
01347 for (i=0;i<numberCuts;i++) {
01348 rowlb[i] = cuts[i].lb();
01349 rowub[i] = cuts[i].ub();
01350 rows[i] = &cuts[i].row();
01351 #ifdef TAKEOUT
01352 if (rows[i]->getNumElements()==10||rows[i]->getNumElements()==15)
01353 printf("ApplyCuts %d size %d\n",getNumRows()+i,rows[i]->getNumElements());
01354 #endif
01355 }
01356 addRows(numberCuts,rows,rowlb,rowub);
01357 delete [] rows;
01358 delete [] rowlb;
01359 delete [] rowub;
01360
01361 }
01362
01363
01364
01365 void OsiClpSolverInterface::applyColCut( const OsiColCut & cc )
01366 {
01367 double * lower = modelPtr_->columnLower();
01368 double * upper = modelPtr_->columnUpper();
01369 const CoinPackedVector & lbs = cc.lbs();
01370 const CoinPackedVector & ubs = cc.ubs();
01371 int i;
01372
01373 for ( i=0; i<lbs.getNumElements(); i++ ) {
01374 int iCol = lbs.getIndices()[i];
01375 double value = lbs.getElements()[i];
01376 if ( value > lower[iCol] )
01377 lower[iCol]= value;
01378 }
01379 for ( i=0; i<ubs.getNumElements(); i++ ) {
01380 int iCol = ubs.getIndices()[i];
01381 double value = ubs.getElements()[i];
01382 if ( value < upper[iCol] )
01383 upper[iCol]= value;
01384 }
01385 }
01386
01387
01388
01389
01390
01391
01392
01393 void OsiClpSolverInterface::freeCachedResults() const
01394 {
01395 delete [] rowsense_;
01396 delete [] rhs_;
01397 delete [] rowrange_;
01398 delete matrixByRow_;
01399 delete ws_;
01400 rowsense_=NULL;
01401 rhs_=NULL;
01402 rowrange_=NULL;
01403 matrixByRow_=NULL;
01404 ws_ = NULL;
01405 }
01406
01407
01408 void OsiClpSolverInterface::extractSenseRhsRange() const
01409 {
01410 if (rowsense_ == NULL) {
01411
01412 assert ((rhs_ == NULL) && (rowrange_ == NULL));
01413
01414 int nr=modelPtr_->numberRows();
01415 if ( nr!=0 ) {
01416 rowsense_ = new char[nr];
01417 rhs_ = new double[nr];
01418 rowrange_ = new double[nr];
01419 std::fill(rowrange_,rowrange_+nr,0.0);
01420
01421 const double * lb = modelPtr_->rowLower();
01422 const double * ub = modelPtr_->rowUpper();
01423
01424 int i;
01425 for ( i=0; i<nr; i++ ) {
01426 convertBoundToSense(lb[i], ub[i], rowsense_[i], rhs_[i], rowrange_[i]);
01427 }
01428 }
01429 }
01430 }
01431
01432 void
01433 OsiClpSolverInterface::newLanguage(CoinMessages::Language language)
01434 {
01435 modelPtr_->newLanguage(language);
01436 OsiSolverInterface::newLanguage(language);
01437 }
01438
01439
01440 void
01441 OsiClpSolverInterface::fillParamMaps()
01442 {
01443 intParamMap_[OsiMaxNumIteration] = ClpMaxNumIteration;
01444 intParamMap_[OsiMaxNumIterationHotStart] = ClpMaxNumIterationHotStart;
01445 intParamMap_[OsiLastIntParam] = ClpLastIntParam;
01446
01447 dblParamMap_[OsiDualObjectiveLimit] = ClpDualObjectiveLimit;
01448 dblParamMap_[OsiPrimalObjectiveLimit] = ClpPrimalObjectiveLimit;
01449 dblParamMap_[OsiDualTolerance] = ClpDualTolerance;
01450 dblParamMap_[OsiPrimalTolerance] = ClpPrimalTolerance;
01451 dblParamMap_[OsiObjOffset] = ClpObjOffset;
01452 dblParamMap_[OsiLastDblParam] = ClpLastDblParam;
01453
01454 strParamMap_[OsiProbName] = ClpProbName;
01455 strParamMap_[OsiLastStrParam] = ClpLastStrParam;
01456 }
01457
01458 CoinWarmStartBasis
01459 OsiClpSolverInterface::getBasis(ClpSimplex * model) const
01460 {
01461 int iRow,iColumn;
01462 int numberRows = model->numberRows();
01463 int numberColumns = model->numberColumns();
01464 CoinWarmStartBasis basis;
01465 basis.setSize(numberColumns,numberRows);
01466
01467 if (model->statusExists()) {
01468 int lookup[]={0,1,2,3,0,3};
01469 for (iRow=0;iRow<numberRows;iRow++) {
01470 int iStatus = model->getRowStatus(iRow);
01471 iStatus = lookup[iStatus];
01472 basis.setArtifStatus(iRow,(CoinWarmStartBasis::Status) iStatus);
01473 }
01474 for (iColumn=0;iColumn<numberColumns;iColumn++) {
01475 int iStatus = model->getColumnStatus(iColumn);
01476 iStatus = lookup[iStatus];
01477 basis.setStructStatus(iColumn,(CoinWarmStartBasis::Status) iStatus);
01478 }
01479 }
01480
01481 return basis;
01482 }
01483
01484 void
01485 OsiClpSolverInterface::setBasis ( const CoinWarmStartBasis & basis,
01486 ClpSimplex * model)
01487 {
01488
01489 int iRow,iColumn;
01490 int numberRows = model->numberRows();
01491 int numberColumns = model->numberColumns();
01492 if (!model->statusExists()) {
01493
01494
01495
01496
01497
01498 model->createStatus();
01499 }
01500 CoinWarmStartBasis basis2 = basis;
01501
01502 basis2.resize(numberRows,numberColumns);
01503
01504 model->createStatus();
01505 for (iRow=0;iRow<numberRows;iRow++) {
01506 model->setRowStatus(iRow,
01507 (ClpSimplex::Status) basis2.getArtifStatus(iRow));
01508 }
01509 for (iColumn=0;iColumn<numberColumns;iColumn++) {
01510 model->setColumnStatus(iColumn,
01511 (ClpSimplex::Status) basis2.getStructStatus(iColumn));
01512 }
01513 }
01514
01515
01516 int
01517 OsiClpSolverInterface::readMps(const char *filename,
01518 const char *extension )
01519 {
01520
01521 delete [] integerInformation_;
01522 integerInformation_=NULL;
01523
01524 int numberErrors = OsiSolverInterface::readMps(filename,extension);
01525
01526 int numberColumns = modelPtr_->numberColumns();
01527 int i;
01528 char * info = new char [numberColumns];
01529 int numberIntegers=0;
01530 for (i=0;i<numberColumns;i++) {
01531 if (isInteger(i)) {
01532 info[i]=1;
01533 numberIntegers++;
01534 } else {
01535 info[i]=0;
01536 }
01537 }
01538 if (numberIntegers)
01539 modelPtr_->copyInIntegerInformation(info);
01540 delete [] info;
01541 return numberErrors;
01542 }
01543
01544 const double *
01545 OsiClpSolverInterface::getColSolution() const
01546 {
01547 if (modelPtr_->solveType()!=2) {
01548 return modelPtr_->primalColumnSolution();
01549 } else {
01550
01551 return modelPtr_->solutionRegion(1);
01552 }
01553 }
01554
01555
01556 const double *
01557 OsiClpSolverInterface::getRowPrice() const
01558 {
01559 if (modelPtr_->solveType()!=2) {
01560 return modelPtr_->dualRowSolution();
01561 } else {
01562
01563
01564 return modelPtr_->dualRowSolution();
01565 }
01566 }
01567
01568
01569 const double *
01570 OsiClpSolverInterface::getReducedCost() const
01571 {
01572 if (modelPtr_->solveType()!=2) {
01573 return modelPtr_->dualColumnSolution();
01574 } else {
01575
01576 return modelPtr_->djRegion(1);
01577 }
01578 }
01579
01580
01581
01582 const double *
01583 OsiClpSolverInterface::getRowActivity() const
01584 {
01585 if (modelPtr_->solveType()!=2) {
01586 return modelPtr_->primalRowSolution();
01587 } else {
01588
01589 return modelPtr_->solutionRegion(0);
01590 }
01591 }
01592
01593 void
01594 OsiClpSolverInterface::setObjCoeff( int elementIndex, double elementValue )
01595 {
01596 linearObjective_[elementIndex] = elementValue;
01597 if (modelPtr_->solveType()==2) {
01598
01599 modelPtr_->costRegion(1)[elementIndex] = elementValue;
01600 }
01601 }
01602
01603
01604
01605 void
01606 OsiClpSolverInterface::setColLower( int elementIndex, double elementValue )
01607 {
01608 modelPtr_->columnLower()[elementIndex] = elementValue;
01609 if (modelPtr_->solveType()==2) {
01610
01611 modelPtr_->lowerRegion(1)[elementIndex] = elementValue;
01612 }
01613 }
01614
01615
01616
01617 void
01618 OsiClpSolverInterface::setColUpper( int elementIndex, double elementValue )
01619 {
01620 modelPtr_->columnUpper()[elementIndex] = elementValue;
01621 if (modelPtr_->solveType()==2) {
01622
01623 modelPtr_->upperRegion(1)[elementIndex] = elementValue;
01624 }
01625 }
01626
01627
01628 void
01629 OsiClpSolverInterface::setColBounds( int elementIndex,
01630 double lower, double upper )
01631 {
01632 modelPtr_->columnLower()[elementIndex] = lower;
01633 modelPtr_->columnUpper()[elementIndex] = upper;
01634 if (modelPtr_->solveType()==2) {
01635
01636 modelPtr_->lowerRegion(1)[elementIndex] = lower;
01637 modelPtr_->upperRegion(1)[elementIndex] = upper;
01638 }
01639 }
01640
01641
01642
01643
01644
01645 void
01646 OsiClpSolverInterface::enableSimplexInterface(bool doingPrimal)
01647 {
01648 assert (modelPtr_->solveType()==1);
01649 modelPtr_->setSolveType(2);
01650 if (doingPrimal)
01651 modelPtr_->setAlgorithm(1);
01652 else
01653 modelPtr_->setAlgorithm(-1);
01654 modelPtr_->scaling(0);
01655
01656 saveData_ = modelPtr_->saveData();
01657
01658 modelPtr_->setInfeasibilityCost(1.0e12);
01659
01660 ClpDualRowDantzig dantzig;
01661 modelPtr_->setDualRowPivotAlgorithm(dantzig);
01662 ClpPrimalColumnDantzig dantzigP;
01663 modelPtr_->setPrimalColumnPivotAlgorithm(dantzigP);
01664 assert (!modelPtr_->startup(0));
01665 }
01666
01667
01668 void
01669 OsiClpSolverInterface::disableSimplexInterface()
01670 {
01671 assert (modelPtr_->solveType()==2);
01672
01673 modelPtr_->setProblemStatus(0);
01674 modelPtr_->setSolveType(1);
01675 modelPtr_->finish();
01676 modelPtr_->restoreData(saveData_);
01677 basis_ = getBasis(modelPtr_);
01678 }
01679
01680
01681
01682
01683
01684
01685
01686
01687 void
01688 OsiClpSolverInterface::getBasisStatus(int* cstat, int* rstat)
01689 {
01690 assert (modelPtr_->solveType()==2);
01691 int i, n;
01692 n=modelPtr_->numberRows();
01693 int lookup[]={0,1,2,3,0,3};
01694 for (i=0;i<n;i++)
01695 rstat[i] = lookup[modelPtr_->getRowStatus(i)];
01696 n=modelPtr_->numberColumns();
01697 for (i=0;i<n;i++)
01698 cstat[i] = lookup[modelPtr_->getColumnStatus(i)];
01699 }
01700
01701
01702 int
01703 OsiClpSolverInterface::setBasisStatus(const int* cstat, const int* rstat)
01704 {
01705 assert (modelPtr_->solveType()==2);
01706 modelPtr_->createStatus();
01707 int i, n;
01708 double * lower, * upper, * solution;
01709 n=modelPtr_->numberRows();
01710 lower = modelPtr_->rowLower();
01711 upper = modelPtr_->rowUpper();
01712 solution = modelPtr_->primalRowSolution();
01713 for (i=0;i<n;i++) {
01714 int status = rstat[i];
01715 if (status<0||status>3)
01716 status = 3;
01717 if (lower[i]<-1.0e50&&upper[i]>1.0e50&&status!=1)
01718 status = 0;
01719 else if (lower[i]<-1.0e50&&status==3)
01720 status = 2;
01721 else if (upper[i]>1.0e50&&status==2)
01722 status = 3;
01723 switch (status) {
01724
01725 case 0:
01726 if (lower[i]<-1.0e50&&upper[i]>1.0e50) {
01727 modelPtr_->setRowStatus(i,ClpSimplex::isFree);
01728 if (fabs(solution[i])>1.0e20)
01729 solution[i]=0.0;
01730 } else {
01731 modelPtr_->setRowStatus(i,ClpSimplex::superBasic);
01732 if (fabs(solution[i])>1.0e20)
01733 solution[i]=0.0;
01734 }
01735 break;
01736 case 1:
01737
01738 modelPtr_->setRowStatus(i,ClpSimplex::basic);
01739 break;
01740 case 2:
01741
01742 solution[i]=upper[i];
01743 if (upper[i]>lower[i])
01744 modelPtr_->setRowStatus(i,ClpSimplex::atUpperBound);
01745 else
01746 modelPtr_->setRowStatus(i,ClpSimplex::isFixed);
01747 break;
01748 case 3:
01749
01750 solution[i]=lower[i];
01751 if (upper[i]>lower[i])
01752 modelPtr_->setRowStatus(i,ClpSimplex::atLowerBound);
01753 else
01754 modelPtr_->setRowStatus(i,ClpSimplex::isFixed);
01755 break;
01756 }
01757 }
01758 n=modelPtr_->numberColumns();
01759 lower = modelPtr_->columnLower();
01760 upper = modelPtr_->columnUpper();
01761 solution = modelPtr_->primalColumnSolution();
01762 for (i=0;i<n;i++) {
01763 int status = cstat[i];
01764 if (status<0||status>3)
01765 status = 3;
01766 if (lower[i]<-1.0e50&&upper[i]>1.0e50&&status!=1)
01767 status = 0;
01768 else if (lower[i]<-1.0e50&&status==3)
01769 status = 2;
01770 else if (upper[i]>1.0e50&&status==2)
01771 status = 3;
01772 switch (status) {
01773
01774 case 0:
01775 if (lower[i]<-1.0e50&&upper[i]>1.0e50) {
01776 modelPtr_->setColumnStatus(i,ClpSimplex::isFree);
01777 if (fabs(solution[i])>1.0e20)
01778 solution[i]=0.0;
01779 } else {
01780 modelPtr_->setColumnStatus(i,ClpSimplex::superBasic);
01781 if (fabs(solution[i])>1.0e20)
01782 solution[i]=0.0;
01783 }
01784 break;
01785 case 1:
01786
01787 modelPtr_->setColumnStatus(i,ClpSimplex::basic);
01788 break;
01789 case 2:
01790
01791 solution[i]=upper[i];
01792 if (upper[i]>lower[i])
01793 modelPtr_->setColumnStatus(i,ClpSimplex::atUpperBound);
01794 else
01795 modelPtr_->setColumnStatus(i,ClpSimplex::isFixed);
01796 break;
01797 case 3:
01798
01799 solution[i]=lower[i];
01800 if (upper[i]>lower[i])
01801 modelPtr_->setColumnStatus(i,ClpSimplex::atLowerBound);
01802 else
01803 modelPtr_->setColumnStatus(i,ClpSimplex::isFixed);
01804 break;
01805 }
01806 }
01807 modelPtr_->statusOfProblem();
01808 return 0;
01809 }
01810
01811
01812
01813
01814
01815 int
01816 OsiClpSolverInterface::pivot(int colIn, int colOut, int outStatus)
01817 {
01818 assert (modelPtr_->solveType()==2);
01819
01820 if (colIn<0)
01821 colIn = modelPtr_->numberColumns()+(-1-colIn);
01822 if (colOut<0)
01823 colOut = modelPtr_->numberColumns()+(-1-colOut);
01824
01825 outStatus = - outStatus;
01826
01827 modelPtr_->setDirectionOut(outStatus);
01828 modelPtr_->setSequenceIn(colIn);
01829 modelPtr_->setSequenceOut(colOut);
01830
01831 modelPtr_->pivot();
01832 return 0;
01833 }
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845 int
01846 OsiClpSolverInterface::primalPivotResult(int colIn, int sign,
01847 int& colOut, int& outStatus,
01848 double& t, CoinPackedVector* dx)
01849 {
01850 assert (modelPtr_->solveType()==2);
01851
01852 if (colIn<0)
01853 colIn = modelPtr_->numberColumns()+(-1-colIn);
01854
01855 modelPtr_->setDirectionIn(sign);
01856 modelPtr_->setSequenceIn(colIn);
01857 modelPtr_->setSequenceOut(-1);
01858 int returnCode = modelPtr_->primalPivotResult();
01859 t = modelPtr_->theta();
01860 int numberColumns = modelPtr_->numberColumns();
01861 if (dx) {
01862 double * ray = modelPtr_->unboundedRay();
01863 if (ray)
01864 dx->setFullNonZero(numberColumns,ray);
01865 else
01866 printf("No ray?\n");
01867 delete [] ray;
01868 }
01869 outStatus = - modelPtr_->directionOut();
01870 colOut = modelPtr_->sequenceOut();
01871 if (colOut>= numberColumns)
01872 colOut = -1-(colOut - numberColumns);
01873 return returnCode;
01874 }
01875
01876
01877
01878
01879
01880
01881
01882 int
01883 OsiClpSolverInterface::dualPivotResult(int& colIn, int& sign,
01884 int colOut, int outStatus,
01885 double& t, CoinPackedVector* dx)
01886 {
01887 assert (modelPtr_->solveType()==2);
01888 abort();
01889 return 0;
01890 }
01891
01892
01893 void
01894 OsiClpSolverInterface::getReducedGradient(
01895 double* columnReducedCosts,
01896 double * duals,
01897 const double * c)
01898 {
01899 assert (modelPtr_->solveType()==2);
01900
01901
01902 int numberColumns = modelPtr_->numberColumns();
01903 double * save = new double [numberColumns];
01904 memcpy(save,modelPtr_->costRegion(),numberColumns*sizeof(double));
01905 memcpy(modelPtr_->costRegion(),c,numberColumns*sizeof(double));
01906 modelPtr_->computeDuals(NULL);
01907 memcpy(modelPtr_->costRegion(),save,numberColumns*sizeof(double));
01908 delete [] save;
01909 int numberRows = modelPtr_->numberRows();
01910 memcpy(duals,modelPtr_->dualRowSolution(),numberRows*sizeof(double));
01911 memcpy(columnReducedCosts,modelPtr_->djRegion(1),
01912 numberColumns*sizeof(double));
01913 }
01914
01915
01916
01917 void OsiClpSolverInterface::setObjectiveAndRefresh(double* c)
01918 {
01919 assert (modelPtr_->solveType()==2);
01920 int numberColumns = modelPtr_->numberColumns();
01921 memcpy(modelPtr_->objective(),c,numberColumns*sizeof(double));
01922 memcpy(modelPtr_->costRegion(),c,numberColumns*sizeof(double));
01923 modelPtr_->computeDuals(NULL);
01924 }
01925
01926
01927 void
01928 OsiClpSolverInterface::getBInvARow(int row, double* z)
01929 {
01930 assert (modelPtr_->solveType()==2);
01931 ClpFactorization * factorization = modelPtr_->factorization();
01932 CoinIndexedVector * rowArray0 = modelPtr_->rowArray(0);
01933 CoinIndexedVector * rowArray1 = modelPtr_->rowArray(1);
01934 CoinIndexedVector * columnArray0 = modelPtr_->columnArray(0);
01935 CoinIndexedVector * columnArray1 = modelPtr_->columnArray(1);
01936 rowArray0->clear();
01937 rowArray1->clear();
01938 columnArray0->clear();
01939 columnArray1->clear();
01940
01941 rowArray1->insert(row,1.0);
01942 factorization->updateColumnTranspose(rowArray0,rowArray1);
01943
01944 modelPtr_->clpMatrix()->transposeTimes(modelPtr_,1.0,
01945 rowArray0,columnArray1,columnArray0);
01946 memcpy(z,columnArray0->denseVector(),
01947 modelPtr_->numberColumns()*sizeof(double));
01948
01949 rowArray0->clear();
01950 rowArray1->clear();
01951 columnArray0->clear();
01952 columnArray1->clear();
01953 }
01954
01955
01956 void
01957 OsiClpSolverInterface::getBInvRow(int row, double* z)
01958
01959 {
01960 assert (modelPtr_->solveType()==2);
01961 ClpFactorization * factorization = modelPtr_->factorization();
01962 CoinIndexedVector * rowArray0 = modelPtr_->rowArray(0);
01963 CoinIndexedVector * rowArray1 = modelPtr_->rowArray(1);
01964 rowArray0->clear();
01965 rowArray1->clear();
01966
01967 rowArray1->insert(row,1.0);
01968 factorization->updateColumnTranspose(rowArray0,rowArray1);
01969 memcpy(z,rowArray1->denseVector(),modelPtr_->numberRows()*sizeof(double));
01970 rowArray1->clear();
01971 }
01972
01973
01974 void
01975 OsiClpSolverInterface::getBInvACol(int col, double* vec)
01976 {
01977 assert (modelPtr_->solveType()==2);
01978 ClpFactorization * factorization = modelPtr_->factorization();
01979 CoinIndexedVector * rowArray0 = modelPtr_->rowArray(0);
01980 CoinIndexedVector * rowArray1 = modelPtr_->rowArray(1);
01981 rowArray0->clear();
01982 rowArray1->clear();
01983
01984 assert(col>=0&&col<modelPtr_->numberColumns());
01985 modelPtr_->unpack(rowArray1,col);
01986 factorization->updateColumn(rowArray0,rowArray1,false);
01987 memcpy(vec,rowArray1->denseVector(),modelPtr_->numberRows()*sizeof(double));
01988 rowArray1->clear();
01989 }
01990
01991
01992 void
01993 OsiClpSolverInterface::getBInvCol(int col, double* vec)
01994 {
01995 assert (modelPtr_->solveType()==2);
01996 ClpFactorization * factorization = modelPtr_->factorization();
01997 CoinIndexedVector * rowArray0 = modelPtr_->rowArray(0);
01998 CoinIndexedVector * rowArray1 = modelPtr_->rowArray(1);
01999 rowArray0->clear();
02000 rowArray1->clear();
02001
02002 rowArray1->insert(col,1.0);
02003 factorization->updateColumn(rowArray0,rowArray1,false);
02004 memcpy(vec,rowArray1->denseVector(),modelPtr_->numberRows()*sizeof(double));
02005 rowArray1->clear();
02006 }
02007
02008
02009
02010
02011
02012 void
02013 OsiClpSolverInterface::getBasics(int* index)
02014 {
02015 assert (modelPtr_->solveType()==2);
02016 assert (index);
02017 memcpy(index,modelPtr_->pivotVariable(),
02018 modelPtr_->numberRows()*sizeof(int));
02019 }
02020
02021 void
02022 OsiClpSolverInterface::reset()
02023 {
02024 setInitialData();
02025 freeCachedResults();
02026 if (!notOwned_)
02027 delete modelPtr_;
02028 delete ws_;
02029 delete [] rowActivity_;
02030 delete [] columnActivity_;
02031 delete [] integerInformation_;
02032 rowActivity_ = NULL;
02033 columnActivity_ = NULL;
02034 integerInformation_ = NULL;
02035 basis_ = CoinWarmStartBasis();
02036 itlimOrig_=9999999;
02037 lastAlgorithm_=0;
02038 notOwned_=false;
02039 modelPtr_ = new ClpSimplex();
02040
02041
02042 linearObjective_ = NULL;
02043 fillParamMaps();
02044 }
02045