Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

OsiClpSolverInterface.cpp

00001 // Copyright (C) 2002, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
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 //  static double cpuTime()
00025 //  {
00026 //    double cpu_temp;
00027 //  #if defined(_MSC_VER)
00028 //    unsigned int ticksnow;        /* clock_t is same as int */
00029   
00030 //    ticksnow = (unsigned int)clock();
00031   
00032 //    cpu_temp = (double)((double)ticksnow/CLOCKS_PER_SEC);
00033 //  #else
00034 //    struct rusage usage;
00035 //    getrusage(RUSAGE_SELF,&usage);
00036 //    cpu_temp = usage.ru_utime.tv_sec;
00037 //    cpu_temp += 1.0e-6*((double) usage.ru_utime.tv_usec);
00038 //  #endif
00039 //    return cpu_temp;
00040 //  }
00041 
00042 //#############################################################################
00043 // Solve methods
00044 //#############################################################################
00045 void OsiClpSolverInterface::initialSolve()
00046 {
00047   ClpSimplex solver;
00048   double time1 = CoinCpuTime();
00049   solver.borrowModel(*modelPtr_);
00050   // Set message handler to have same levels etc
00051   solver.passInMessageHandler(handler_);
00052   // set reasonable defaults
00053   bool takeHint;
00054   OsiHintStrength strength;
00055   // Switch off printing if asked to
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   // scaling
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   //solver.setDualBound(1.0e6);
00075   //solver.setDualTolerance(1.0e-7);
00076 
00077   ClpDualRowSteepest steep;
00078   solver.setDualRowPivotAlgorithm(steep);
00079   //solver.setPrimalTolerance(1.0e-8);
00080   ClpPrimalColumnSteepest steepP;
00081   solver.setPrimalColumnPivotAlgorithm(steepP);
00082   /*
00083     If basis then do primal (as user could do dual with resolve)
00084     If not then see if dual feasible (and allow for gubs etc?)
00085    */
00086   bool doPrimal = (basis_.numberBasicStructurals()>0);
00087   setBasis(basis_,&solver);
00088 
00089   // sort out hints;
00090   // algorithm 0 whatever, -1 force dual, +1 force primal
00091   int algorithm = 0;
00092   gotHint = (getHintParam(OsiDoDualInInitial,takeHint,strength));
00093   assert (gotHint);
00094   if (strength!=OsiHintIgnore)
00095     algorithm = takeHint ? -1 : 1;
00096   // crash 0 do lightweight if all slack, 1 do, -1 don't
00097   int doCrash=0;
00098   gotHint = (getHintParam(OsiDoCrash,takeHint,strength));
00099   assert (gotHint);
00100   if (strength!=OsiHintIgnore)
00101     doCrash = takeHint ? 1 : -1;
00102          
00103   // presolve
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       // problem found to be infeasible - whats best?
00111       model2 = &solver;
00112     }
00113       
00114     // change from 200 (unless changed)
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       // faster if bounds tightened
00122       //int numberInfeasibilities = model2->tightenPrimalBounds();
00123       model2->tightenPrimalBounds();
00124       // look further
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       //if (numberInfeasibilities)
00138       //std::cout<<"** Analysis indicates model infeasible"
00139       //       <<std::endl;
00140       // up dual bound for safety
00141       //model2->setDualBound(1.0e11);
00142       model2->dual();
00143       // check if clp thought it was in a loop
00144       if (model2->status()==3&&
00145           model2->numberIterations()<model2->maximumIterations()) {
00146         // switch algorithm
00147         model2->primal();
00148       }
00149     } else {
00150       // up infeasibility cost for safety
00151       //model2->setInfeasibilityCost(1.0e10);
00152       model2->primal();
00153       // check if clp thought it was in a loop
00154       if (model2->status()==3
00155           &&model2->numberIterations()<model2->maximumIterations()) {
00156         // switch algorithm
00157         model2->dual();
00158       }
00159     }
00160     model2->setPerturbation(savePerturbation);
00161     if (model2!=&solver) {
00162       pinfo.postsolve(true);
00163     
00164       delete model2;
00165       //printf("Resolving from postsolved model\n");
00166       // later try without (1) and check duals before solve
00167       solver.primal(1);
00168     }
00169     lastAlgorithm_=1; // primal
00170     //if (solver.numberIterations())
00171     //printf("****** iterated %d\n",solver.numberIterations());
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       //printf("doing dual\n");
00185       solver.dual();
00186       lastAlgorithm_=2; // dual
00187       // check if clp thought it was in a loop
00188       if (solver.status()==3&&solver.numberIterations()<solver.maximumIterations()) {
00189         // switch algorithm
00190         solver.primal();
00191         lastAlgorithm_=1; // primal
00192       }
00193     } else {
00194       //printf("doing primal\n");
00195       solver.primal();
00196       lastAlgorithm_=1; // primal
00197       // check if clp thought it was in a loop
00198       if (solver.status()==3&&solver.numberIterations()<solver.maximumIterations()) {
00199         // switch algorithm
00200         solver.dual();
00201         lastAlgorithm_=2; // dual
00202       }
00203     }
00204   }
00205   basis_ = getBasis(&solver);
00206   //basis_.print();
00207   solver.messageHandler()->setLogLevel(saveMessageLevel);
00208   solver.returnModel(*modelPtr_);
00209   time1 = CoinCpuTime()-time1;
00210   totalTime += time1;
00211   //std::cout<<time1<<" seconds - total "<<totalTime<<std::endl;
00212 }
00213 
00214 //-----------------------------------------------------------------------------
00215 void OsiClpSolverInterface::resolve()
00216 {
00217   ClpSimplex solver;
00218   solver.borrowModel(*modelPtr_);
00219   // Set message handler to have same levels etc
00220   solver.passInMessageHandler(handler_);
00221   //basis_.print();
00222   setBasis(basis_,&solver);
00223   // set reasonable defaults
00224   bool takeHint;
00225   OsiHintStrength strength;
00226   // Switch off printing if asked to
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   // scaling
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   // sort out hints;
00248   // algorithm -1 force dual, +1 force primal
00249   int algorithm = -1;
00250   gotHint = (getHintParam(OsiDoDualInResolve,takeHint,strength));
00251   assert (gotHint);
00252   if (strength!=OsiHintIgnore)
00253     algorithm = takeHint ? -1 : 1;
00254   //solver.saveModel("save.bad");
00255   // presolve
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       // problem found to be infeasible - whats best?
00263       model2 = &solver;
00264     }
00265     // change from 200
00266     model2->factorization()->maximumPivots(100+model2->numberRows()/50);
00267     if (algorithm<0) {
00268       // up dual bound for safety
00269       //model2->setDualBound(1.0e10);
00270       model2->dual();
00271       // check if clp thought it was in a loop
00272       if (model2->status()==3&&
00273           model2->numberIterations()<model2->maximumIterations()) {
00274         // switch algorithm
00275         model2->primal();
00276       }
00277     } else {
00278       // up infeasibility cost for safety
00279       //model2->setInfeasibilityCost(1.0e10);
00280       model2->primal();
00281       // check if clp thought it was in a loop
00282       if (model2->status()==3
00283           &&model2->numberIterations()<model2->maximumIterations()) {
00284         // switch algorithm
00285         model2->dual();
00286       }
00287     }
00288     if (model2!=&solver) {
00289       pinfo.postsolve(true);
00290     
00291       delete model2;
00292       // later try without (1) and check duals before solve
00293       solver.primal(1);
00294       lastAlgorithm_=1; // primal
00295     }
00296     //if (solver.numberIterations())
00297     //printf("****** iterated %d\n",solver.numberIterations());
00298   } else {
00299     if (algorithm<0) {
00300       //printf("doing dual\n");
00301       solver.dual();
00302       lastAlgorithm_=2; // dual
00303       // check if clp thought it was in a loop
00304       if (solver.status()==3&&solver.numberIterations()<solver.maximumIterations()) {
00305         // switch algorithm
00306         solver.primal();
00307         lastAlgorithm_=1; // primal
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       //printf("doing primal\n");
00323       solver.primal();
00324       lastAlgorithm_=1; // primal
00325       // check if clp thought it was in a loop
00326       if (solver.status()==3&&solver.numberIterations()<solver.maximumIterations()) {
00327         // switch algorithm
00328         solver.dual();
00329         lastAlgorithm_=2; // dual
00330       }
00331     }
00332   }
00333   basis_ = getBasis(&solver);
00334   //basis_.print();
00335   solver.messageHandler()->setLogLevel(saveMessageLevel);
00336   solver.returnModel(*modelPtr_);
00337 }
00338 
00339 //#############################################################################
00340 // Parameter related methods
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 // Methods returning info on how the solution process terminated
00432 //#############################################################################
00433 
00434 bool OsiClpSolverInterface::isAbandoned() const
00435 {
00436   // not sure about -1 (should not happen)
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    NOTE - Coding if limit > 1.0e30 says that 1.0e29 is loose bound
00463    so all maximization tests are changed 
00464 */
00465 bool OsiClpSolverInterface::isPrimalObjectiveLimitReached() const
00466 {
00467   double limit = 0.0;
00468   modelPtr_->getDblParam(ClpPrimalObjectiveLimit, limit);
00469   if (limit > 1e30) {
00470     // was not ever set
00471     return false;
00472   }
00473    
00474   const double obj = modelPtr_->objectiveValue();
00475   int maxmin = (int) modelPtr_->optimizationDirection();
00476 
00477   switch (lastAlgorithm_) {
00478    case 0: // no simplex was needed
00479      return maxmin > 0 ? (obj < limit) /*minim*/ : (-obj < limit) /*maxim*/;
00480    case 2: // dual simplex
00481      if (modelPtr_->status() == 0) // optimal
00482         return maxmin > 0 ? (obj < limit) /*minim*/ : (-obj < limit) /*maxim*/;
00483      return false;
00484    case 1: // primal simplex
00485      return maxmin > 0 ? (obj < limit) /*minim*/ : (-obj < limit) /*maxim*/;
00486   }
00487   return false; // fake return
00488 }
00489 
00490 bool OsiClpSolverInterface::isDualObjectiveLimitReached() const
00491 {
00492 
00493   double limit = 0.0;
00494   modelPtr_->getDblParam(ClpDualObjectiveLimit, limit);
00495   if (limit > 1e30) {
00496     // was not ever set
00497     return false;
00498   }
00499    
00500   const double obj = modelPtr_->objectiveValue();
00501   int maxmin = (int) modelPtr_->optimizationDirection();
00502 
00503   switch (lastAlgorithm_) {
00504    case 0: // no simplex was needed
00505      return maxmin > 0 ? (obj > limit) /*minim*/ : (-obj > limit) /*maxim*/;
00506    case 1: // primal simplex
00507      if (modelPtr_->status() == 0) // optimal
00508         return maxmin > 0 ? (obj > limit) /*minim*/ : (-obj > limit) /*maxim*/;
00509      return false;
00510    case 2: // dual simplex
00511      if (modelPtr_->status() != 0 && modelPtr_->status() != 3)
00512         // over dual limit
00513         return true;
00514      return maxmin > 0 ? (obj > limit) /*minim*/ : (-obj > limit) /*maxim*/;
00515   }
00516   return false; // fake return
00517 }
00518 
00519 bool OsiClpSolverInterface::isIterationLimitReached() const
00520 {
00521   const int stat = modelPtr_->status();
00522   return (stat == 3);
00523 }
00524 
00525 //#############################################################################
00526 // WarmStart related methods
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 // Hotstart related methods (primarily used in strong branching)
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   // Switch off printing if asked to
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 // Problem information methods (original data)
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 // Return information on integrality
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 // Row and column copies of the matrix ...
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     // directly into code as well
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   // *TEST*
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     // directly into code as well
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     // directly into code as well (? sign )
00835     CoinDisjointCopyN(rs,modelPtr_->numberRows(),
00836                       modelPtr_->djRegion(0));
00837   }
00838 }
00839 
00840 //#############################################################################
00841 // Problem modifying methods (matrix)
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 // Methods to input a problem
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 // Write mps files
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     // no extension so no trailing period
01132     fullname = f;
01133   }
01134   // Fall back on Osi version - without names
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 // CLP specific public interfaces
01150 //#############################################################################
01151 
01152 ClpSimplex * OsiClpSolverInterface::getModelPtr() const
01153 {
01154   freeCachedResults();
01155   return modelPtr_;
01156 }
01157 
01158 //------------------------------------------------------------------- 
01159 
01160 //#############################################################################
01161 // Constructors, destructors clone and assignment
01162 //#############################################################################
01163 
01164 //-------------------------------------------------------------------
01165 // Default Constructor 
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 // Clone
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 // Copy constructor 
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 // Borrow constructor - only delete one copy
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 // Releases so won't error
01270 void 
01271 OsiClpSolverInterface::releaseClp()
01272 {
01273   modelPtr_=NULL;
01274   notOwned_=false;
01275 }
01276     
01277 
01278 //-------------------------------------------------------------------
01279 // Destructor 
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 // Assignment operator 
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 // Applying cuts
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 /* Apply a collection of row cuts which are all effective.
01334    applyCuts seems to do one at a time which seems inefficient.
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 // Private methods
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     // all three must be NULL
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 // Set language
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 // Warm start
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   //basis.print();
01481   return basis;
01482 }
01483 // Sets up basis
01484 void 
01485 OsiClpSolverInterface::setBasis ( const CoinWarmStartBasis & basis,
01486                                   ClpSimplex * model)
01487 {
01488   // transform basis to status arrays
01489   int iRow,iColumn;
01490   int numberRows = model->numberRows();
01491   int numberColumns = model->numberColumns();
01492   if (!model->statusExists()) {
01493     /*
01494       get status arrays
01495       ClpBasis would seem to have overheads and we will need
01496       extra bits anyway.
01497     */
01498     model->createStatus();
01499   }
01500   CoinWarmStartBasis basis2 = basis;
01501   // resize if necessary
01502   basis2.resize(numberRows,numberColumns);
01503   // move status
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 /* Read an mps file from the given filename (defaults to Osi reader) - returns
01515    number of errors (see OsiMpsReader class) */
01516 int 
01517 OsiClpSolverInterface::readMps(const char *filename,
01518                                const char *extension ) 
01519 {
01520   // Get rid of integer stuff
01521   delete [] integerInformation_;
01522   integerInformation_=NULL;
01523   
01524   int numberErrors = OsiSolverInterface::readMps(filename,extension);
01525   // move across integer information
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 // Get pointer to array[getNumCols()] of primal solution vector
01544 const double * 
01545 OsiClpSolverInterface::getColSolution() const 
01546 { 
01547   if (modelPtr_->solveType()!=2) {
01548     return modelPtr_->primalColumnSolution();
01549   } else {
01550     // simplex interface
01551     return modelPtr_->solutionRegion(1);
01552   }
01553 }
01554   
01555 // Get pointer to array[getNumRows()] of dual prices
01556 const double * 
01557 OsiClpSolverInterface::getRowPrice() const
01558 { 
01559   if (modelPtr_->solveType()!=2) {
01560     return modelPtr_->dualRowSolution();
01561   } else {
01562     // simplex interface
01563     //return modelPtr_->djRegion(0);
01564     return modelPtr_->dualRowSolution();
01565   }
01566 }
01567   
01568 // Get a pointer to array[getNumCols()] of reduced costs
01569 const double * 
01570 OsiClpSolverInterface::getReducedCost() const 
01571 { 
01572   if (modelPtr_->solveType()!=2) {
01573     return modelPtr_->dualColumnSolution();
01574   } else {
01575     // simplex interface
01576     return modelPtr_->djRegion(1);
01577   }
01578 }
01579 
01580 /* Get pointer to array[getNumRows()] of row activity levels (constraint
01581    matrix times the solution vector */
01582 const double * 
01583 OsiClpSolverInterface::getRowActivity() const 
01584 { 
01585   if (modelPtr_->solveType()!=2) {
01586     return modelPtr_->primalRowSolution();
01587   } else {
01588     // simplex interface
01589     return modelPtr_->solutionRegion(0);
01590   }
01591 }
01592 /* Set an objective function coefficient */
01593 void 
01594 OsiClpSolverInterface::setObjCoeff( int elementIndex, double elementValue )
01595 {
01596   linearObjective_[elementIndex] = elementValue;
01597   if (modelPtr_->solveType()==2) {
01598     // simplex interface
01599     modelPtr_->costRegion(1)[elementIndex] = elementValue;
01600   }
01601 }
01602 
01603 /* Set a single column lower bound<br>
01604    Use -DBL_MAX for -infinity. */
01605 void 
01606 OsiClpSolverInterface::setColLower( int elementIndex, double elementValue )
01607 {
01608   modelPtr_->columnLower()[elementIndex] = elementValue;
01609   if (modelPtr_->solveType()==2) {
01610     // simplex interface
01611     modelPtr_->lowerRegion(1)[elementIndex] = elementValue;
01612   }
01613 }
01614       
01615 /* Set a single column upper bound<br>
01616    Use DBL_MAX for infinity. */
01617 void 
01618 OsiClpSolverInterface::setColUpper( int elementIndex, double elementValue )
01619 {
01620   modelPtr_->columnUpper()[elementIndex] = elementValue;
01621   if (modelPtr_->solveType()==2) {
01622     // simplex interface
01623     modelPtr_->upperRegion(1)[elementIndex] = elementValue;
01624   }
01625 }
01626 
01627 /* Set a single column lower and upper bound */
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     // simplex interface
01636     modelPtr_->lowerRegion(1)[elementIndex] = lower;
01637     modelPtr_->upperRegion(1)[elementIndex] = upper;
01638   }
01639 }
01640 /*Enables normal operation of subsequent functions.
01641   This method is supposed to ensure that all typical things (like
01642   reduced costs, etc.) are updated when individual pivots are executed
01643   and can be queried by other methods 
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   // Do initialization
01656   saveData_ = modelPtr_->saveData();
01657   // set infeasibility cost up
01658   modelPtr_->setInfeasibilityCost(1.0e12);
01659   // probably should save and restore?
01660   ClpDualRowDantzig dantzig;
01661   modelPtr_->setDualRowPivotAlgorithm(dantzig);
01662   ClpPrimalColumnDantzig dantzigP;
01663   modelPtr_->setPrimalColumnPivotAlgorithm(dantzigP);
01664   assert (!modelPtr_->startup(0));
01665 }
01666 
01667 //Undo whatever setting changes the above method had to make
01668 void 
01669 OsiClpSolverInterface::disableSimplexInterface()
01670 {
01671   assert (modelPtr_->solveType()==2);
01672   // declare optimality anyway  (for message handler)
01673   modelPtr_->setProblemStatus(0);
01674   modelPtr_->setSolveType(1);
01675   modelPtr_->finish();
01676   modelPtr_->restoreData(saveData_);
01677   basis_ = getBasis(modelPtr_);
01678 }
01679 /* The following two methods may be replaced by the
01680    methods of OsiSolverInterface using OsiWarmStartBasis if:
01681    1. OsiWarmStartBasis resize operation is implemented
01682    more efficiently and
01683    2. It is ensured that effects on the solver are the same
01684    
01685    Returns a basis status of the structural/artificial variables 
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 //Set the status of structural/artificial variables 
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; // set free if should be
01719     else if (lower[i]<-1.0e50&&status==3)
01720       status = 2; // can't be at lower bound
01721     else if (upper[i]>1.0e50&&status==2)
01722       status = 3; // can't be at upper bound
01723     switch (status) {
01724       // free or superbasic
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       // basic
01738       modelPtr_->setRowStatus(i,ClpSimplex::basic);
01739       break;
01740     case 2:
01741       // at upper bound
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       // at lower bound
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; // set free if should be
01768     else if (lower[i]<-1.0e50&&status==3)
01769       status = 2; // can't be at lower bound
01770     else if (upper[i]>1.0e50&&status==2)
01771       status = 3; // can't be at upper bound
01772     switch (status) {
01773       // free or superbasic
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       // basic
01787       modelPtr_->setColumnStatus(i,ClpSimplex::basic);
01788       break;
01789     case 2:
01790       // at upper bound
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       // at lower bound
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 /* Perform a pivot by substituting a colIn for colOut in the basis. 
01812    The status of the leaving variable is given in statOut. Where
01813    1 is to upper bound, -1 to lower bound
01814 */
01815 int 
01816 OsiClpSolverInterface::pivot(int colIn, int colOut, int outStatus)
01817 {
01818   assert (modelPtr_->solveType()==2);
01819   // convert to Clp style (what about flips?)
01820   if (colIn<0) 
01821     colIn = modelPtr_->numberColumns()+(-1-colIn);
01822   if (colOut<0) 
01823     colOut = modelPtr_->numberColumns()+(-1-colOut);
01824   // in clp direction of out is reversed
01825   outStatus = - outStatus;
01826   // set in clp
01827   modelPtr_->setDirectionOut(outStatus);
01828   modelPtr_->setSequenceIn(colIn);
01829   modelPtr_->setSequenceOut(colOut);
01830   // do pivot
01831   modelPtr_->pivot();
01832   return 0;
01833 }
01834 
01835 /* Obtain a result of the primal pivot 
01836    Outputs: colOut -- leaving column, outStatus -- its status,
01837    t -- step size, and, if dx!=NULL, *dx -- primal ray direction.
01838    Inputs: colIn -- entering column, sign -- direction of its change (+/-1).
01839    Both for colIn and colOut, artificial variables are index by
01840    the negative of the row index minus 1.
01841    Return code (for now): 0 -- leaving variable found, 
01842    -1 -- everything else?
01843    Clearly, more informative set of return values is required 
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   // convert to Clp style
01852   if (colIn<0) 
01853     colIn = modelPtr_->numberColumns()+(-1-colIn);
01854   // set in clp
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 /* Obtain a result of the dual pivot (similar to the previous method)
01877    Differences: entering variable and a sign of its change are now
01878    the outputs, the leaving variable and its statuts -- the inputs
01879    If dx!=NULL, then *dx contains dual ray
01880    Return code: same
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 //Get the reduced gradient for the cost vector c 
01893 void 
01894 OsiClpSolverInterface::getReducedGradient(
01895                                           double* columnReducedCosts, 
01896                                           double * duals,
01897                                           const double * c)
01898 {
01899   assert (modelPtr_->solveType()==2);
01900   // could do this faster with coding inside Clp
01901   // save current costs
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 /* Set a new objective and apply the old basis so that the
01916    reduced costs are properly updated  */
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 //Get a row of the tableau
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   // put +1 in row
01941   rowArray1->insert(row,1.0);
01942   factorization->updateColumnTranspose(rowArray0,rowArray1);
01943   // put row of tableau in rowArray1 and columnArray0
01944   modelPtr_->clpMatrix()->transposeTimes(modelPtr_,1.0,
01945                             rowArray0,columnArray1,columnArray0);
01946   memcpy(z,columnArray0->denseVector(),
01947          modelPtr_->numberColumns()*sizeof(double));
01948   // don't need to clear everything always, but doesn't cost
01949   rowArray0->clear();
01950   rowArray1->clear();
01951   columnArray0->clear();
01952   columnArray1->clear();
01953 }
01954 
01955 //Get a row of the basis inverse
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   // put +1 in row
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 //Get a column of the tableau
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   // get column of matrix
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 //Get a column of the basis inverse
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   // put +1 in row
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 /* Get basic indices (order of indices corresponds to the
02009    order of elements in a vector retured by getBInvACol() and
02010    getBInvCol()).
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 // Resets as if default constructor
02021 void 
02022 OsiClpSolverInterface::reset()
02023 {
02024   setInitialData(); // clear base class
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   // This is also deleted by Clp --tkr 7/31/03
02041   // delete linearObjective_;
02042   linearObjective_ = NULL;
02043   fillParamMaps();
02044 }
02045 

Generated on Wed Dec 3 14:35:28 2003 for Osi by doxygen 1.3.5