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

ClpModel.cpp

00001 // Copyright (C) 2002, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 
00004 #include <cmath>
00005 #include <cassert>
00006 #include <cfloat>
00007 #include <string>
00008 #include <cstdio>
00009 #include <iostream>
00010 
00011 
00012 #include "CoinPragma.hpp"
00013 
00014 #include "CoinHelperFunctions.hpp"
00015 #include "CoinTime.hpp"
00016 #include "ClpModel.hpp"
00017 #include "ClpPackedMatrix.hpp"
00018 #include "CoinPackedVector.hpp"
00019 #include "CoinIndexedVector.hpp"
00020 #include "CoinMpsIO.hpp"
00021 #include "ClpMessage.hpp"
00022 #include "ClpLinearObjective.hpp"
00023 #include "ClpQuadraticObjective.hpp"
00024 
00025 //#############################################################################
00026 
00027 ClpModel::ClpModel () :
00028 
00029   optimizationDirection_(1),
00030   objectiveValue_(0.0),
00031   smallElement_(1.0e-20),
00032   numberRows_(0),
00033   numberColumns_(0),
00034   rowActivity_(NULL),
00035   columnActivity_(NULL),
00036   dual_(NULL),
00037   reducedCost_(NULL),
00038   rowLower_(NULL),
00039   rowUpper_(NULL),
00040   objective_(NULL),
00041   rowObjective_(NULL),
00042   columnLower_(NULL),
00043   columnUpper_(NULL),
00044   matrix_(NULL),
00045   rowCopy_(NULL),
00046   ray_(NULL),
00047   status_(NULL),
00048   integerType_(NULL),
00049   userPointer_(NULL),
00050   numberIterations_(0),
00051   solveType_(0),
00052   problemStatus_(-1),
00053   secondaryStatus_(0),
00054   lengthNames_(0),
00055   defaultHandler_(true),
00056   rowNames_(),
00057   columnNames_()
00058 {
00059   intParam_[ClpMaxNumIteration] = 99999999;
00060   intParam_[ClpMaxNumIterationHotStart] = 9999999;
00061 
00062   dblParam_[ClpDualObjectiveLimit] = COIN_DBL_MAX;
00063   dblParam_[ClpPrimalObjectiveLimit] = COIN_DBL_MAX;
00064   dblParam_[ClpDualTolerance] = 1e-7;
00065   dblParam_[ClpPrimalTolerance] = 1e-7;
00066   dblParam_[ClpObjOffset] = 0.0;
00067   dblParam_[ClpMaxSeconds] = -1.0;
00068 
00069   strParam_[ClpProbName] = "ClpDefaultName";
00070   handler_ = new CoinMessageHandler();
00071   handler_->setLogLevel(1);
00072   messages_ = ClpMessage();
00073 }
00074 
00075 //-----------------------------------------------------------------------------
00076 
00077 ClpModel::~ClpModel ()
00078 {
00079   if (defaultHandler_) {
00080     delete handler_;
00081     handler_ = NULL;
00082   }
00083   gutsOfDelete();
00084 }
00085 void ClpModel::gutsOfDelete()
00086 {
00087   delete [] rowActivity_;
00088   rowActivity_=NULL;
00089   delete [] columnActivity_;
00090   columnActivity_=NULL;
00091   delete [] dual_;
00092   dual_=NULL;
00093   delete [] reducedCost_;
00094   reducedCost_=NULL;
00095   delete [] rowLower_;
00096   delete [] rowUpper_;
00097   delete [] rowObjective_;
00098   rowLower_=NULL;
00099   rowUpper_=NULL;
00100   rowObjective_=NULL;
00101   delete [] columnLower_;
00102   delete [] columnUpper_;
00103   delete objective_;
00104   columnLower_=NULL;
00105   columnUpper_=NULL;
00106   objective_=NULL;
00107   delete matrix_;
00108   matrix_=NULL;
00109   delete rowCopy_;
00110   rowCopy_=NULL;
00111   delete [] ray_;
00112   ray_ = NULL;
00113   delete [] integerType_;
00114   integerType_ = NULL;
00115   delete [] status_;
00116   status_=NULL;
00117 }
00118 //#############################################################################
00119 void ClpModel::setPrimalTolerance( double value) 
00120 {
00121   if (value>0.0&&value<1.0e10)
00122     dblParam_[ClpPrimalTolerance]=value;
00123 }
00124 void ClpModel::setDualTolerance( double value) 
00125 {
00126   if (value>0.0&&value<1.0e10)
00127     dblParam_[ClpDualTolerance]=value;
00128 }
00129 void ClpModel::setOptimizationDirection( double value) 
00130 {
00131   optimizationDirection_=value;
00132 }
00133 void
00134 ClpModel::gutsOfLoadModel (int numberRows, int numberColumns, 
00135                      const double* collb, const double* colub,   
00136                      const double* obj,
00137                      const double* rowlb, const double* rowub,
00138                                 const double * rowObjective)
00139 {
00140   gutsOfDelete();
00141   numberRows_=numberRows;
00142   numberColumns_=numberColumns;
00143   rowActivity_=new double[numberRows_];
00144   columnActivity_=new double[numberColumns_];
00145   dual_=new double[numberRows_];
00146   reducedCost_=new double[numberColumns_];
00147 
00148   ClpFillN(dual_,numberRows_,0.0);
00149   ClpFillN(reducedCost_,numberColumns_,0.0);
00150   int iRow,iColumn;
00151 
00152   rowLower_=ClpCopyOfArray(rowlb,numberRows_,-COIN_DBL_MAX);
00153   rowUpper_=ClpCopyOfArray(rowub,numberRows_,COIN_DBL_MAX);
00154   double * objective=ClpCopyOfArray(obj,numberColumns_,0.0);
00155   objective_ = new ClpLinearObjective(objective,numberColumns_);
00156   delete [] objective;
00157   rowObjective_=ClpCopyOfArray(rowObjective,numberRows_);
00158   columnLower_=ClpCopyOfArray(collb,numberColumns_,0.0);
00159   columnUpper_=ClpCopyOfArray(colub,numberColumns_,COIN_DBL_MAX);
00160   // set default solution
00161   for (iRow=0;iRow<numberRows_;iRow++) {
00162     if (rowLower_[iRow]>0.0) {
00163       rowActivity_[iRow]=rowLower_[iRow];
00164     } else if (rowUpper_[iRow]<0.0) {
00165       rowActivity_[iRow]=rowUpper_[iRow];
00166     } else {
00167       rowActivity_[iRow]=0.0;
00168     }
00169   }
00170   for (iColumn=0;iColumn<numberColumns_;iColumn++) {
00171     if (columnLower_[iColumn]>0.0) {
00172       columnActivity_[iColumn]=columnLower_[iColumn];
00173     } else if (columnUpper_[iColumn]<0.0) {
00174       columnActivity_[iColumn]=columnUpper_[iColumn];
00175     } else {
00176       columnActivity_[iColumn]=0.0;
00177     }
00178   }
00179 }
00180 // This just loads up a row objective
00181 void ClpModel::setRowObjective(const double * rowObjective)
00182 {
00183   delete [] rowObjective_;
00184   rowObjective_=ClpCopyOfArray(rowObjective,numberRows_);
00185 }
00186 void
00187 ClpModel::loadProblem (  const ClpMatrixBase& matrix,
00188                      const double* collb, const double* colub,   
00189                      const double* obj,
00190                      const double* rowlb, const double* rowub,
00191                                 const double * rowObjective)
00192 {
00193   gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(),
00194                   collb, colub, obj, rowlb, rowub, rowObjective);
00195   if (matrix.isColOrdered()) {
00196     matrix_=matrix.clone();
00197   } else {
00198     // later may want to keep as unknown class
00199     CoinPackedMatrix matrix2;
00200     matrix2.reverseOrderedCopyOf(*matrix.getPackedMatrix());
00201     matrix.releasePackedMatrix();
00202     matrix_=new ClpPackedMatrix(matrix2);
00203   }    
00204 }
00205 void
00206 ClpModel::loadProblem (  const CoinPackedMatrix& matrix,
00207                      const double* collb, const double* colub,   
00208                      const double* obj,
00209                      const double* rowlb, const double* rowub,
00210                                 const double * rowObjective)
00211 {
00212   gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(),
00213                   collb, colub, obj, rowlb, rowub, rowObjective);
00214   if (matrix.isColOrdered()) {
00215     matrix_=new ClpPackedMatrix(matrix);
00216   } else {
00217     CoinPackedMatrix matrix2;
00218     matrix2.reverseOrderedCopyOf(matrix);
00219     matrix_=new ClpPackedMatrix(matrix2);
00220   }    
00221 }
00222 void
00223 ClpModel::loadProblem ( 
00224                               const int numcols, const int numrows,
00225                               const CoinBigIndex* start, const int* index,
00226                               const double* value,
00227                               const double* collb, const double* colub,   
00228                               const double* obj,
00229                               const double* rowlb, const double* rowub,
00230                               const double * rowObjective)
00231 {
00232   gutsOfLoadModel(numrows, numcols,
00233                   collb, colub, obj, rowlb, rowub, rowObjective);
00234   CoinPackedMatrix matrix(true,numrows,numcols,start[numcols],
00235                               value,index,start,NULL);
00236   matrix_ = new ClpPackedMatrix(matrix);
00237 }
00238 void
00239 ClpModel::loadProblem ( 
00240                               const int numcols, const int numrows,
00241                               const CoinBigIndex* start, const int* index,
00242                               const double* value,const int* length,
00243                               const double* collb, const double* colub,   
00244                               const double* obj,
00245                               const double* rowlb, const double* rowub,
00246                               const double * rowObjective)
00247 {
00248   gutsOfLoadModel(numrows, numcols,
00249                   collb, colub, obj, rowlb, rowub, rowObjective);
00250   // Compute number of elements
00251   int numberElements = 0;
00252   int i;
00253   for (i=0;i<numcols;i++) 
00254     numberElements += length[i];
00255   CoinPackedMatrix matrix(true,numrows,numcols,numberElements,
00256                               value,index,start,length);
00257   matrix_ = new ClpPackedMatrix(matrix);
00258 }
00259 void
00260 ClpModel::getRowBound(int iRow, double& lower, double& upper) const
00261 {
00262   lower=-COIN_DBL_MAX;
00263   upper=COIN_DBL_MAX;
00264   if (rowUpper_)
00265     upper=rowUpper_[iRow];
00266   if (rowLower_)
00267     lower=rowLower_[iRow];
00268 }
00269 //#############################################################################
00270 // Copy constructor. 
00271 ClpModel::ClpModel(const ClpModel &rhs) :
00272   optimizationDirection_(rhs.optimizationDirection_),
00273   numberRows_(rhs.numberRows_),
00274   numberColumns_(rhs.numberColumns_)
00275 {
00276   gutsOfCopy(rhs);
00277 }
00278 // Assignment operator. This copies the data
00279 ClpModel & 
00280 ClpModel::operator=(const ClpModel & rhs)
00281 {
00282   if (this != &rhs) {
00283     if (defaultHandler_) {
00284       delete handler_;
00285       handler_ = NULL;
00286     }
00287     gutsOfDelete();
00288     optimizationDirection_ = rhs.optimizationDirection_;
00289     numberRows_ = rhs.numberRows_;
00290     numberColumns_ = rhs.numberColumns_;
00291     gutsOfCopy(rhs);
00292   }
00293   return *this;
00294 }
00295 // Does most of copying
00296 void 
00297 ClpModel::gutsOfCopy(const ClpModel & rhs, bool trueCopy)
00298 {
00299   defaultHandler_ = rhs.defaultHandler_;
00300   if (defaultHandler_) 
00301     handler_ = new CoinMessageHandler(*rhs.handler_);
00302    else 
00303     handler_ = rhs.handler_;
00304   messages_ = rhs.messages_;
00305   intParam_[ClpMaxNumIteration] = rhs.intParam_[ClpMaxNumIteration];
00306   intParam_[ClpMaxNumIterationHotStart] = 
00307     rhs.intParam_[ClpMaxNumIterationHotStart];
00308 
00309   dblParam_[ClpDualObjectiveLimit] = rhs.dblParam_[ClpDualObjectiveLimit];
00310   dblParam_[ClpPrimalObjectiveLimit] = rhs.dblParam_[ClpPrimalObjectiveLimit];
00311   dblParam_[ClpDualTolerance] = rhs.dblParam_[ClpDualTolerance];
00312   dblParam_[ClpPrimalTolerance] = rhs.dblParam_[ClpPrimalTolerance];
00313   dblParam_[ClpObjOffset] = rhs.dblParam_[ClpObjOffset];
00314   dblParam_[ClpMaxSeconds] = rhs.dblParam_[ClpMaxSeconds];
00315 
00316   strParam_[ClpProbName] = rhs.strParam_[ClpProbName];
00317 
00318   optimizationDirection_ = rhs.optimizationDirection_;
00319   objectiveValue_=rhs.objectiveValue_;
00320   smallElement_ = rhs.smallElement_;
00321   numberIterations_ = rhs.numberIterations_;
00322   solveType_ = rhs.solveType_;
00323   problemStatus_ = rhs.problemStatus_;
00324   secondaryStatus_ = rhs.secondaryStatus_;
00325   numberRows_ = rhs.numberRows_;
00326   numberColumns_ = rhs.numberColumns_;
00327   userPointer_ = rhs.userPointer_;
00328   if (trueCopy) {
00329     lengthNames_ = rhs.lengthNames_;
00330     rowNames_ = rhs.rowNames_;
00331     columnNames_ = rhs.columnNames_;
00332     if (rhs.integerType_) {
00333       integerType_ = new char[numberColumns_];
00334       memcpy(integerType_,rhs.integerType_,numberColumns_*sizeof(char));
00335     } else {
00336       integerType_ = NULL;
00337     }
00338     if (rhs.rowActivity_) {
00339       rowActivity_=new double[numberRows_];
00340       columnActivity_=new double[numberColumns_];
00341       dual_=new double[numberRows_];
00342       reducedCost_=new double[numberColumns_];
00343       ClpDisjointCopyN ( rhs.rowActivity_, numberRows_ ,
00344                           rowActivity_);
00345       ClpDisjointCopyN ( rhs.columnActivity_, numberColumns_ ,
00346                           columnActivity_);
00347       ClpDisjointCopyN ( rhs.dual_, numberRows_ , 
00348                           dual_);
00349       ClpDisjointCopyN ( rhs.reducedCost_, numberColumns_ ,
00350                           reducedCost_);
00351     } else {
00352       rowActivity_=NULL;
00353       columnActivity_=NULL;
00354       dual_=NULL;
00355       reducedCost_=NULL;
00356     }
00357     rowLower_ = ClpCopyOfArray ( rhs.rowLower_, numberRows_ );
00358     rowUpper_ = ClpCopyOfArray ( rhs.rowUpper_, numberRows_ );
00359     columnLower_ = ClpCopyOfArray ( rhs.columnLower_, numberColumns_ );
00360     columnUpper_ = ClpCopyOfArray ( rhs.columnUpper_, numberColumns_ );
00361     if (rhs.objective_)
00362       objective_  = rhs.objective_->clone();
00363     else
00364       objective_ = NULL;
00365     rowObjective_ = ClpCopyOfArray ( rhs.rowObjective_, numberRows_ );
00366     status_ = ClpCopyOfArray( rhs.status_,numberColumns_+numberRows_);
00367     ray_ = NULL;
00368     if (problemStatus_==1&&!secondaryStatus_)
00369       ray_ = ClpCopyOfArray (rhs.ray_,numberRows_);
00370     else if (problemStatus_==2)
00371       ray_ = ClpCopyOfArray (rhs.ray_,numberColumns_);
00372     if (rhs.rowCopy_) {
00373       rowCopy_ = rhs.rowCopy_->clone();
00374     } else {
00375       rowCopy_=NULL;
00376     }
00377     matrix_=NULL;
00378     if (rhs.matrix_) {
00379       matrix_ = rhs.matrix_->clone();
00380     }
00381   } else {
00382     rowActivity_ = rhs.rowActivity_;
00383     columnActivity_ = rhs.columnActivity_;
00384     dual_ = rhs.dual_;
00385     reducedCost_ = rhs.reducedCost_;
00386     rowLower_ = rhs.rowLower_;
00387     rowUpper_ = rhs.rowUpper_;
00388     objective_ = rhs.objective_;
00389     rowObjective_ = rhs.rowObjective_;
00390     columnLower_ = rhs.columnLower_;
00391     columnUpper_ = rhs.columnUpper_;
00392     matrix_ = rhs.matrix_;
00393     rowCopy_ = NULL;
00394     ray_ = rhs.ray_;
00395     lengthNames_ = 0;
00396     rowNames_ = std::vector<std::string> ();
00397     columnNames_ = std::vector<std::string> ();
00398     integerType_ = NULL;
00399     status_ = rhs.status_;
00400   }
00401 }
00402 /* Borrow model.  This is so we dont have to copy large amounts
00403    of data around.  It assumes a derived class wants to overwrite
00404    an empty model with a real one - while it does an algorithm */
00405 void 
00406 ClpModel::borrowModel(ClpModel & rhs)
00407 {
00408   if (defaultHandler_) {
00409     delete handler_;
00410     handler_ = NULL;
00411   }
00412   gutsOfDelete();
00413   optimizationDirection_ = rhs.optimizationDirection_;
00414   numberRows_ = rhs.numberRows_;
00415   numberColumns_ = rhs.numberColumns_;
00416   delete [] rhs.ray_;
00417   rhs.ray_=NULL;
00418   gutsOfCopy(rhs,false);
00419 }
00420 // Return model - nulls all arrays so can be deleted safely
00421 void 
00422 ClpModel::returnModel(ClpModel & otherModel)
00423 {
00424   otherModel.objectiveValue_=objectiveValue_;
00425   otherModel.numberIterations_ = numberIterations_;
00426   otherModel.problemStatus_ = problemStatus_;
00427   otherModel.secondaryStatus_ = secondaryStatus_;
00428   rowActivity_ = NULL;
00429   columnActivity_ = NULL;
00430   dual_ = NULL;
00431   reducedCost_ = NULL;
00432   rowLower_ = NULL;
00433   rowUpper_ = NULL;
00434   objective_ = NULL;
00435   rowObjective_ = NULL;
00436   columnLower_ = NULL;
00437   columnUpper_ = NULL;
00438   matrix_ = NULL;
00439   rowCopy_ = NULL;
00440   delete [] otherModel.ray_;
00441   otherModel.ray_ = ray_;
00442   ray_ = NULL;
00443   // do status
00444   if (otherModel.status_!=status_) {
00445     delete [] otherModel.status_;
00446     otherModel.status_ = status_;
00447   }
00448   status_ = NULL;
00449   if (defaultHandler_) {
00450     delete handler_;
00451     handler_ = NULL;
00452   }
00453 }
00454 //#############################################################################
00455 // Parameter related methods
00456 //#############################################################################
00457 
00458 bool
00459 ClpModel::setIntParam(ClpIntParam key, int value)
00460 {
00461   switch (key) {
00462   case ClpMaxNumIteration:
00463     if (value < 0)
00464       return false;
00465     break;
00466   case ClpMaxNumIterationHotStart:
00467     if (value < 0)
00468       return false;
00469     break;
00470   case ClpLastIntParam:
00471     return false;
00472   }
00473   intParam_[key] = value;
00474   return true;
00475 }
00476 
00477 //-----------------------------------------------------------------------------
00478 
00479 bool
00480 ClpModel::setDblParam(ClpDblParam key, double value)
00481 {
00482 
00483   switch (key) {
00484   case ClpDualObjectiveLimit:
00485     break;
00486 
00487   case ClpPrimalObjectiveLimit:
00488     break;
00489 
00490   case ClpDualTolerance: 
00491     if (value<=0.0||value>1.0e10)
00492       return false;
00493     break;
00494     
00495   case ClpPrimalTolerance: 
00496     if (value<=0.0||value>1.0e10)
00497       return false;
00498     break;
00499     
00500   case ClpObjOffset: 
00501     break;
00502 
00503   case ClpMaxSeconds: 
00504     if(value>=0)
00505       value += CoinCpuTime();
00506     else
00507       value = -1.0;
00508     break;
00509 
00510   case ClpLastDblParam:
00511     return false;
00512   }
00513   dblParam_[key] = value;
00514   return true;
00515 }
00516 
00517 //-----------------------------------------------------------------------------
00518 
00519 bool
00520 ClpModel::setStrParam(ClpStrParam key, const std::string & value)
00521 {
00522 
00523   switch (key) {
00524   case ClpProbName:
00525     break;
00526 
00527   case ClpLastStrParam:
00528     return false;
00529   }
00530   strParam_[key] = value;
00531   return true;
00532 }
00533 // Useful routines
00534 // Returns resized array and deletes incoming
00535 double * resizeDouble(double * array , int size, int newSize, double fill,
00536                       bool createArray)
00537 {
00538   if ((array||createArray)&&size!=newSize) {
00539     int i;
00540     double * newArray = new double[newSize];
00541     if (array)
00542       memcpy(newArray,array,min(newSize,size)*sizeof(double));
00543     delete [] array;
00544     array = newArray;
00545     for (i=size;i<newSize;i++) 
00546       array[i]=fill;
00547   } 
00548   return array;
00549 }
00550 // Returns resized array and updates size
00551 double * deleteDouble(double * array , int size, 
00552                       int number, const int * which,int & newSize)
00553 {
00554   if (array) {
00555     int i ;
00556     char * deleted = new char[size];
00557     int numberDeleted=0;
00558     memset(deleted,0,size*sizeof(char));
00559     for (i=0;i<number;i++) {
00560       int j = which[i];
00561       if (j>=0&&j<size&&!deleted[j]) {
00562         numberDeleted++;
00563         deleted[j]=1;
00564       }
00565     }
00566     newSize = size-numberDeleted;
00567     double * newArray = new double[newSize];
00568     int put=0;
00569     for (i=0;i<size;i++) {
00570       if (!deleted[i]) {
00571         newArray[put++]=array[i];
00572       }
00573     }
00574     delete [] array;
00575     array = newArray;
00576     delete [] deleted;
00577   }
00578   return array;
00579 }
00580 char * deleteChar(char * array , int size, 
00581                   int number, const int * which,int & newSize,
00582                   bool ifDelete)
00583 {
00584   if (array) {
00585     int i ;
00586     char * deleted = new char[size];
00587     int numberDeleted=0;
00588     memset(deleted,0,size*sizeof(char));
00589     for (i=0;i<number;i++) {
00590       int j = which[i];
00591       if (j>=0&&j<size&&!deleted[j]) {
00592         numberDeleted++;
00593         deleted[j]=1;
00594       }
00595     }
00596     newSize = size-numberDeleted;
00597     char * newArray = new char[newSize];
00598     int put=0;
00599     for (i=0;i<size;i++) {
00600       if (!deleted[i]) {
00601         newArray[put++]=array[i];
00602       }
00603     }
00604     if (ifDelete)
00605       delete [] array;
00606     array = newArray;
00607     delete [] deleted;
00608   }
00609   return array;
00610 }
00611 // Create empty ClpPackedMatrix
00612 void 
00613 ClpModel::createEmptyMatrix()
00614 {
00615   delete matrix_;
00616   CoinPackedMatrix matrix2;
00617   matrix_=new ClpPackedMatrix(matrix2);
00618 }
00619 // Resizes 
00620 void 
00621 ClpModel::resize (int newNumberRows, int newNumberColumns)
00622 {
00623   rowActivity_ = resizeDouble(rowActivity_,numberRows_,
00624                               newNumberRows,0.0,true);
00625   dual_ = resizeDouble(dual_,numberRows_,
00626                        newNumberRows,0.0,true);
00627   rowObjective_ = resizeDouble(rowObjective_,numberRows_,
00628                                newNumberRows,0.0,false);
00629   rowLower_ = resizeDouble(rowLower_,numberRows_,
00630                            newNumberRows,-COIN_DBL_MAX,true);
00631   rowUpper_ = resizeDouble(rowUpper_,numberRows_,
00632                            newNumberRows,COIN_DBL_MAX,true);
00633   columnActivity_ = resizeDouble(columnActivity_,numberColumns_,
00634                                  newNumberColumns,0.0,true);
00635   reducedCost_ = resizeDouble(reducedCost_,numberColumns_,
00636                               newNumberColumns,0.0,true);
00637   if (objective_)
00638     objective_->resize(newNumberColumns);
00639   else 
00640     objective_ = new ClpLinearObjective(NULL,newNumberColumns);
00641   columnLower_ = resizeDouble(columnLower_,numberColumns_,
00642                               newNumberColumns,0.0,true);
00643   columnUpper_ = resizeDouble(columnUpper_,numberColumns_,
00644                               newNumberColumns,COIN_DBL_MAX,true);
00645   if (newNumberRows<numberRows_) {
00646     int * which = new int[numberRows_-newNumberRows];
00647     int i;
00648     for (i=newNumberRows;i<numberRows_;i++) 
00649       which[i-newNumberRows]=i;
00650     matrix_->deleteRows(numberRows_-newNumberRows,which);
00651     delete [] which;
00652   }
00653   if (numberRows_!=newNumberRows||numberColumns_!=newNumberColumns) {
00654     // set state back to unknown
00655     problemStatus_ = -1;
00656     secondaryStatus_ = 0;
00657     delete [] ray_;
00658     ray_ = NULL;
00659   }
00660   if (status_) {
00661     unsigned char * tempC = new unsigned char [newNumberColumns+newNumberRows];
00662     unsigned char * tempR = tempC + newNumberColumns;
00663     memset(tempC,0,(newNumberColumns+newNumberRows)*sizeof(unsigned char));
00664     memcpy(tempC,status_,min(newNumberColumns,numberColumns_)*sizeof(unsigned char));
00665     memcpy(tempR,status_+numberColumns_,min(newNumberRows,numberRows_)*sizeof(unsigned char));
00666     delete [] status_;
00667     status_ = tempC;
00668   }
00669   numberRows_ = newNumberRows;
00670   if (newNumberColumns<numberColumns_) {
00671     int * which = new int[numberColumns_-newNumberColumns];
00672     int i;
00673     for (i=newNumberColumns;i<numberColumns_;i++) 
00674       which[i-newNumberColumns]=i;
00675     matrix_->deleteCols(numberColumns_-newNumberColumns,which);
00676     delete [] which;
00677   }
00678   if (integerType_) {
00679     char * temp = new char [newNumberColumns];
00680     memset(temp,0,newNumberColumns*sizeof(char));
00681     memcpy(temp,integerType_,
00682            min(newNumberColumns,numberColumns_)*sizeof(char));
00683     delete [] integerType_;
00684     integerType_ = temp;
00685   }
00686   numberColumns_ = newNumberColumns;
00687   // for now gets rid of names
00688   lengthNames_ = 0;
00689   rowNames_ = std::vector<std::string> ();
00690   columnNames_ = std::vector<std::string> ();
00691 }
00692 // Deletes rows
00693 void 
00694 ClpModel::deleteRows(int number, const int * which)
00695 {
00696   int newSize=0;
00697   rowActivity_ = deleteDouble(rowActivity_,numberRows_,
00698                               number, which, newSize);
00699   dual_ = deleteDouble(dual_,numberRows_,
00700                               number, which, newSize);
00701   rowObjective_ = deleteDouble(rowObjective_,numberRows_,
00702                               number, which, newSize);
00703   rowLower_ = deleteDouble(rowLower_,numberRows_,
00704                               number, which, newSize);
00705   rowUpper_ = deleteDouble(rowUpper_,numberRows_,
00706                               number, which, newSize);
00707   matrix_->deleteRows(number,which);
00708   //matrix_->removeGaps();
00709   // status
00710   if (status_) {
00711     unsigned char * tempR  = (unsigned char *) deleteChar((char *)status_+numberColumns_,
00712                                         numberRows_,
00713                                         number, which, newSize,false);
00714     unsigned char * tempC = new unsigned char [numberColumns_+newSize];
00715     memcpy(tempC,status_,numberColumns_*sizeof(unsigned char));
00716     memcpy(tempC+numberColumns_,tempR,newSize*sizeof(unsigned char));
00717     delete [] tempR;
00718     delete [] status_;
00719     status_ = tempC;
00720   }
00721   numberRows_=newSize;
00722   // set state back to unknown
00723   problemStatus_ = -1;
00724   secondaryStatus_ = 0;
00725   delete [] ray_;
00726   ray_ = NULL;
00727   // for now gets rid of names
00728   lengthNames_ = 0;
00729   rowNames_ = std::vector<std::string> ();
00730   columnNames_ = std::vector<std::string> ();
00731 }
00732 // Deletes columns
00733 void 
00734 ClpModel::deleteColumns(int number, const int * which)
00735 {
00736   int newSize=0;
00737   columnActivity_ = deleteDouble(columnActivity_,numberColumns_,
00738                               number, which, newSize);
00739   reducedCost_ = deleteDouble(reducedCost_,numberColumns_,
00740                               number, which, newSize);
00741   objective_->deleteSome(number, which);
00742   columnLower_ = deleteDouble(columnLower_,numberColumns_,
00743                               number, which, newSize);
00744   columnUpper_ = deleteDouble(columnUpper_,numberColumns_,
00745                               number, which, newSize);
00746   matrix_->deleteCols(number,which);
00747   //matrix_->removeGaps();
00748   // status
00749   if (status_) {
00750     unsigned char * tempC  = (unsigned char *) deleteChar((char *)status_,
00751                                         numberColumns_,
00752                                         number, which, newSize,false);
00753     unsigned char * temp = new unsigned char [numberRows_+newSize];
00754     memcpy(temp,tempC,newSize*sizeof(unsigned char));
00755     memcpy(temp+newSize,status_+numberColumns_,
00756            numberRows_*sizeof(unsigned char));
00757     delete [] tempC;
00758     delete [] status_;
00759     status_ = temp;
00760   }
00761   integerType_ = deleteChar(integerType_,numberColumns_,
00762                             number, which, newSize,true);
00763   numberColumns_=newSize;
00764   // set state back to unknown
00765   problemStatus_ = -1;
00766   secondaryStatus_ = 0;
00767   delete [] ray_;
00768   ray_ = NULL;
00769   // for now gets rid of names
00770   lengthNames_ = 0;
00771   rowNames_ = std::vector<std::string> ();
00772   columnNames_ = std::vector<std::string> ();
00773 }
00774 // Add rows
00775 void 
00776 ClpModel::addRows(int number, const double * rowLower, 
00777                   const double * rowUpper,
00778                   const int * rowStarts, const int * columns,
00779                   const double * elements)
00780 {
00781   // Create a list of CoinPackedVectors
00782   if (number) {
00783     CoinPackedVectorBase ** rows=
00784       new CoinPackedVectorBase * [number];
00785     int iRow;
00786     for (iRow=0;iRow<number;iRow++) {
00787       int iStart = rowStarts[iRow];
00788       rows[iRow] = 
00789         new CoinPackedVector(rowStarts[iRow+1]-iStart,
00790                              columns+iStart,elements+iStart);
00791     }
00792     addRows(number, rowLower, rowUpper,
00793             rows);
00794     for (iRow=0;iRow<number;iRow++) 
00795       delete rows[iRow];
00796     delete [] rows;
00797   }
00798 }
00799 // Add rows
00800 void 
00801 ClpModel::addRows(int number, const double * rowLower, 
00802                   const double * rowUpper,
00803                   const int * rowStarts, 
00804                   const int * rowLengths, const int * columns,
00805                   const double * elements)
00806 {
00807   // Create a list of CoinPackedVectors
00808   if (number) {
00809     CoinPackedVectorBase ** rows=
00810       new CoinPackedVectorBase * [number];
00811     int iRow;
00812     for (iRow=0;iRow<number;iRow++) {
00813       int iStart = rowStarts[iRow];
00814       rows[iRow] = 
00815         new CoinPackedVector(rowLengths[iRow],
00816                              columns+iStart,elements+iStart);
00817     }
00818     addRows(number, rowLower, rowUpper,
00819             rows);
00820     for (iRow=0;iRow<number;iRow++) 
00821       delete rows[iRow];
00822     delete [] rows;
00823   }
00824 }
00825 void 
00826 ClpModel::addRows(int number, const double * rowLower, 
00827                   const double * rowUpper,
00828                   const CoinPackedVectorBase * const * rows)
00829 {
00830   if (!number)
00831     return;
00832   int numberRowsNow = numberRows_;
00833   resize(numberRowsNow+number,numberColumns_);
00834   double * lower = rowLower_+numberRowsNow;
00835   double * upper = rowUpper_+numberRowsNow;
00836   int iRow;
00837   if (rowLower) {
00838     for (iRow = 0; iRow < number; iRow++) {
00839       double value = rowLower[iRow];
00840       if (value<-1.0e20)
00841         value = -COIN_DBL_MAX;
00842       lower[iRow]= value;
00843     }
00844   } else {
00845     for (iRow = 0; iRow < number; iRow++) {
00846       lower[iRow]= -COIN_DBL_MAX;
00847     }
00848   }
00849   if (rowUpper) {
00850     for (iRow = 0; iRow < number; iRow++) {
00851       double value = rowUpper[iRow];
00852       if (value>1.0e20)
00853         value = COIN_DBL_MAX;
00854       upper[iRow]= value;
00855     }
00856   } else {
00857     for (iRow = 0; iRow < number; iRow++) {
00858       upper[iRow]= COIN_DBL_MAX;
00859     }
00860   }
00861   // Deal with matrix
00862 
00863   delete rowCopy_;
00864   rowCopy_=NULL;
00865   if (!matrix_)
00866     createEmptyMatrix();
00867   matrix_->appendRows(number,rows);
00868 }
00869 // Add columns
00870 void 
00871 ClpModel::addColumns(int number, const double * columnLower, 
00872                      const double * columnUpper,
00873                      const double * objIn,
00874                      const int * columnStarts, const int * rows,
00875                      const double * elements)
00876 {
00877   // Create a list of CoinPackedVectors
00878   if (number) {
00879     CoinPackedVectorBase ** columns=
00880       new CoinPackedVectorBase * [number];
00881     int iColumn;
00882     for (iColumn=0;iColumn<number;iColumn++) {
00883       int iStart = columnStarts[iColumn];
00884       columns[iColumn] = 
00885         new CoinPackedVector(columnStarts[iColumn+1]-iStart,
00886                              rows+iStart,elements+iStart);
00887     }
00888     addColumns(number, columnLower, columnUpper,
00889                objIn, columns);
00890     for (iColumn=0;iColumn<number;iColumn++) 
00891       delete columns[iColumn];
00892     delete [] columns;
00893 
00894   }
00895 }
00896 // Add columns
00897 void 
00898 ClpModel::addColumns(int number, const double * columnLower, 
00899                      const double * columnUpper,
00900                      const double * objIn,
00901                      const int * columnStarts, 
00902                      const int * columnLengths, const int * rows,
00903                      const double * elements)
00904 {
00905   // Create a list of CoinPackedVectors
00906   if (number) {
00907     CoinPackedVectorBase ** columns=
00908       new CoinPackedVectorBase * [number];
00909     int iColumn;
00910     for (iColumn=0;iColumn<number;iColumn++) {
00911       int iStart = columnStarts[iColumn];
00912       columns[iColumn] = 
00913         new CoinPackedVector(columnLengths[iColumn],
00914                              rows+iStart,elements+iStart);
00915     }
00916     addColumns(number, columnLower, columnUpper,
00917                objIn, columns);
00918     for (iColumn=0;iColumn<number;iColumn++) 
00919       delete columns[iColumn];
00920     delete [] columns;
00921 
00922   }
00923 }
00924 void 
00925 ClpModel::addColumns(int number, const double * columnLower, 
00926                      const double * columnUpper,
00927                      const double * objIn,
00928                      const CoinPackedVectorBase * const * columns)
00929 {
00930   if (!number)
00931     return;
00932   int numberColumnsNow = numberColumns_;
00933   resize(numberRows_,numberColumnsNow+number);
00934   double * lower = columnLower_+numberColumnsNow;
00935   double * upper = columnUpper_+numberColumnsNow;
00936   double * obj = objective()+numberColumnsNow;
00937   int iColumn;
00938   if (columnLower) {
00939     for (iColumn = 0; iColumn < number; iColumn++) {
00940       double value = columnLower[iColumn];
00941       if (value<-1.0e20)
00942         value = -COIN_DBL_MAX;
00943       lower[iColumn]= value;
00944     }
00945   } else {
00946     for (iColumn = 0; iColumn < number; iColumn++) {
00947       lower[iColumn]= 0.0;
00948     }
00949   }
00950   if (columnUpper) {
00951     for (iColumn = 0; iColumn < number; iColumn++) {
00952       double value = columnUpper[iColumn];
00953       if (value>1.0e20)
00954         value = COIN_DBL_MAX;
00955       upper[iColumn]= value;
00956     }
00957   } else {
00958     for (iColumn = 0; iColumn < number; iColumn++) {
00959       upper[iColumn]= COIN_DBL_MAX;
00960     }
00961   }
00962   if (objIn) {
00963     for (iColumn = 0; iColumn < number; iColumn++) {
00964       obj[iColumn] = objIn[iColumn];
00965     }
00966   } else {
00967     for (iColumn = 0; iColumn < number; iColumn++) {
00968       obj[iColumn]= 0.0;
00969     }
00970   }
00971   // Deal with matrix
00972 
00973   delete rowCopy_;
00974   rowCopy_=NULL;
00975   if (!matrix_)
00976     createEmptyMatrix();
00977   matrix_->appendCols(number,columns);
00978 }
00979 // Infeasibility/unbounded ray (NULL returned if none/wrong)
00980 double * 
00981 ClpModel::infeasibilityRay() const
00982 {
00983   double * array = NULL;
00984   if (problemStatus_==1&&!secondaryStatus_) 
00985     array = ClpCopyOfArray(ray_,numberRows_);
00986   return array;
00987 }
00988 double * 
00989 ClpModel::unboundedRay() const
00990 {
00991   double * array = NULL;
00992   if (problemStatus_==2) 
00993     array = ClpCopyOfArray(ray_,numberColumns_);
00994   return array;
00995 }
00996 void 
00997 ClpModel::setMaximumIterations(int value)
00998 {
00999   if(value>=0)
01000     intParam_[ClpMaxNumIteration]=value;
01001 }
01002 void 
01003 ClpModel::setMaximumSeconds(double value)
01004 {
01005   if(value>=0)
01006     dblParam_[ClpMaxSeconds]=value+CoinCpuTime();
01007   else
01008     dblParam_[ClpMaxSeconds]=-1.0;
01009 }
01010 // Returns true if hit maximum iterations (or time)
01011 bool 
01012 ClpModel::hitMaximumIterations() const
01013 {
01014   bool hitMax= (numberIterations_>=maximumIterations());
01015   if (dblParam_[ClpMaxSeconds]>=0.0&&!hitMax)
01016     hitMax = (CoinCpuTime()>=dblParam_[ClpMaxSeconds]);
01017   return hitMax;
01018 }
01019 // Pass in Message handler (not deleted at end)
01020 void 
01021 ClpModel::passInMessageHandler(CoinMessageHandler * handler)
01022 {
01023   if (defaultHandler_)
01024     delete handler_;
01025   defaultHandler_=false;
01026   handler_=handler;
01027 }
01028 // Set language
01029 void 
01030 ClpModel::newLanguage(CoinMessages::Language language)
01031 {
01032   messages_ = ClpMessage(language);
01033 }
01034 // Read an mps file from the given filename
01035 int 
01036 ClpModel::readMps(const char *fileName,
01037                   bool keepNames,
01038                   bool ignoreErrors)
01039 {
01040   bool canOpen=false;
01041   if (!strcmp(fileName,"-")||!strcmp(fileName,"stdin")) {
01042     // stdin
01043     canOpen=true;
01044   } else {
01045     FILE *fp=fopen(fileName,"r");
01046     if (fp) {
01047       // can open - lets go for it
01048       fclose(fp);
01049       canOpen=true;
01050     } else {
01051       handler_->message(CLP_UNABLE_OPEN,messages_)
01052         <<fileName<<CoinMessageEol;
01053       return -1;
01054     }
01055   }
01056   CoinMpsIO m;
01057   m.passInMessageHandler(handler_);
01058   bool savePrefix =m.messageHandler()->prefix();
01059   m.messageHandler()->setPrefix(handler_->prefix());
01060   double time1 = CoinCpuTime(),time2;
01061   int status=m.readMps(fileName,"");
01062   m.messageHandler()->setPrefix(savePrefix);
01063   if (!status||ignoreErrors) {
01064     loadProblem(*m.getMatrixByCol(),
01065                 m.getColLower(),m.getColUpper(),
01066                 m.getObjCoefficients(),
01067                 m.getRowLower(),m.getRowUpper());
01068     if (m.integerColumns()) {
01069       integerType_ = new char[numberColumns_];
01070       memcpy(integerType_,m.integerColumns(),numberColumns_*sizeof(char));
01071     } else {
01072       integerType_ = NULL;
01073     }
01074     // set problem name
01075     setStrParam(ClpProbName,m.getProblemName());
01076     // do names
01077     if (keepNames) {
01078       unsigned int maxLength=0;
01079       int iRow;
01080       rowNames_ = std::vector<std::string> ();
01081       columnNames_ = std::vector<std::string> ();
01082       rowNames_.reserve(numberRows_);
01083       for (iRow=0;iRow<numberRows_;iRow++) {
01084         const char * name = m.rowName(iRow);
01085         maxLength = max(maxLength,(unsigned int) strlen(name));
01086           rowNames_.push_back(name);
01087       }
01088       
01089       int iColumn;
01090       columnNames_.reserve(numberColumns_);
01091       for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01092         const char * name = m.columnName(iColumn);
01093         maxLength = max(maxLength,(unsigned int) strlen(name));
01094         columnNames_.push_back(name);
01095       }
01096       lengthNames_=(int) maxLength;
01097     } else {
01098       lengthNames_=0;
01099     }
01100     setDblParam(ClpObjOffset,m.objectiveOffset());
01101     time2 = CoinCpuTime();
01102     handler_->message(CLP_IMPORT_RESULT,messages_)
01103       <<fileName
01104       <<time2-time1<<CoinMessageEol;
01105   } else {
01106     // errors
01107     handler_->message(CLP_IMPORT_ERRORS,messages_)
01108       <<status<<fileName<<CoinMessageEol;
01109   }
01110 
01111   return status;
01112 }
01113 bool ClpModel::isPrimalObjectiveLimitReached() const
01114 {
01115   double limit = 0.0;
01116   getDblParam(ClpPrimalObjectiveLimit, limit);
01117   if (limit > 1e30) {
01118     // was not ever set
01119     return false;
01120   }
01121    
01122   const double obj = objectiveValue();
01123   const double maxmin = optimizationDirection();
01124 
01125   if (problemStatus_ == 0) // optimal
01126     return maxmin > 0 ? (obj < limit) /*minim*/ : (-obj < limit) /*maxim*/;
01127   else if (problemStatus_==2)
01128     return true;
01129   else
01130     return false;
01131 }
01132 
01133 bool ClpModel::isDualObjectiveLimitReached() const
01134 {
01135 
01136   double limit = 0.0;
01137   getDblParam(ClpDualObjectiveLimit, limit);
01138   if (limit > 1e30) {
01139     // was not ever set
01140     return false;
01141   }
01142    
01143   const double obj = objectiveValue();
01144   const double maxmin = optimizationDirection();
01145 
01146   if (problemStatus_ == 0) // optimal
01147     return maxmin > 0 ? (obj > limit) /*minim*/ : (-obj > limit) /*maxim*/;
01148   else if (problemStatus_==1)
01149     return true;
01150   else
01151     return false;
01152 
01153 }
01154 void 
01155 ClpModel::copyInIntegerInformation(const char * information)
01156 {
01157   delete [] integerType_;
01158   if (information) {
01159     integerType_ = new char[numberColumns_];
01160     memcpy(integerType_,information,numberColumns_*sizeof(char));
01161   } else {
01162     integerType_ = NULL;
01163   }
01164 }
01165 // Drops names - makes lengthnames 0 and names empty
01166 void 
01167 ClpModel::dropNames()
01168 {
01169   lengthNames_=0;
01170   rowNames_ = std::vector<std::string> ();
01171   columnNames_ = std::vector<std::string> ();
01172 }
01173 // Drop integer informations
01174 void 
01175 ClpModel::deleteIntegerInformation()
01176 {
01177   delete [] integerType_;
01178   integerType_ = NULL;
01179 }
01180 /* Return copy of status array (char[numberRows+numberColumns]),
01181    use delete [] */
01182 unsigned char *  
01183 ClpModel::statusCopy() const
01184 {
01185   return ClpCopyOfArray(status_,numberRows_+numberColumns_);
01186 }
01187 // Copy in status vector
01188 void 
01189 ClpModel::copyinStatus(const unsigned char * statusArray)
01190 {
01191   delete [] status_;
01192   if (statusArray) {
01193     status_ = new unsigned char [numberRows_+numberColumns_];
01194     memcpy(status_,statusArray,(numberRows_+numberColumns_)*sizeof(unsigned char));
01195   } else {
01196     status_=NULL;
01197   }
01198 }
01199 
01200 // Load up quadratic objective 
01201 void 
01202 ClpModel::loadQuadraticObjective(const int numberColumns, const CoinBigIndex * start,
01203                               const int * column, const double * element)
01204 {
01205   assert (numberColumns==numberColumns_);
01206   assert ((dynamic_cast< ClpLinearObjective*>(objective_)));
01207   double offset;
01208   ClpObjective * obj = new ClpQuadraticObjective(objective_->gradient(NULL,offset,false),numberColumns,
01209                                              start,column,element);
01210   delete objective_;
01211   objective_ = obj;
01212 
01213 }
01214 void 
01215 ClpModel::loadQuadraticObjective (  const CoinPackedMatrix& matrix)
01216 {
01217   assert (matrix.getNumCols()==numberColumns_);
01218   assert ((dynamic_cast< ClpLinearObjective*>(objective_)));
01219   double offset;
01220   ClpQuadraticObjective * obj = 
01221     new ClpQuadraticObjective(objective_->gradient(NULL,offset,false),numberColumns_,
01222                                                  NULL,NULL,NULL);
01223   delete objective_;
01224   objective_ = obj;
01225   obj->loadQuadraticObjective(matrix);
01226 }
01227 // Get rid of quadratic objective
01228 void 
01229 ClpModel::deleteQuadraticObjective()
01230 {
01231   ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
01232   if (obj)
01233     obj->deleteQuadraticObjective();
01234 }
01235 void 
01236 ClpModel::setObjective(ClpObjective * objective)
01237 {
01238   delete objective_;
01239   objective_=objective->clone();
01240 }
01241 // Returns resized array and updates size
01242 double * whichDouble(double * array , int number, const int * which)
01243 {
01244   double * newArray=NULL;
01245   if (array&&number) {
01246     int i ;
01247     newArray = new double[number];
01248     for (i=0;i<number;i++) 
01249       newArray[i]=array[which[i]];
01250   }
01251   return newArray;
01252 }
01253 char * whichChar(char * array , int number, const int * which)
01254 {
01255   char * newArray=NULL;
01256   if (array&&number) {
01257     int i ;
01258     newArray = new char[number];
01259     for (i=0;i<number;i++) 
01260       newArray[i]=array[which[i]];
01261   }
01262   return newArray;
01263 }
01264 unsigned char * whichUnsignedChar(unsigned char * array , 
01265                                   int number, const int * which)
01266 {
01267   unsigned char * newArray=NULL;
01268   if (array&&number) {
01269     int i ;
01270     newArray = new unsigned char[number];
01271     for (i=0;i<number;i++) 
01272       newArray[i]=array[which[i]];
01273   }
01274   return newArray;
01275 }
01276 // Replace Clp Matrix (current is not deleted)
01277 void 
01278 ClpModel::replaceMatrix( ClpMatrixBase * matrix)
01279 {
01280   matrix_=matrix;
01281 }
01282 // Subproblem constructor
01283 ClpModel::ClpModel ( const ClpModel * rhs,
01284                      int numberRows, const int * whichRow,
01285                      int numberColumns, const int * whichColumn,
01286                      bool dropNames, bool dropIntegers)
01287 {
01288 #if 0
01289   // Could be recoded to be faster and take less memory
01290   // and to allow re-ordering and duplicates etc
01291   gutsOfCopy(*rhs,true);
01292   int numberRowsWhole = rhs->numberRows();
01293   int * delRow = new int[numberRowsWhole];
01294   memset(delRow,0,numberRowsWhole*sizeof(int));
01295   int i;
01296   for (i=0;i<numberRows;i++) {
01297     int iRow=whichRow[i];
01298     assert (iRow>=0&&iRow<numberRowsWhole);
01299     delRow[iRow]=1;
01300   }
01301   numberRows=0;
01302   for (i=0;i<numberRowsWhole;i++) {
01303     if (delRow[i]==0)
01304       delRow[numberRows++]=i;
01305   }
01306   deleteRows(numberRows,delRow);
01307   delete [] delRow;
01308   int numberColumnsWhole = rhs->numberColumns();
01309   int * delColumn = new int[numberColumnsWhole];
01310   memset(delColumn,0,numberColumnsWhole*sizeof(int));
01311   for (i=0;i<numberColumns;i++) {
01312     int iColumn=whichColumn[i];
01313     assert (iColumn>=0&&iColumn<numberColumnsWhole);
01314     delColumn[iColumn]=1;
01315   }
01316   numberColumns=0;
01317   for (i=0;i<numberColumnsWhole;i++) {
01318     if (delColumn[i]==0)
01319       delColumn[numberColumns++]=i;
01320   }
01321   deleteColumns(numberColumns,delColumn);
01322   delete [] delColumn;
01323 #else
01324   defaultHandler_ = rhs->defaultHandler_;
01325   if (defaultHandler_) 
01326     handler_ = new CoinMessageHandler(*rhs->handler_);
01327    else 
01328     handler_ = rhs->handler_;
01329   messages_ = rhs->messages_;
01330   intParam_[ClpMaxNumIteration] = rhs->intParam_[ClpMaxNumIteration];
01331   intParam_[ClpMaxNumIterationHotStart] = 
01332     rhs->intParam_[ClpMaxNumIterationHotStart];
01333 
01334   dblParam_[ClpDualObjectiveLimit] = rhs->dblParam_[ClpDualObjectiveLimit];
01335   dblParam_[ClpPrimalObjectiveLimit] = rhs->dblParam_[ClpPrimalObjectiveLimit];
01336   dblParam_[ClpDualTolerance] = rhs->dblParam_[ClpDualTolerance];
01337   dblParam_[ClpPrimalTolerance] = rhs->dblParam_[ClpPrimalTolerance];
01338   dblParam_[ClpObjOffset] = rhs->dblParam_[ClpObjOffset];
01339   dblParam_[ClpMaxSeconds] = rhs->dblParam_[ClpMaxSeconds];
01340 
01341   strParam_[ClpProbName] = rhs->strParam_[ClpProbName];
01342 
01343   optimizationDirection_ = rhs->optimizationDirection_;
01344   objectiveValue_=rhs->objectiveValue_;
01345   smallElement_ = rhs->smallElement_;
01346   numberIterations_ = rhs->numberIterations_;
01347   solveType_ = rhs->solveType_;
01348   problemStatus_ = rhs->problemStatus_;
01349   secondaryStatus_ = rhs->secondaryStatus_;
01350   // check valid lists
01351   int numberBad=0;
01352   int i;
01353   for (i=0;i<numberRows;i++)
01354     if (whichRow[i]<0||whichRow[i]>=rhs->numberRows_)
01355       numberBad++;
01356   if (numberBad)
01357     throw CoinError("bad row list", "subproblem constructor", "ClpModel");
01358   numberBad=0;
01359   for (i=0;i<numberColumns;i++)
01360     if (whichColumn[i]<0||whichColumn[i]>=rhs->numberColumns_)
01361       numberBad++;
01362   if (numberBad)
01363     throw CoinError("bad column list", "subproblem constructor", "ClpModel");
01364   numberRows_ = numberRows;
01365   numberColumns_ = numberColumns;
01366   userPointer_ = rhs->userPointer_;
01367   if (!dropNames) {
01368     unsigned int maxLength=0;
01369     int iRow;
01370     rowNames_ = std::vector<std::string> ();
01371     columnNames_ = std::vector<std::string> ();
01372     rowNames_.reserve(numberRows_);
01373     for (iRow=0;iRow<numberRows_;iRow++) {
01374       rowNames_[iRow] = rhs->rowNames_[whichRow[iRow]];
01375       maxLength = max(maxLength,(unsigned int) strlen(rowNames_[iRow].c_str()));
01376     }
01377     int iColumn;
01378     columnNames_.reserve(numberColumns_);
01379     for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01380       columnNames_[iColumn] = rhs->columnNames_[whichColumn[iColumn]];
01381       maxLength = max(maxLength,(unsigned int) strlen(columnNames_[iColumn].c_str()));
01382     }
01383     lengthNames_=(int) maxLength;
01384   } else {
01385     lengthNames_ = 0;
01386     rowNames_ = std::vector<std::string> ();
01387     columnNames_ = std::vector<std::string> ();
01388   }
01389   if (rhs->integerType_&&!dropIntegers) {
01390     integerType_ = whichChar(rhs->integerType_,numberColumns,whichColumn);
01391   } else {
01392     integerType_ = NULL;
01393   }
01394   if (rhs->rowActivity_) {
01395     rowActivity_=whichDouble(rhs->rowActivity_,numberRows,whichRow);
01396     dual_=whichDouble(rhs->dual_,numberRows,whichRow);
01397     columnActivity_=whichDouble(rhs->columnActivity_,numberColumns,
01398                                 whichColumn);
01399     reducedCost_=whichDouble(rhs->reducedCost_,numberColumns,
01400                                 whichColumn);
01401   } else {
01402     rowActivity_=NULL;
01403     columnActivity_=NULL;
01404     dual_=NULL;
01405     reducedCost_=NULL;
01406   }
01407   rowLower_=whichDouble(rhs->rowLower_,numberRows,whichRow);
01408   rowUpper_=whichDouble(rhs->rowUpper_,numberRows,whichRow);
01409   columnLower_=whichDouble(rhs->columnLower_,numberColumns,whichColumn);
01410   columnUpper_=whichDouble(rhs->columnUpper_,numberColumns,whichColumn);
01411   if (rhs->objective_)
01412     objective_  = rhs->objective_->subsetClone(numberColumns,whichColumn);
01413   else
01414     objective_ = NULL;
01415   rowObjective_=whichDouble(rhs->rowObjective_,numberRows,whichRow);
01416   // status has to be done in two stages
01417   status_ = new unsigned char[numberColumns_+numberRows_];
01418   unsigned char * rowStatus = whichUnsignedChar(rhs->status_+rhs->numberColumns_,
01419                                                 numberRows_,whichRow);
01420   unsigned char * columnStatus = whichUnsignedChar(rhs->status_,
01421                                                 numberColumns_,whichColumn);
01422   memcpy(status_+numberColumns_,rowStatus,numberRows_);
01423   delete [] rowStatus;
01424   memcpy(status_,columnStatus,numberColumns_);
01425   delete [] columnStatus;
01426   ray_ = NULL;
01427   if (problemStatus_==1&&!secondaryStatus_)
01428     ray_ = whichDouble (rhs->ray_,numberRows,whichRow);
01429   else if (problemStatus_==2)
01430     ray_ = whichDouble (rhs->ray_,numberColumns,whichColumn);
01431   if (rhs->rowCopy_) {
01432     rowCopy_ = rhs->rowCopy_->subsetClone(numberRows,whichRow,
01433                                           numberColumns,whichColumn);
01434   } else {
01435     rowCopy_=NULL;
01436   }
01437   matrix_=NULL;
01438   if (rhs->matrix_) {
01439     matrix_ = rhs->matrix_->subsetClone(numberRows,whichRow,
01440                                         numberColumns,whichColumn);
01441   }
01442 #endif
01443 }
01444 // Copies in names
01445 void 
01446 ClpModel::copyNames(std::vector<std::string> & rowNames,
01447                  std::vector<std::string> & columnNames)
01448 {
01449   unsigned int maxLength=0;
01450   int iRow;
01451   rowNames_ = std::vector<std::string> ();
01452   columnNames_ = std::vector<std::string> ();
01453   rowNames_.reserve(numberRows_);
01454   for (iRow=0;iRow<numberRows_;iRow++) {
01455     rowNames_.push_back(rowNames[iRow]);
01456     maxLength = max(maxLength,(unsigned int) strlen(rowNames_[iRow].c_str()));
01457   }
01458   int iColumn;
01459   columnNames_.reserve(numberColumns_);
01460   for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01461     columnNames_.push_back(columnNames[iColumn]);
01462     maxLength = max(maxLength,(unsigned int) strlen(columnNames_[iColumn].c_str()));
01463   }
01464   lengthNames_=(int) maxLength;
01465 }
01466 // Dual objective limit
01467 void 
01468 ClpModel::setDualObjectiveLimit(double value)
01469 {
01470   dblParam_[ClpDualObjectiveLimit]=value;
01471 }
01472 // Objective offset
01473 void 
01474 ClpModel::setObjectiveOffset(double value)
01475 {
01476   dblParam_[ClpObjOffset]=value;
01477 }
01478 //#############################################################################
01479 // Constructors / Destructor / Assignment
01480 //#############################################################################
01481 
01482 //-------------------------------------------------------------------
01483 // Default Constructor 
01484 //-------------------------------------------------------------------
01485 ClpDataSave::ClpDataSave () 
01486 {
01487   dualBound_ = 0.0;
01488   infeasibilityCost_ = 0.0;
01489   sparseThreshold_ = 0;
01490   perturbation_ = 0;
01491 }
01492 
01493 //-------------------------------------------------------------------
01494 // Copy constructor 
01495 //-------------------------------------------------------------------
01496 ClpDataSave::ClpDataSave (const ClpDataSave & rhs) 
01497 {  
01498   dualBound_ = rhs.dualBound_;
01499   infeasibilityCost_ = rhs.infeasibilityCost_;
01500   sparseThreshold_ = rhs.sparseThreshold_;
01501   perturbation_ = rhs.perturbation_;
01502 }
01503 
01504 //-------------------------------------------------------------------
01505 // Destructor 
01506 //-------------------------------------------------------------------
01507 ClpDataSave::~ClpDataSave ()
01508 {
01509 
01510 }
01511 
01512 //----------------------------------------------------------------
01513 // Assignment operator 
01514 //-------------------------------------------------------------------
01515 ClpDataSave &
01516 ClpDataSave::operator=(const ClpDataSave& rhs)
01517 {
01518   if (this != &rhs) {
01519     dualBound_ = rhs.dualBound_;
01520     infeasibilityCost_ = rhs.infeasibilityCost_;
01521     sparseThreshold_ = rhs.sparseThreshold_;
01522     perturbation_ = rhs.perturbation_;
01523   }
01524   return *this;
01525 }

Generated on Wed Dec 3 14:37:27 2003 for CLP by doxygen 1.3.5