[800] | 1 | // copyright (C) 2002, International Business Machines |
---|
[2] | 2 | // Corporation and others. All Rights Reserved. |
---|
| 3 | |
---|
[1185] | 4 | #include <cstdlib> |
---|
[50] | 5 | #include <cmath> |
---|
[2] | 6 | #include <cassert> |
---|
| 7 | #include <cfloat> |
---|
| 8 | #include <string> |
---|
[50] | 9 | #include <cstdio> |
---|
[2] | 10 | #include <iostream> |
---|
[50] | 11 | |
---|
[63] | 12 | |
---|
| 13 | #include "CoinPragma.hpp" |
---|
[2] | 14 | |
---|
[50] | 15 | #include "CoinHelperFunctions.hpp" |
---|
[225] | 16 | #include "CoinTime.hpp" |
---|
[50] | 17 | #include "ClpModel.hpp" |
---|
[344] | 18 | #include "ClpEventHandler.hpp" |
---|
[50] | 19 | #include "ClpPackedMatrix.hpp" |
---|
[650] | 20 | #ifndef SLIM_CLP |
---|
[557] | 21 | #include "ClpPlusMinusOneMatrix.hpp" |
---|
[650] | 22 | #endif |
---|
[653] | 23 | #ifndef CLP_NO_VECTOR |
---|
[169] | 24 | #include "CoinPackedVector.hpp" |
---|
[653] | 25 | #endif |
---|
[50] | 26 | #include "CoinIndexedVector.hpp" |
---|
[651] | 27 | #if SLIM_CLP==2 |
---|
| 28 | #define SLIM_NOIO |
---|
| 29 | #endif |
---|
| 30 | #ifndef SLIM_NOIO |
---|
[50] | 31 | #include "CoinMpsIO.hpp" |
---|
[603] | 32 | #include "CoinFileIO.hpp" |
---|
[651] | 33 | #include "CoinModel.hpp" |
---|
| 34 | #endif |
---|
[50] | 35 | #include "ClpMessage.hpp" |
---|
[701] | 36 | #include "CoinMessage.hpp" |
---|
[119] | 37 | #include "ClpLinearObjective.hpp" |
---|
[650] | 38 | #ifndef SLIM_CLP |
---|
[225] | 39 | #include "ClpQuadraticObjective.hpp" |
---|
[540] | 40 | #include "CoinBuild.hpp" |
---|
[650] | 41 | #endif |
---|
[50] | 42 | |
---|
[2] | 43 | //############################################################################# |
---|
[1034] | 44 | ClpModel::ClpModel (bool emptyMessages) : |
---|
[2] | 45 | |
---|
| 46 | optimizationDirection_(1), |
---|
[114] | 47 | objectiveValue_(0.0), |
---|
| 48 | smallElement_(1.0e-20), |
---|
[389] | 49 | objectiveScale_(1.0), |
---|
| 50 | rhsScale_(1.0), |
---|
[2] | 51 | numberRows_(0), |
---|
| 52 | numberColumns_(0), |
---|
| 53 | rowActivity_(NULL), |
---|
| 54 | columnActivity_(NULL), |
---|
| 55 | dual_(NULL), |
---|
| 56 | reducedCost_(NULL), |
---|
| 57 | rowLower_(NULL), |
---|
| 58 | rowUpper_(NULL), |
---|
| 59 | objective_(NULL), |
---|
| 60 | rowObjective_(NULL), |
---|
| 61 | columnLower_(NULL), |
---|
| 62 | columnUpper_(NULL), |
---|
| 63 | matrix_(NULL), |
---|
| 64 | rowCopy_(NULL), |
---|
[1150] | 65 | scaledMatrix_(NULL), |
---|
[2] | 66 | ray_(NULL), |
---|
[372] | 67 | rowScale_(NULL), |
---|
| 68 | columnScale_(NULL), |
---|
[1197] | 69 | inverseRowScale_(NULL), |
---|
| 70 | inverseColumnScale_(NULL), |
---|
[749] | 71 | scalingFlag_(3), |
---|
[114] | 72 | status_(NULL), |
---|
| 73 | integerType_(NULL), |
---|
[240] | 74 | userPointer_(NULL), |
---|
[2] | 75 | numberIterations_(0), |
---|
[109] | 76 | solveType_(0), |
---|
[472] | 77 | whatsChanged_(0), |
---|
[2] | 78 | problemStatus_(-1), |
---|
[225] | 79 | secondaryStatus_(0), |
---|
[114] | 80 | lengthNames_(0), |
---|
[740] | 81 | numberThreads_(0), |
---|
[1034] | 82 | specialOptions_(0), |
---|
[653] | 83 | #ifndef CLP_NO_STD |
---|
[2] | 84 | defaultHandler_(true), |
---|
| 85 | rowNames_(), |
---|
[1147] | 86 | columnNames_(), |
---|
[653] | 87 | #else |
---|
[1147] | 88 | defaultHandler_(true), |
---|
[653] | 89 | #endif |
---|
[1147] | 90 | maximumColumns_(-1), |
---|
| 91 | maximumRows_(-1), |
---|
[1197] | 92 | maximumInternalColumns_(-1), |
---|
| 93 | maximumInternalRows_(-1), |
---|
[1147] | 94 | savedRowScale_(NULL), |
---|
| 95 | savedColumnScale_(NULL) |
---|
[2] | 96 | { |
---|
[676] | 97 | intParam_[ClpMaxNumIteration] = 2147483647; |
---|
[50] | 98 | intParam_[ClpMaxNumIterationHotStart] = 9999999; |
---|
[1015] | 99 | intParam_[ClpNameDiscipline] = 0; |
---|
[2] | 100 | |
---|
[123] | 101 | dblParam_[ClpDualObjectiveLimit] = COIN_DBL_MAX; |
---|
| 102 | dblParam_[ClpPrimalObjectiveLimit] = COIN_DBL_MAX; |
---|
[50] | 103 | dblParam_[ClpDualTolerance] = 1e-7; |
---|
| 104 | dblParam_[ClpPrimalTolerance] = 1e-7; |
---|
| 105 | dblParam_[ClpObjOffset] = 0.0; |
---|
[142] | 106 | dblParam_[ClpMaxSeconds] = -1.0; |
---|
[708] | 107 | dblParam_[ClpPresolveTolerance] = 1.0e-8; |
---|
[2] | 108 | |
---|
[653] | 109 | #ifndef CLP_NO_STD |
---|
[50] | 110 | strParam_[ClpProbName] = "ClpDefaultName"; |
---|
[653] | 111 | #endif |
---|
[50] | 112 | handler_ = new CoinMessageHandler(); |
---|
[225] | 113 | handler_->setLogLevel(1); |
---|
[344] | 114 | eventHandler_ = new ClpEventHandler(); |
---|
[1034] | 115 | if (!emptyMessages) { |
---|
| 116 | messages_ = ClpMessage(); |
---|
| 117 | coinMessages_ = CoinMessage(); |
---|
| 118 | } |
---|
[1141] | 119 | randomNumberGenerator_.setSeed(1234567); |
---|
[2] | 120 | } |
---|
| 121 | |
---|
| 122 | //----------------------------------------------------------------------------- |
---|
| 123 | |
---|
| 124 | ClpModel::~ClpModel () |
---|
| 125 | { |
---|
| 126 | if (defaultHandler_) { |
---|
| 127 | delete handler_; |
---|
| 128 | handler_ = NULL; |
---|
| 129 | } |
---|
[1147] | 130 | gutsOfDelete(0); |
---|
[2] | 131 | } |
---|
[1147] | 132 | // Does most of deletion (0 = all, 1 = most) |
---|
| 133 | void |
---|
| 134 | ClpModel::gutsOfDelete(int type) |
---|
[2] | 135 | { |
---|
[1147] | 136 | if (!type||!permanentArrays()) { |
---|
| 137 | maximumRows_=-1; |
---|
| 138 | maximumColumns_ = -1; |
---|
| 139 | delete [] rowActivity_; |
---|
| 140 | rowActivity_=NULL; |
---|
| 141 | delete [] columnActivity_; |
---|
| 142 | columnActivity_=NULL; |
---|
| 143 | delete [] dual_; |
---|
| 144 | dual_=NULL; |
---|
| 145 | delete [] reducedCost_; |
---|
| 146 | reducedCost_=NULL; |
---|
| 147 | delete [] rowLower_; |
---|
| 148 | delete [] rowUpper_; |
---|
| 149 | delete [] rowObjective_; |
---|
| 150 | rowLower_=NULL; |
---|
| 151 | rowUpper_=NULL; |
---|
| 152 | rowObjective_=NULL; |
---|
| 153 | delete [] columnLower_; |
---|
| 154 | delete [] columnUpper_; |
---|
| 155 | delete objective_; |
---|
| 156 | columnLower_=NULL; |
---|
| 157 | columnUpper_=NULL; |
---|
| 158 | objective_=NULL; |
---|
| 159 | delete [] savedRowScale_; |
---|
| 160 | if (rowScale_==savedRowScale_) |
---|
| 161 | rowScale_=NULL; |
---|
| 162 | savedRowScale_ = NULL; |
---|
| 163 | delete [] savedColumnScale_; |
---|
| 164 | if (columnScale_==savedColumnScale_) |
---|
| 165 | columnScale_=NULL; |
---|
| 166 | savedColumnScale_ = NULL; |
---|
| 167 | delete [] rowScale_; |
---|
| 168 | rowScale_ = NULL; |
---|
| 169 | delete [] columnScale_; |
---|
| 170 | columnScale_ = NULL; |
---|
| 171 | delete [] integerType_; |
---|
| 172 | integerType_ = NULL; |
---|
| 173 | delete [] status_; |
---|
| 174 | status_=NULL; |
---|
| 175 | delete eventHandler_; |
---|
| 176 | eventHandler_=NULL; |
---|
| 177 | } |
---|
| 178 | whatsChanged_=0; |
---|
[2] | 179 | delete matrix_; |
---|
| 180 | matrix_=NULL; |
---|
| 181 | delete rowCopy_; |
---|
| 182 | rowCopy_=NULL; |
---|
[1150] | 183 | delete scaledMatrix_; |
---|
| 184 | scaledMatrix_=NULL, |
---|
[2] | 185 | delete [] ray_; |
---|
| 186 | ray_ = NULL; |
---|
[1034] | 187 | specialOptions_ = 0; |
---|
[2] | 188 | } |
---|
[1147] | 189 | void |
---|
| 190 | ClpModel::setRowScale(double * scale) |
---|
| 191 | { |
---|
| 192 | if (!savedRowScale_) { |
---|
| 193 | delete [] (double *) rowScale_; |
---|
| 194 | rowScale_ = scale; |
---|
| 195 | } else { |
---|
| 196 | assert (!scale); |
---|
| 197 | rowScale_ = NULL; |
---|
| 198 | } |
---|
| 199 | } |
---|
| 200 | void |
---|
| 201 | ClpModel::setColumnScale(double * scale) |
---|
| 202 | { |
---|
| 203 | if (!savedColumnScale_) { |
---|
| 204 | delete [] (double *) columnScale_; |
---|
| 205 | columnScale_ = scale; |
---|
| 206 | } else { |
---|
| 207 | assert (!scale); |
---|
| 208 | columnScale_ = NULL; |
---|
| 209 | } |
---|
| 210 | } |
---|
[2] | 211 | //############################################################################# |
---|
| 212 | void ClpModel::setPrimalTolerance( double value) |
---|
| 213 | { |
---|
[647] | 214 | if (value>0.0&&value<1.0e10) |
---|
[50] | 215 | dblParam_[ClpPrimalTolerance]=value; |
---|
[2] | 216 | } |
---|
| 217 | void ClpModel::setDualTolerance( double value) |
---|
| 218 | { |
---|
| 219 | if (value>0.0&&value<1.0e10) |
---|
[50] | 220 | dblParam_[ClpDualTolerance]=value; |
---|
[2] | 221 | } |
---|
[225] | 222 | void ClpModel::setOptimizationDirection( double value) |
---|
[2] | 223 | { |
---|
[225] | 224 | optimizationDirection_=value; |
---|
[2] | 225 | } |
---|
| 226 | void |
---|
| 227 | ClpModel::gutsOfLoadModel (int numberRows, int numberColumns, |
---|
| 228 | const double* collb, const double* colub, |
---|
| 229 | const double* obj, |
---|
| 230 | const double* rowlb, const double* rowub, |
---|
| 231 | const double * rowObjective) |
---|
| 232 | { |
---|
[344] | 233 | // save event handler in case already set |
---|
| 234 | ClpEventHandler * handler = eventHandler_->clone(); |
---|
[1053] | 235 | // Save specialOptions |
---|
| 236 | int saveOptions = specialOptions_; |
---|
[1147] | 237 | gutsOfDelete(0); |
---|
[1053] | 238 | specialOptions_ = saveOptions; |
---|
[344] | 239 | eventHandler_ = handler; |
---|
[2] | 240 | numberRows_=numberRows; |
---|
| 241 | numberColumns_=numberColumns; |
---|
| 242 | rowActivity_=new double[numberRows_]; |
---|
| 243 | columnActivity_=new double[numberColumns_]; |
---|
| 244 | dual_=new double[numberRows_]; |
---|
| 245 | reducedCost_=new double[numberColumns_]; |
---|
| 246 | |
---|
[706] | 247 | CoinZeroN(dual_,numberRows_); |
---|
| 248 | CoinZeroN(reducedCost_,numberColumns_); |
---|
[2] | 249 | int iRow,iColumn; |
---|
| 250 | |
---|
[123] | 251 | rowLower_=ClpCopyOfArray(rowlb,numberRows_,-COIN_DBL_MAX); |
---|
| 252 | rowUpper_=ClpCopyOfArray(rowub,numberRows_,COIN_DBL_MAX); |
---|
[119] | 253 | double * objective=ClpCopyOfArray(obj,numberColumns_,0.0); |
---|
| 254 | objective_ = new ClpLinearObjective(objective,numberColumns_); |
---|
| 255 | delete [] objective; |
---|
[50] | 256 | rowObjective_=ClpCopyOfArray(rowObjective,numberRows_); |
---|
| 257 | columnLower_=ClpCopyOfArray(collb,numberColumns_,0.0); |
---|
[123] | 258 | columnUpper_=ClpCopyOfArray(colub,numberColumns_,COIN_DBL_MAX); |
---|
[466] | 259 | // set default solution and clean bounds |
---|
[2] | 260 | for (iRow=0;iRow<numberRows_;iRow++) { |
---|
| 261 | if (rowLower_[iRow]>0.0) { |
---|
| 262 | rowActivity_[iRow]=rowLower_[iRow]; |
---|
| 263 | } else if (rowUpper_[iRow]<0.0) { |
---|
| 264 | rowActivity_[iRow]=rowUpper_[iRow]; |
---|
| 265 | } else { |
---|
| 266 | rowActivity_[iRow]=0.0; |
---|
| 267 | } |
---|
[466] | 268 | if (rowLower_[iRow]<-1.0e27) |
---|
| 269 | rowLower_[iRow]=-COIN_DBL_MAX; |
---|
| 270 | if (rowUpper_[iRow]>1.0e27) |
---|
| 271 | rowUpper_[iRow]=COIN_DBL_MAX; |
---|
[2] | 272 | } |
---|
| 273 | for (iColumn=0;iColumn<numberColumns_;iColumn++) { |
---|
| 274 | if (columnLower_[iColumn]>0.0) { |
---|
| 275 | columnActivity_[iColumn]=columnLower_[iColumn]; |
---|
| 276 | } else if (columnUpper_[iColumn]<0.0) { |
---|
| 277 | columnActivity_[iColumn]=columnUpper_[iColumn]; |
---|
| 278 | } else { |
---|
| 279 | columnActivity_[iColumn]=0.0; |
---|
| 280 | } |
---|
[466] | 281 | if (columnLower_[iColumn]<-1.0e27) |
---|
| 282 | columnLower_[iColumn]=-COIN_DBL_MAX; |
---|
| 283 | if (columnUpper_[iColumn]>1.0e27) |
---|
| 284 | columnUpper_[iColumn]=COIN_DBL_MAX; |
---|
[2] | 285 | } |
---|
| 286 | } |
---|
[133] | 287 | // This just loads up a row objective |
---|
[134] | 288 | void ClpModel::setRowObjective(const double * rowObjective) |
---|
[133] | 289 | { |
---|
| 290 | delete [] rowObjective_; |
---|
| 291 | rowObjective_=ClpCopyOfArray(rowObjective,numberRows_); |
---|
[472] | 292 | whatsChanged_=0; |
---|
[133] | 293 | } |
---|
[2] | 294 | void |
---|
| 295 | ClpModel::loadProblem ( const ClpMatrixBase& matrix, |
---|
| 296 | const double* collb, const double* colub, |
---|
| 297 | const double* obj, |
---|
| 298 | const double* rowlb, const double* rowub, |
---|
| 299 | const double * rowObjective) |
---|
| 300 | { |
---|
| 301 | gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(), |
---|
| 302 | collb, colub, obj, rowlb, rowub, rowObjective); |
---|
| 303 | if (matrix.isColOrdered()) { |
---|
| 304 | matrix_=matrix.clone(); |
---|
| 305 | } else { |
---|
| 306 | // later may want to keep as unknown class |
---|
[50] | 307 | CoinPackedMatrix matrix2; |
---|
[2] | 308 | matrix2.reverseOrderedCopyOf(*matrix.getPackedMatrix()); |
---|
| 309 | matrix.releasePackedMatrix(); |
---|
| 310 | matrix_=new ClpPackedMatrix(matrix2); |
---|
| 311 | } |
---|
[558] | 312 | matrix_->setDimensions(numberRows_,numberColumns_); |
---|
[2] | 313 | } |
---|
| 314 | void |
---|
[50] | 315 | ClpModel::loadProblem ( const CoinPackedMatrix& matrix, |
---|
[2] | 316 | const double* collb, const double* colub, |
---|
| 317 | const double* obj, |
---|
| 318 | const double* rowlb, const double* rowub, |
---|
| 319 | const double * rowObjective) |
---|
| 320 | { |
---|
| 321 | gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(), |
---|
| 322 | collb, colub, obj, rowlb, rowub, rowObjective); |
---|
| 323 | if (matrix.isColOrdered()) { |
---|
| 324 | matrix_=new ClpPackedMatrix(matrix); |
---|
| 325 | } else { |
---|
[50] | 326 | CoinPackedMatrix matrix2; |
---|
[2] | 327 | matrix2.reverseOrderedCopyOf(matrix); |
---|
| 328 | matrix_=new ClpPackedMatrix(matrix2); |
---|
| 329 | } |
---|
[558] | 330 | matrix_->setDimensions(numberRows_,numberColumns_); |
---|
[2] | 331 | } |
---|
| 332 | void |
---|
| 333 | ClpModel::loadProblem ( |
---|
| 334 | const int numcols, const int numrows, |
---|
[50] | 335 | const CoinBigIndex* start, const int* index, |
---|
[2] | 336 | const double* value, |
---|
| 337 | const double* collb, const double* colub, |
---|
| 338 | const double* obj, |
---|
| 339 | const double* rowlb, const double* rowub, |
---|
| 340 | const double * rowObjective) |
---|
| 341 | { |
---|
| 342 | gutsOfLoadModel(numrows, numcols, |
---|
| 343 | collb, colub, obj, rowlb, rowub, rowObjective); |
---|
[1034] | 344 | int numberElements = start ? start[numcols] : 0; |
---|
| 345 | CoinPackedMatrix matrix(true,numrows,numrows ? numcols : 0,numberElements, |
---|
[2] | 346 | value,index,start,NULL); |
---|
| 347 | matrix_ = new ClpPackedMatrix(matrix); |
---|
[558] | 348 | matrix_->setDimensions(numberRows_,numberColumns_); |
---|
[2] | 349 | } |
---|
| 350 | void |
---|
[50] | 351 | ClpModel::loadProblem ( |
---|
| 352 | const int numcols, const int numrows, |
---|
| 353 | const CoinBigIndex* start, const int* index, |
---|
| 354 | const double* value,const int* length, |
---|
| 355 | const double* collb, const double* colub, |
---|
| 356 | const double* obj, |
---|
| 357 | const double* rowlb, const double* rowub, |
---|
| 358 | const double * rowObjective) |
---|
| 359 | { |
---|
| 360 | gutsOfLoadModel(numrows, numcols, |
---|
| 361 | collb, colub, obj, rowlb, rowub, rowObjective); |
---|
| 362 | // Compute number of elements |
---|
| 363 | int numberElements = 0; |
---|
| 364 | int i; |
---|
| 365 | for (i=0;i<numcols;i++) |
---|
| 366 | numberElements += length[i]; |
---|
| 367 | CoinPackedMatrix matrix(true,numrows,numcols,numberElements, |
---|
| 368 | value,index,start,length); |
---|
| 369 | matrix_ = new ClpPackedMatrix(matrix); |
---|
| 370 | } |
---|
[651] | 371 | #ifndef SLIM_NOIO |
---|
[546] | 372 | // This loads a model from a coinModel object - returns number of errors |
---|
| 373 | int |
---|
[557] | 374 | ClpModel::loadProblem ( CoinModel & modelObject,bool tryPlusMinusOne) |
---|
[546] | 375 | { |
---|
[1034] | 376 | if (modelObject.numberColumns()==0&&modelObject.numberRows()==0) |
---|
[618] | 377 | return 0; |
---|
[546] | 378 | int numberErrors = 0; |
---|
| 379 | // Set arrays for normal use |
---|
| 380 | double * rowLower = modelObject.rowLowerArray(); |
---|
| 381 | double * rowUpper = modelObject.rowUpperArray(); |
---|
| 382 | double * columnLower = modelObject.columnLowerArray(); |
---|
| 383 | double * columnUpper = modelObject.columnUpperArray(); |
---|
| 384 | double * objective = modelObject.objectiveArray(); |
---|
| 385 | int * integerType = modelObject.integerTypeArray(); |
---|
| 386 | double * associated = modelObject.associatedArray(); |
---|
| 387 | // If strings then do copies |
---|
| 388 | if (modelObject.stringsExist()) { |
---|
| 389 | numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper, |
---|
| 390 | objective, integerType,associated); |
---|
| 391 | } |
---|
| 392 | int numberRows = modelObject.numberRows(); |
---|
| 393 | int numberColumns = modelObject.numberColumns(); |
---|
| 394 | gutsOfLoadModel(numberRows, numberColumns, |
---|
| 395 | columnLower, columnUpper, objective, rowLower, rowUpper, NULL); |
---|
[558] | 396 | CoinBigIndex * startPositive = NULL; |
---|
| 397 | CoinBigIndex * startNegative = NULL; |
---|
| 398 | delete matrix_; |
---|
| 399 | if (tryPlusMinusOne) { |
---|
| 400 | startPositive = new CoinBigIndex[numberColumns+1]; |
---|
| 401 | startNegative = new CoinBigIndex[numberColumns]; |
---|
| 402 | modelObject.countPlusMinusOne(startPositive,startNegative,associated); |
---|
| 403 | if (startPositive[0]<0) { |
---|
| 404 | // no good |
---|
| 405 | tryPlusMinusOne=false; |
---|
| 406 | delete [] startPositive; |
---|
| 407 | delete [] startNegative; |
---|
| 408 | } |
---|
| 409 | } |
---|
[650] | 410 | #ifndef SLIM_CLP |
---|
[558] | 411 | if (!tryPlusMinusOne) { |
---|
[650] | 412 | #endif |
---|
[558] | 413 | CoinPackedMatrix matrix; |
---|
| 414 | modelObject.createPackedMatrix(matrix,associated); |
---|
| 415 | matrix_ = new ClpPackedMatrix(matrix); |
---|
[650] | 416 | #ifndef SLIM_CLP |
---|
[558] | 417 | } else { |
---|
| 418 | // create +-1 matrix |
---|
| 419 | CoinBigIndex size = startPositive[numberColumns]; |
---|
| 420 | int * indices = new int[size]; |
---|
| 421 | modelObject.createPlusMinusOne(startPositive,startNegative,indices, |
---|
| 422 | associated); |
---|
| 423 | // Get good object |
---|
| 424 | ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix(); |
---|
| 425 | matrix->passInCopy(numberRows,numberColumns, |
---|
| 426 | true,indices,startPositive,startNegative); |
---|
| 427 | matrix_=matrix; |
---|
| 428 | } |
---|
[650] | 429 | #endif |
---|
[653] | 430 | #ifndef CLP_NO_STD |
---|
[546] | 431 | // Do names if wanted |
---|
[637] | 432 | int numberItems; |
---|
| 433 | numberItems = modelObject.rowNames()->numberItems(); |
---|
| 434 | if (numberItems) { |
---|
[546] | 435 | const char *const * rowNames=modelObject.rowNames()->names(); |
---|
[637] | 436 | copyRowNames(rowNames,0,numberItems); |
---|
[546] | 437 | } |
---|
[637] | 438 | numberItems = modelObject.columnNames()->numberItems(); |
---|
| 439 | if (numberItems) { |
---|
[546] | 440 | const char *const * columnNames=modelObject.columnNames()->names(); |
---|
[637] | 441 | copyColumnNames(columnNames,0,numberItems); |
---|
[546] | 442 | } |
---|
[653] | 443 | #endif |
---|
[546] | 444 | // Do integers if wanted |
---|
| 445 | assert(integerType); |
---|
| 446 | for (int iColumn=0;iColumn<numberColumns;iColumn++) { |
---|
| 447 | if (integerType[iColumn]) |
---|
| 448 | setInteger(iColumn); |
---|
| 449 | } |
---|
| 450 | if (rowLower!=modelObject.rowLowerArray()|| |
---|
| 451 | columnLower!=modelObject.columnLowerArray()) { |
---|
| 452 | delete [] rowLower; |
---|
| 453 | delete [] rowUpper; |
---|
| 454 | delete [] columnLower; |
---|
| 455 | delete [] columnUpper; |
---|
| 456 | delete [] objective; |
---|
| 457 | delete [] integerType; |
---|
[560] | 458 | delete [] associated; |
---|
| 459 | if (numberErrors) |
---|
| 460 | handler_->message(CLP_BAD_STRING_VALUES,messages_) |
---|
| 461 | <<numberErrors |
---|
| 462 | <<CoinMessageEol; |
---|
[546] | 463 | } |
---|
[558] | 464 | matrix_->setDimensions(numberRows_,numberColumns_); |
---|
[546] | 465 | return numberErrors; |
---|
| 466 | } |
---|
[651] | 467 | #endif |
---|
[50] | 468 | void |
---|
[2] | 469 | ClpModel::getRowBound(int iRow, double& lower, double& upper) const |
---|
| 470 | { |
---|
[123] | 471 | lower=-COIN_DBL_MAX; |
---|
| 472 | upper=COIN_DBL_MAX; |
---|
[2] | 473 | if (rowUpper_) |
---|
| 474 | upper=rowUpper_[iRow]; |
---|
| 475 | if (rowLower_) |
---|
| 476 | lower=rowLower_[iRow]; |
---|
| 477 | } |
---|
[470] | 478 | //------------------------------------------------------------------ |
---|
[471] | 479 | #ifndef NDEBUG |
---|
| 480 | // For errors to make sure print to screen |
---|
| 481 | // only called in debug mode |
---|
| 482 | static void indexError(int index, |
---|
| 483 | std::string methodName) |
---|
| 484 | { |
---|
| 485 | std::cerr<<"Illegal index "<<index<<" in ClpModel::"<<methodName<<std::endl; |
---|
| 486 | throw CoinError("Illegal index",methodName,"ClpModel"); |
---|
| 487 | } |
---|
| 488 | #endif |
---|
[470] | 489 | /* Set an objective function coefficient */ |
---|
| 490 | void |
---|
| 491 | ClpModel::setObjectiveCoefficient( int elementIndex, double elementValue ) |
---|
| 492 | { |
---|
| 493 | #ifndef NDEBUG |
---|
| 494 | if (elementIndex<0||elementIndex>=numberColumns_) { |
---|
| 495 | indexError(elementIndex,"setObjectiveCoefficient"); |
---|
| 496 | } |
---|
| 497 | #endif |
---|
| 498 | objective()[elementIndex] = elementValue; |
---|
[472] | 499 | whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep) |
---|
[470] | 500 | } |
---|
| 501 | /* Set a single row lower bound<br> |
---|
| 502 | Use -DBL_MAX for -infinity. */ |
---|
| 503 | void |
---|
| 504 | ClpModel::setRowLower( int elementIndex, double elementValue ) { |
---|
| 505 | if (elementValue<-1.0e27) |
---|
| 506 | elementValue=-COIN_DBL_MAX; |
---|
| 507 | rowLower_[elementIndex] = elementValue; |
---|
[472] | 508 | whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep) |
---|
[470] | 509 | } |
---|
| 510 | |
---|
| 511 | /* Set a single row upper bound<br> |
---|
| 512 | Use DBL_MAX for infinity. */ |
---|
| 513 | void |
---|
| 514 | ClpModel::setRowUpper( int elementIndex, double elementValue ) { |
---|
| 515 | if (elementValue>1.0e27) |
---|
| 516 | elementValue=COIN_DBL_MAX; |
---|
| 517 | rowUpper_[elementIndex] = elementValue; |
---|
[472] | 518 | whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep) |
---|
[470] | 519 | } |
---|
| 520 | |
---|
| 521 | /* Set a single row lower and upper bound */ |
---|
| 522 | void |
---|
| 523 | ClpModel::setRowBounds( int elementIndex, |
---|
| 524 | double lower, double upper ) { |
---|
| 525 | if (lower<-1.0e27) |
---|
| 526 | lower=-COIN_DBL_MAX; |
---|
| 527 | if (upper>1.0e27) |
---|
| 528 | upper=COIN_DBL_MAX; |
---|
[560] | 529 | CoinAssert (upper>=lower); |
---|
[470] | 530 | rowLower_[elementIndex] = lower; |
---|
| 531 | rowUpper_[elementIndex] = upper; |
---|
[472] | 532 | whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep) |
---|
[470] | 533 | } |
---|
| 534 | void ClpModel::setRowSetBounds(const int* indexFirst, |
---|
| 535 | const int* indexLast, |
---|
| 536 | const double* boundList) |
---|
| 537 | { |
---|
| 538 | #ifndef NDEBUG |
---|
| 539 | int n = numberRows_; |
---|
| 540 | #endif |
---|
| 541 | double * lower = rowLower_; |
---|
| 542 | double * upper = rowUpper_; |
---|
[472] | 543 | whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep) |
---|
[470] | 544 | while (indexFirst != indexLast) { |
---|
| 545 | const int iRow=*indexFirst++; |
---|
| 546 | #ifndef NDEBUG |
---|
| 547 | if (iRow<0||iRow>=n) { |
---|
| 548 | indexError(iRow,"setRowSetBounds"); |
---|
| 549 | } |
---|
| 550 | #endif |
---|
| 551 | lower[iRow]= *boundList++; |
---|
| 552 | upper[iRow]= *boundList++; |
---|
| 553 | if (lower[iRow]<-1.0e27) |
---|
| 554 | lower[iRow]=-COIN_DBL_MAX; |
---|
| 555 | if (upper[iRow]>1.0e27) |
---|
| 556 | upper[iRow]=COIN_DBL_MAX; |
---|
[560] | 557 | CoinAssert (upper[iRow]>=lower[iRow]); |
---|
[470] | 558 | } |
---|
| 559 | } |
---|
| 560 | //----------------------------------------------------------------------------- |
---|
| 561 | /* Set a single column lower bound<br> |
---|
| 562 | Use -DBL_MAX for -infinity. */ |
---|
| 563 | void |
---|
| 564 | ClpModel::setColumnLower( int elementIndex, double elementValue ) |
---|
| 565 | { |
---|
| 566 | #ifndef NDEBUG |
---|
| 567 | int n = numberColumns_; |
---|
| 568 | if (elementIndex<0||elementIndex>=n) { |
---|
| 569 | indexError(elementIndex,"setColumnLower"); |
---|
| 570 | } |
---|
| 571 | #endif |
---|
| 572 | if (elementValue<-1.0e27) |
---|
| 573 | elementValue=-COIN_DBL_MAX; |
---|
| 574 | columnLower_[elementIndex] = elementValue; |
---|
[472] | 575 | whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep) |
---|
[470] | 576 | } |
---|
| 577 | |
---|
| 578 | /* Set a single column upper bound<br> |
---|
| 579 | Use DBL_MAX for infinity. */ |
---|
| 580 | void |
---|
| 581 | ClpModel::setColumnUpper( int elementIndex, double elementValue ) |
---|
| 582 | { |
---|
| 583 | #ifndef NDEBUG |
---|
| 584 | int n = numberColumns_; |
---|
| 585 | if (elementIndex<0||elementIndex>=n) { |
---|
| 586 | indexError(elementIndex,"setColumnUpper"); |
---|
| 587 | } |
---|
| 588 | #endif |
---|
| 589 | if (elementValue>1.0e27) |
---|
| 590 | elementValue=COIN_DBL_MAX; |
---|
| 591 | columnUpper_[elementIndex] = elementValue; |
---|
[472] | 592 | whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep) |
---|
[470] | 593 | } |
---|
| 594 | |
---|
| 595 | /* Set a single column lower and upper bound */ |
---|
| 596 | void |
---|
| 597 | ClpModel::setColumnBounds( int elementIndex, |
---|
| 598 | double lower, double upper ) |
---|
| 599 | { |
---|
| 600 | #ifndef NDEBUG |
---|
| 601 | int n = numberColumns_; |
---|
| 602 | if (elementIndex<0||elementIndex>=n) { |
---|
| 603 | indexError(elementIndex,"setColumnBounds"); |
---|
| 604 | } |
---|
| 605 | #endif |
---|
| 606 | if (lower<-1.0e27) |
---|
| 607 | lower=-COIN_DBL_MAX; |
---|
| 608 | if (upper>1.0e27) |
---|
| 609 | upper=COIN_DBL_MAX; |
---|
| 610 | columnLower_[elementIndex] = lower; |
---|
| 611 | columnUpper_[elementIndex] = upper; |
---|
[560] | 612 | CoinAssert (upper>=lower); |
---|
[472] | 613 | whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep) |
---|
[470] | 614 | } |
---|
| 615 | void ClpModel::setColumnSetBounds(const int* indexFirst, |
---|
| 616 | const int* indexLast, |
---|
| 617 | const double* boundList) |
---|
| 618 | { |
---|
| 619 | double * lower = columnLower_; |
---|
| 620 | double * upper = columnUpper_; |
---|
[472] | 621 | whatsChanged_ = 0; // Can't be sure (use ClpSimplex to keep) |
---|
[470] | 622 | #ifndef NDEBUG |
---|
| 623 | int n = numberColumns_; |
---|
| 624 | #endif |
---|
| 625 | while (indexFirst != indexLast) { |
---|
| 626 | const int iColumn=*indexFirst++; |
---|
| 627 | #ifndef NDEBUG |
---|
| 628 | if (iColumn<0||iColumn>=n) { |
---|
| 629 | indexError(iColumn,"setColumnSetBounds"); |
---|
| 630 | } |
---|
| 631 | #endif |
---|
| 632 | lower[iColumn]= *boundList++; |
---|
| 633 | upper[iColumn]= *boundList++; |
---|
[560] | 634 | CoinAssert (upper[iColumn]>=lower[iColumn]); |
---|
[470] | 635 | if (lower[iColumn]<-1.0e27) |
---|
| 636 | lower[iColumn]=-COIN_DBL_MAX; |
---|
| 637 | if (upper[iColumn]>1.0e27) |
---|
| 638 | upper[iColumn]=COIN_DBL_MAX; |
---|
| 639 | } |
---|
| 640 | } |
---|
| 641 | //----------------------------------------------------------------------------- |
---|
[2] | 642 | //############################################################################# |
---|
| 643 | // Copy constructor. |
---|
[393] | 644 | ClpModel::ClpModel(const ClpModel &rhs, int scalingMode) : |
---|
[2] | 645 | optimizationDirection_(rhs.optimizationDirection_), |
---|
| 646 | numberRows_(rhs.numberRows_), |
---|
[1147] | 647 | numberColumns_(rhs.numberColumns_), |
---|
| 648 | specialOptions_(rhs.specialOptions_), |
---|
| 649 | maximumColumns_(-1), |
---|
| 650 | maximumRows_(-1), |
---|
[1197] | 651 | maximumInternalColumns_(-1), |
---|
| 652 | maximumInternalRows_(-1), |
---|
[1147] | 653 | savedRowScale_(NULL), |
---|
| 654 | savedColumnScale_(NULL) |
---|
[2] | 655 | { |
---|
| 656 | gutsOfCopy(rhs); |
---|
[393] | 657 | if (scalingMode>=0&&matrix_&& |
---|
| 658 | matrix_->allElementsInRange(this,smallElement_,1.0e20)) { |
---|
| 659 | // really do scaling |
---|
| 660 | scalingFlag_=scalingMode; |
---|
[1147] | 661 | setRowScale(NULL); |
---|
| 662 | setColumnScale(NULL); |
---|
[634] | 663 | delete rowCopy_; // in case odd |
---|
| 664 | rowCopy_=NULL; |
---|
[1150] | 665 | delete scaledMatrix_; |
---|
| 666 | scaledMatrix_=NULL; |
---|
[634] | 667 | if (scalingMode&&!matrix_->scale(this)) { |
---|
[393] | 668 | // scaling worked - now apply |
---|
| 669 | gutsOfScaling(); |
---|
| 670 | // pretend not scaled |
---|
| 671 | scalingFlag_ = -scalingFlag_; |
---|
| 672 | } else { |
---|
| 673 | // not scaled |
---|
| 674 | scalingFlag_=0; |
---|
| 675 | } |
---|
| 676 | } |
---|
[1141] | 677 | randomNumberGenerator_.setSeed(1234567); |
---|
[2] | 678 | } |
---|
| 679 | // Assignment operator. This copies the data |
---|
| 680 | ClpModel & |
---|
| 681 | ClpModel::operator=(const ClpModel & rhs) |
---|
| 682 | { |
---|
| 683 | if (this != &rhs) { |
---|
| 684 | if (defaultHandler_) { |
---|
[1147] | 685 | //delete handler_; |
---|
| 686 | //handler_ = NULL; |
---|
[2] | 687 | } |
---|
[1147] | 688 | gutsOfDelete(1); |
---|
[2] | 689 | optimizationDirection_ = rhs.optimizationDirection_; |
---|
| 690 | numberRows_ = rhs.numberRows_; |
---|
| 691 | numberColumns_ = rhs.numberColumns_; |
---|
[1147] | 692 | gutsOfCopy(rhs,-1); |
---|
[2] | 693 | } |
---|
| 694 | return *this; |
---|
| 695 | } |
---|
[1147] | 696 | /* Does most of copying |
---|
| 697 | If trueCopy 0 then just points to arrays |
---|
| 698 | If -1 leaves as much as possible */ |
---|
[2] | 699 | void |
---|
[1147] | 700 | ClpModel::gutsOfCopy(const ClpModel & rhs, int trueCopy) |
---|
[2] | 701 | { |
---|
| 702 | defaultHandler_ = rhs.defaultHandler_; |
---|
[1147] | 703 | if (trueCopy>=0) { |
---|
| 704 | if (defaultHandler_) |
---|
| 705 | handler_ = new CoinMessageHandler(*rhs.handler_); |
---|
| 706 | else |
---|
| 707 | handler_ = rhs.handler_; |
---|
| 708 | eventHandler_ = rhs.eventHandler_->clone(); |
---|
| 709 | randomNumberGenerator_ = rhs.randomNumberGenerator_; |
---|
| 710 | messages_ = rhs.messages_; |
---|
| 711 | coinMessages_ = rhs.coinMessages_; |
---|
| 712 | } else { |
---|
| 713 | if (!eventHandler_&&rhs.eventHandler_) |
---|
| 714 | eventHandler_ = rhs.eventHandler_->clone(); |
---|
| 715 | } |
---|
[50] | 716 | intParam_[ClpMaxNumIteration] = rhs.intParam_[ClpMaxNumIteration]; |
---|
| 717 | intParam_[ClpMaxNumIterationHotStart] = |
---|
| 718 | rhs.intParam_[ClpMaxNumIterationHotStart]; |
---|
[1015] | 719 | intParam_[ClpNameDiscipline] = rhs.intParam_[ClpNameDiscipline] ; |
---|
[2] | 720 | |
---|
[50] | 721 | dblParam_[ClpDualObjectiveLimit] = rhs.dblParam_[ClpDualObjectiveLimit]; |
---|
| 722 | dblParam_[ClpPrimalObjectiveLimit] = rhs.dblParam_[ClpPrimalObjectiveLimit]; |
---|
| 723 | dblParam_[ClpDualTolerance] = rhs.dblParam_[ClpDualTolerance]; |
---|
| 724 | dblParam_[ClpPrimalTolerance] = rhs.dblParam_[ClpPrimalTolerance]; |
---|
| 725 | dblParam_[ClpObjOffset] = rhs.dblParam_[ClpObjOffset]; |
---|
[142] | 726 | dblParam_[ClpMaxSeconds] = rhs.dblParam_[ClpMaxSeconds]; |
---|
[708] | 727 | dblParam_[ClpPresolveTolerance] = rhs.dblParam_[ClpPresolveTolerance]; |
---|
[653] | 728 | #ifndef CLP_NO_STD |
---|
[2] | 729 | |
---|
[50] | 730 | strParam_[ClpProbName] = rhs.strParam_[ClpProbName]; |
---|
[653] | 731 | #endif |
---|
[2] | 732 | |
---|
[225] | 733 | optimizationDirection_ = rhs.optimizationDirection_; |
---|
[2] | 734 | objectiveValue_=rhs.objectiveValue_; |
---|
[112] | 735 | smallElement_ = rhs.smallElement_; |
---|
[389] | 736 | objectiveScale_ = rhs.objectiveScale_; |
---|
| 737 | rhsScale_ = rhs.rhsScale_; |
---|
[2] | 738 | numberIterations_ = rhs.numberIterations_; |
---|
[109] | 739 | solveType_ = rhs.solveType_; |
---|
[472] | 740 | whatsChanged_ = rhs.whatsChanged_; |
---|
[2] | 741 | problemStatus_ = rhs.problemStatus_; |
---|
[225] | 742 | secondaryStatus_ = rhs.secondaryStatus_; |
---|
| 743 | numberRows_ = rhs.numberRows_; |
---|
| 744 | numberColumns_ = rhs.numberColumns_; |
---|
[240] | 745 | userPointer_ = rhs.userPointer_; |
---|
[372] | 746 | scalingFlag_ = rhs.scalingFlag_; |
---|
[1034] | 747 | specialOptions_ = rhs.specialOptions_; |
---|
[2] | 748 | if (trueCopy) { |
---|
[653] | 749 | #ifndef CLP_NO_STD |
---|
[2] | 750 | lengthNames_ = rhs.lengthNames_; |
---|
[589] | 751 | if (lengthNames_) { |
---|
| 752 | rowNames_ = rhs.rowNames_; |
---|
| 753 | columnNames_ = rhs.columnNames_; |
---|
| 754 | } |
---|
[653] | 755 | #endif |
---|
[740] | 756 | numberThreads_ = rhs.numberThreads_; |
---|
[1147] | 757 | if (maximumRows_<0) { |
---|
| 758 | specialOptions_ &= ~65536; |
---|
| 759 | savedRowScale_ = NULL; |
---|
| 760 | savedColumnScale_ = NULL; |
---|
| 761 | integerType_ = CoinCopyOfArray(rhs.integerType_,numberColumns_); |
---|
| 762 | if (rhs.rowActivity_) { |
---|
| 763 | rowActivity_=new double[numberRows_]; |
---|
| 764 | columnActivity_=new double[numberColumns_]; |
---|
| 765 | dual_=new double[numberRows_]; |
---|
| 766 | reducedCost_=new double[numberColumns_]; |
---|
| 767 | ClpDisjointCopyN ( rhs.rowActivity_, numberRows_ , |
---|
| 768 | rowActivity_); |
---|
| 769 | ClpDisjointCopyN ( rhs.columnActivity_, numberColumns_ , |
---|
| 770 | columnActivity_); |
---|
| 771 | ClpDisjointCopyN ( rhs.dual_, numberRows_ , |
---|
| 772 | dual_); |
---|
| 773 | ClpDisjointCopyN ( rhs.reducedCost_, numberColumns_ , |
---|
| 774 | reducedCost_); |
---|
| 775 | } else { |
---|
| 776 | rowActivity_=NULL; |
---|
| 777 | columnActivity_=NULL; |
---|
| 778 | dual_=NULL; |
---|
| 779 | reducedCost_=NULL; |
---|
| 780 | } |
---|
| 781 | rowLower_ = ClpCopyOfArray ( rhs.rowLower_, numberRows_ ); |
---|
| 782 | rowUpper_ = ClpCopyOfArray ( rhs.rowUpper_, numberRows_ ); |
---|
| 783 | columnLower_ = ClpCopyOfArray ( rhs.columnLower_, numberColumns_ ); |
---|
| 784 | int scaleLength = ((specialOptions_&131072)==0) ? 1 : 2; |
---|
| 785 | columnUpper_ = ClpCopyOfArray ( rhs.columnUpper_, numberColumns_ ); |
---|
| 786 | rowScale_ = ClpCopyOfArray(rhs.rowScale_,numberRows_*scaleLength); |
---|
| 787 | columnScale_ = ClpCopyOfArray(rhs.columnScale_,numberColumns_*scaleLength); |
---|
| 788 | if (rhs.objective_) |
---|
| 789 | objective_ = rhs.objective_->clone(); |
---|
| 790 | else |
---|
| 791 | objective_ = NULL; |
---|
| 792 | rowObjective_ = ClpCopyOfArray ( rhs.rowObjective_, numberRows_ ); |
---|
| 793 | status_ = ClpCopyOfArray( rhs.status_,numberColumns_+numberRows_); |
---|
| 794 | ray_ = NULL; |
---|
| 795 | if (problemStatus_==1&&!secondaryStatus_) |
---|
| 796 | ray_ = ClpCopyOfArray (rhs.ray_,numberRows_); |
---|
| 797 | else if (problemStatus_==2) |
---|
| 798 | ray_ = ClpCopyOfArray (rhs.ray_,numberColumns_); |
---|
| 799 | if (rhs.rowCopy_) { |
---|
| 800 | rowCopy_ = rhs.rowCopy_->clone(); |
---|
| 801 | } else { |
---|
| 802 | rowCopy_=NULL; |
---|
| 803 | } |
---|
[1150] | 804 | if (rhs.scaledMatrix_) { |
---|
| 805 | scaledMatrix_ = new ClpPackedMatrix(*rhs.scaledMatrix_); |
---|
| 806 | } else { |
---|
| 807 | scaledMatrix_=NULL; |
---|
| 808 | } |
---|
[1147] | 809 | matrix_=NULL; |
---|
| 810 | if (rhs.matrix_) { |
---|
| 811 | matrix_ = rhs.matrix_->clone(); |
---|
| 812 | } |
---|
[2] | 813 | } else { |
---|
[1147] | 814 | // This already has arrays - just copy |
---|
[1197] | 815 | savedRowScale_ = NULL; |
---|
| 816 | savedColumnScale_ = NULL; |
---|
[1147] | 817 | startPermanentArrays(); |
---|
| 818 | if (rhs.integerType_) { |
---|
| 819 | assert (integerType_); |
---|
| 820 | ClpDisjointCopyN(rhs.integerType_,numberColumns_,integerType_); |
---|
| 821 | } else { |
---|
| 822 | integerType_ = NULL; |
---|
| 823 | } |
---|
| 824 | if (rhs.rowActivity_) { |
---|
| 825 | ClpDisjointCopyN ( rhs.rowActivity_, numberRows_ , |
---|
| 826 | rowActivity_); |
---|
| 827 | ClpDisjointCopyN ( rhs.columnActivity_, numberColumns_ , |
---|
| 828 | columnActivity_); |
---|
| 829 | ClpDisjointCopyN ( rhs.dual_, numberRows_ , |
---|
| 830 | dual_); |
---|
| 831 | ClpDisjointCopyN ( rhs.reducedCost_, numberColumns_ , |
---|
| 832 | reducedCost_); |
---|
| 833 | } else { |
---|
| 834 | rowActivity_=NULL; |
---|
| 835 | columnActivity_=NULL; |
---|
| 836 | dual_=NULL; |
---|
| 837 | reducedCost_=NULL; |
---|
| 838 | } |
---|
| 839 | ClpDisjointCopyN ( rhs.rowLower_, numberRows_,rowLower_ ); |
---|
| 840 | ClpDisjointCopyN ( rhs.rowUpper_, numberRows_,rowUpper_ ); |
---|
| 841 | ClpDisjointCopyN ( rhs.columnLower_, numberColumns_,columnLower_ ); |
---|
| 842 | assert ((specialOptions_&131072)==0); |
---|
| 843 | ClpDisjointCopyN ( rhs.columnUpper_, numberColumns_,columnUpper_ ); |
---|
| 844 | if (rhs.objective_) { |
---|
| 845 | abort(); //check if same |
---|
| 846 | objective_ = rhs.objective_->clone(); |
---|
| 847 | } else { |
---|
| 848 | objective_ = NULL; |
---|
| 849 | } |
---|
| 850 | assert (!rhs.rowObjective_); |
---|
| 851 | ClpDisjointCopyN( rhs.status_,numberColumns_+numberRows_,status_); |
---|
| 852 | ray_ = NULL; |
---|
| 853 | if (problemStatus_==1&&!secondaryStatus_) |
---|
| 854 | ray_ = ClpCopyOfArray (rhs.ray_,numberRows_); |
---|
| 855 | else if (problemStatus_==2) |
---|
| 856 | ray_ = ClpCopyOfArray (rhs.ray_,numberColumns_); |
---|
| 857 | assert (!ray_); |
---|
| 858 | delete rowCopy_; |
---|
| 859 | if (rhs.rowCopy_) { |
---|
| 860 | rowCopy_ = rhs.rowCopy_->clone(); |
---|
| 861 | } else { |
---|
| 862 | rowCopy_=NULL; |
---|
| 863 | } |
---|
[1150] | 864 | delete scaledMatrix_; |
---|
| 865 | if (rhs.scaledMatrix_) { |
---|
| 866 | scaledMatrix_ = new ClpPackedMatrix(*rhs.scaledMatrix_); |
---|
| 867 | } else { |
---|
| 868 | scaledMatrix_=NULL; |
---|
| 869 | } |
---|
[1147] | 870 | delete matrix_; |
---|
| 871 | matrix_=NULL; |
---|
| 872 | if (rhs.matrix_) { |
---|
| 873 | matrix_ = rhs.matrix_->clone(); |
---|
| 874 | } |
---|
| 875 | if (rhs.savedRowScale_) { |
---|
| 876 | assert (savedRowScale_); |
---|
| 877 | assert (!rowScale_); |
---|
[1197] | 878 | ClpDisjointCopyN(rhs.savedRowScale_,4*maximumInternalRows_,savedRowScale_); |
---|
| 879 | ClpDisjointCopyN(rhs.savedColumnScale_,4*maximumInternalColumns_,savedColumnScale_); |
---|
[1147] | 880 | } else { |
---|
| 881 | assert (!savedRowScale_); |
---|
| 882 | if (rowScale_) { |
---|
| 883 | ClpDisjointCopyN(rhs.rowScale_,numberRows_,rowScale_); |
---|
| 884 | ClpDisjointCopyN(rhs.columnScale_,numberColumns_,columnScale_); |
---|
| 885 | } else { |
---|
| 886 | rowScale_ =NULL; |
---|
| 887 | columnScale_=NULL; |
---|
| 888 | } |
---|
| 889 | } |
---|
| 890 | abort(); // look at resizeDouble and resize |
---|
[2] | 891 | } |
---|
| 892 | } else { |
---|
[1147] | 893 | savedRowScale_ = rhs.savedRowScale_; |
---|
[1197] | 894 | assert (!savedRowScale_); |
---|
[1147] | 895 | savedColumnScale_ = rhs.savedColumnScale_; |
---|
[2] | 896 | rowActivity_ = rhs.rowActivity_; |
---|
| 897 | columnActivity_ = rhs.columnActivity_; |
---|
| 898 | dual_ = rhs.dual_; |
---|
| 899 | reducedCost_ = rhs.reducedCost_; |
---|
| 900 | rowLower_ = rhs.rowLower_; |
---|
| 901 | rowUpper_ = rhs.rowUpper_; |
---|
| 902 | objective_ = rhs.objective_; |
---|
| 903 | rowObjective_ = rhs.rowObjective_; |
---|
| 904 | columnLower_ = rhs.columnLower_; |
---|
| 905 | columnUpper_ = rhs.columnUpper_; |
---|
| 906 | matrix_ = rhs.matrix_; |
---|
[164] | 907 | rowCopy_ = NULL; |
---|
[1150] | 908 | scaledMatrix_ = NULL; |
---|
[2] | 909 | ray_ = rhs.ray_; |
---|
[393] | 910 | //rowScale_ = rhs.rowScale_; |
---|
| 911 | //columnScale_ = rhs.columnScale_; |
---|
[2] | 912 | lengthNames_ = 0; |
---|
[740] | 913 | numberThreads_ = rhs.numberThreads_; |
---|
[653] | 914 | #ifndef CLP_NO_STD |
---|
[2] | 915 | rowNames_ = std::vector<std::string> (); |
---|
| 916 | columnNames_ = std::vector<std::string> (); |
---|
[653] | 917 | #endif |
---|
[50] | 918 | integerType_ = NULL; |
---|
| 919 | status_ = rhs.status_; |
---|
[2] | 920 | } |
---|
[1197] | 921 | inverseRowScale_ = NULL; |
---|
| 922 | inverseColumnScale_ = NULL; |
---|
[2] | 923 | } |
---|
[1147] | 924 | // Copy contents - resizing if necessary - otherwise re-use memory |
---|
| 925 | void |
---|
| 926 | ClpModel::copy(const ClpMatrixBase * from, ClpMatrixBase * & to) |
---|
| 927 | { |
---|
| 928 | assert (from); |
---|
| 929 | const ClpPackedMatrix * matrixFrom = (dynamic_cast<const ClpPackedMatrix*>(from)); |
---|
| 930 | ClpPackedMatrix * matrixTo = (dynamic_cast< ClpPackedMatrix*>(to)); |
---|
| 931 | if (matrixFrom&&matrixTo) { |
---|
| 932 | matrixTo->copy(matrixFrom); |
---|
| 933 | } else { |
---|
| 934 | delete to; |
---|
| 935 | to = from->clone(); |
---|
| 936 | } |
---|
| 937 | #if 0 |
---|
[1197] | 938 | delete modelPtr_->matrix_; |
---|
| 939 | if (continuousModel_->matrix_) { |
---|
| 940 | modelPtr_->matrix_ = continuousModel_->matrix_->clone(); |
---|
| 941 | } else { |
---|
| 942 | modelPtr_->matrix_=NULL; |
---|
| 943 | } |
---|
[1147] | 944 | #endif |
---|
| 945 | } |
---|
[2] | 946 | /* Borrow model. This is so we dont have to copy large amounts |
---|
| 947 | of data around. It assumes a derived class wants to overwrite |
---|
| 948 | an empty model with a real one - while it does an algorithm */ |
---|
| 949 | void |
---|
| 950 | ClpModel::borrowModel(ClpModel & rhs) |
---|
| 951 | { |
---|
| 952 | if (defaultHandler_) { |
---|
| 953 | delete handler_; |
---|
| 954 | handler_ = NULL; |
---|
| 955 | } |
---|
[1147] | 956 | gutsOfDelete(1); |
---|
[2] | 957 | optimizationDirection_ = rhs.optimizationDirection_; |
---|
| 958 | numberRows_ = rhs.numberRows_; |
---|
| 959 | numberColumns_ = rhs.numberColumns_; |
---|
[50] | 960 | delete [] rhs.ray_; |
---|
| 961 | rhs.ray_=NULL; |
---|
[1150] | 962 | // make sure scaled matrix not copied |
---|
| 963 | ClpPackedMatrix * save = rhs.scaledMatrix_; |
---|
| 964 | rhs.scaledMatrix_ = NULL; |
---|
| 965 | delete scaledMatrix_; |
---|
| 966 | scaledMatrix_=NULL; |
---|
[1147] | 967 | gutsOfCopy(rhs,0); |
---|
[1150] | 968 | rhs.scaledMatrix_ = save; |
---|
[1147] | 969 | specialOptions_ = rhs.specialOptions_ & ~65536; |
---|
| 970 | savedRowScale_=NULL; |
---|
| 971 | savedColumnScale_=NULL; |
---|
[1197] | 972 | inverseRowScale_ = NULL; |
---|
| 973 | inverseColumnScale_ = NULL; |
---|
[2] | 974 | } |
---|
| 975 | // Return model - nulls all arrays so can be deleted safely |
---|
| 976 | void |
---|
| 977 | ClpModel::returnModel(ClpModel & otherModel) |
---|
| 978 | { |
---|
| 979 | otherModel.objectiveValue_=objectiveValue_; |
---|
| 980 | otherModel.numberIterations_ = numberIterations_; |
---|
| 981 | otherModel.problemStatus_ = problemStatus_; |
---|
[225] | 982 | otherModel.secondaryStatus_ = secondaryStatus_; |
---|
[2] | 983 | rowActivity_ = NULL; |
---|
| 984 | columnActivity_ = NULL; |
---|
| 985 | dual_ = NULL; |
---|
| 986 | reducedCost_ = NULL; |
---|
| 987 | rowLower_ = NULL; |
---|
| 988 | rowUpper_ = NULL; |
---|
| 989 | objective_ = NULL; |
---|
| 990 | rowObjective_ = NULL; |
---|
| 991 | columnLower_ = NULL; |
---|
| 992 | columnUpper_ = NULL; |
---|
| 993 | matrix_ = NULL; |
---|
| 994 | rowCopy_ = NULL; |
---|
[1150] | 995 | delete scaledMatrix_; |
---|
| 996 | scaledMatrix_ = NULL; |
---|
[50] | 997 | delete [] otherModel.ray_; |
---|
| 998 | otherModel.ray_ = ray_; |
---|
[2] | 999 | ray_ = NULL; |
---|
[1152] | 1000 | if (rowScale_&&otherModel.rowScale_!=rowScale_) { |
---|
| 1001 | delete [] rowScale_; |
---|
| 1002 | delete [] columnScale_; |
---|
| 1003 | } |
---|
[1147] | 1004 | rowScale_ = NULL; |
---|
| 1005 | columnScale_ = NULL; |
---|
[393] | 1006 | //rowScale_=NULL; |
---|
| 1007 | //columnScale_=NULL; |
---|
[50] | 1008 | // do status |
---|
| 1009 | if (otherModel.status_!=status_) { |
---|
| 1010 | delete [] otherModel.status_; |
---|
| 1011 | otherModel.status_ = status_; |
---|
| 1012 | } |
---|
| 1013 | status_ = NULL; |
---|
[72] | 1014 | if (defaultHandler_) { |
---|
| 1015 | delete handler_; |
---|
| 1016 | handler_ = NULL; |
---|
| 1017 | } |
---|
[1197] | 1018 | inverseRowScale_ = NULL; |
---|
| 1019 | inverseColumnScale_ = NULL; |
---|
[2] | 1020 | } |
---|
| 1021 | //############################################################################# |
---|
| 1022 | // Parameter related methods |
---|
| 1023 | //############################################################################# |
---|
| 1024 | |
---|
| 1025 | bool |
---|
[50] | 1026 | ClpModel::setIntParam(ClpIntParam key, int value) |
---|
[2] | 1027 | { |
---|
| 1028 | switch (key) { |
---|
[50] | 1029 | case ClpMaxNumIteration: |
---|
[2] | 1030 | if (value < 0) |
---|
| 1031 | return false; |
---|
| 1032 | break; |
---|
[50] | 1033 | case ClpMaxNumIterationHotStart: |
---|
[2] | 1034 | if (value < 0) |
---|
| 1035 | return false; |
---|
| 1036 | break; |
---|
[1015] | 1037 | case ClpNameDiscipline: |
---|
| 1038 | if (value < 0) |
---|
| 1039 | return false; |
---|
| 1040 | break; |
---|
[1034] | 1041 | default: |
---|
[2] | 1042 | return false; |
---|
| 1043 | } |
---|
| 1044 | intParam_[key] = value; |
---|
| 1045 | return true; |
---|
| 1046 | } |
---|
| 1047 | |
---|
| 1048 | //----------------------------------------------------------------------------- |
---|
| 1049 | |
---|
| 1050 | bool |
---|
[50] | 1051 | ClpModel::setDblParam(ClpDblParam key, double value) |
---|
[2] | 1052 | { |
---|
| 1053 | |
---|
| 1054 | switch (key) { |
---|
[50] | 1055 | case ClpDualObjectiveLimit: |
---|
[2] | 1056 | break; |
---|
| 1057 | |
---|
[50] | 1058 | case ClpPrimalObjectiveLimit: |
---|
[2] | 1059 | break; |
---|
| 1060 | |
---|
[50] | 1061 | case ClpDualTolerance: |
---|
[2] | 1062 | if (value<=0.0||value>1.0e10) |
---|
| 1063 | return false; |
---|
| 1064 | break; |
---|
| 1065 | |
---|
[50] | 1066 | case ClpPrimalTolerance: |
---|
[2] | 1067 | if (value<=0.0||value>1.0e10) |
---|
| 1068 | return false; |
---|
| 1069 | break; |
---|
| 1070 | |
---|
[50] | 1071 | case ClpObjOffset: |
---|
[2] | 1072 | break; |
---|
| 1073 | |
---|
[142] | 1074 | case ClpMaxSeconds: |
---|
| 1075 | if(value>=0) |
---|
[225] | 1076 | value += CoinCpuTime(); |
---|
[142] | 1077 | else |
---|
| 1078 | value = -1.0; |
---|
| 1079 | break; |
---|
| 1080 | |
---|
[708] | 1081 | case ClpPresolveTolerance: |
---|
| 1082 | if (value<=0.0||value>1.0e10) |
---|
| 1083 | return false; |
---|
| 1084 | break; |
---|
| 1085 | |
---|
[1034] | 1086 | default: |
---|
[2] | 1087 | return false; |
---|
| 1088 | } |
---|
| 1089 | dblParam_[key] = value; |
---|
| 1090 | return true; |
---|
| 1091 | } |
---|
| 1092 | |
---|
| 1093 | //----------------------------------------------------------------------------- |
---|
[653] | 1094 | #ifndef CLP_NO_STD |
---|
[2] | 1095 | |
---|
| 1096 | bool |
---|
[50] | 1097 | ClpModel::setStrParam(ClpStrParam key, const std::string & value) |
---|
[2] | 1098 | { |
---|
| 1099 | |
---|
| 1100 | switch (key) { |
---|
[50] | 1101 | case ClpProbName: |
---|
[2] | 1102 | break; |
---|
| 1103 | |
---|
[1034] | 1104 | default: |
---|
[2] | 1105 | return false; |
---|
| 1106 | } |
---|
| 1107 | strParam_[key] = value; |
---|
| 1108 | return true; |
---|
| 1109 | } |
---|
[653] | 1110 | #endif |
---|
[2] | 1111 | // Useful routines |
---|
| 1112 | // Returns resized array and deletes incoming |
---|
[77] | 1113 | double * resizeDouble(double * array , int size, int newSize, double fill, |
---|
| 1114 | bool createArray) |
---|
[2] | 1115 | { |
---|
[1147] | 1116 | if ((array||createArray)&&size<newSize) { |
---|
[2] | 1117 | int i; |
---|
| 1118 | double * newArray = new double[newSize]; |
---|
[77] | 1119 | if (array) |
---|
[706] | 1120 | CoinMemcpyN(array,CoinMin(newSize,size),newArray); |
---|
[2] | 1121 | delete [] array; |
---|
| 1122 | array = newArray; |
---|
| 1123 | for (i=size;i<newSize;i++) |
---|
| 1124 | array[i]=fill; |
---|
| 1125 | } |
---|
| 1126 | return array; |
---|
| 1127 | } |
---|
| 1128 | // Returns resized array and updates size |
---|
| 1129 | double * deleteDouble(double * array , int size, |
---|
| 1130 | int number, const int * which,int & newSize) |
---|
| 1131 | { |
---|
| 1132 | if (array) { |
---|
| 1133 | int i ; |
---|
| 1134 | char * deleted = new char[size]; |
---|
| 1135 | int numberDeleted=0; |
---|
[706] | 1136 | CoinZeroN(deleted,size); |
---|
[2] | 1137 | for (i=0;i<number;i++) { |
---|
| 1138 | int j = which[i]; |
---|
| 1139 | if (j>=0&&j<size&&!deleted[j]) { |
---|
| 1140 | numberDeleted++; |
---|
| 1141 | deleted[j]=1; |
---|
| 1142 | } |
---|
| 1143 | } |
---|
| 1144 | newSize = size-numberDeleted; |
---|
| 1145 | double * newArray = new double[newSize]; |
---|
| 1146 | int put=0; |
---|
| 1147 | for (i=0;i<size;i++) { |
---|
| 1148 | if (!deleted[i]) { |
---|
| 1149 | newArray[put++]=array[i]; |
---|
| 1150 | } |
---|
| 1151 | } |
---|
| 1152 | delete [] array; |
---|
| 1153 | array = newArray; |
---|
| 1154 | delete [] deleted; |
---|
| 1155 | } |
---|
| 1156 | return array; |
---|
| 1157 | } |
---|
[50] | 1158 | char * deleteChar(char * array , int size, |
---|
| 1159 | int number, const int * which,int & newSize, |
---|
| 1160 | bool ifDelete) |
---|
| 1161 | { |
---|
| 1162 | if (array) { |
---|
| 1163 | int i ; |
---|
| 1164 | char * deleted = new char[size]; |
---|
| 1165 | int numberDeleted=0; |
---|
[706] | 1166 | CoinZeroN(deleted,size); |
---|
[50] | 1167 | for (i=0;i<number;i++) { |
---|
| 1168 | int j = which[i]; |
---|
| 1169 | if (j>=0&&j<size&&!deleted[j]) { |
---|
| 1170 | numberDeleted++; |
---|
| 1171 | deleted[j]=1; |
---|
| 1172 | } |
---|
| 1173 | } |
---|
| 1174 | newSize = size-numberDeleted; |
---|
| 1175 | char * newArray = new char[newSize]; |
---|
| 1176 | int put=0; |
---|
| 1177 | for (i=0;i<size;i++) { |
---|
| 1178 | if (!deleted[i]) { |
---|
| 1179 | newArray[put++]=array[i]; |
---|
| 1180 | } |
---|
| 1181 | } |
---|
| 1182 | if (ifDelete) |
---|
| 1183 | delete [] array; |
---|
| 1184 | array = newArray; |
---|
| 1185 | delete [] deleted; |
---|
| 1186 | } |
---|
| 1187 | return array; |
---|
| 1188 | } |
---|
[77] | 1189 | // Create empty ClpPackedMatrix |
---|
| 1190 | void |
---|
| 1191 | ClpModel::createEmptyMatrix() |
---|
| 1192 | { |
---|
| 1193 | delete matrix_; |
---|
[472] | 1194 | whatsChanged_ = 0; |
---|
[77] | 1195 | CoinPackedMatrix matrix2; |
---|
| 1196 | matrix_=new ClpPackedMatrix(matrix2); |
---|
| 1197 | } |
---|
[1034] | 1198 | /* Really clean up matrix. |
---|
| 1199 | a) eliminate all duplicate AND small elements in matrix |
---|
| 1200 | b) remove all gaps and set extraGap_ and extraMajor_ to 0.0 |
---|
| 1201 | c) reallocate arrays and make max lengths equal to lengths |
---|
| 1202 | d) orders elements |
---|
| 1203 | returns number of elements eliminated or -1 if not ClpMatrix |
---|
| 1204 | */ |
---|
| 1205 | int |
---|
| 1206 | ClpModel::cleanMatrix(double threshold) |
---|
| 1207 | { |
---|
| 1208 | ClpPackedMatrix * matrix = (dynamic_cast< ClpPackedMatrix*>(matrix_)); |
---|
| 1209 | if (matrix) { |
---|
| 1210 | return matrix->getPackedMatrix()->cleanMatrix(threshold); |
---|
| 1211 | } else { |
---|
| 1212 | return -1; |
---|
| 1213 | } |
---|
| 1214 | } |
---|
[2] | 1215 | // Resizes |
---|
| 1216 | void |
---|
| 1217 | ClpModel::resize (int newNumberRows, int newNumberColumns) |
---|
| 1218 | { |
---|
[472] | 1219 | if (newNumberRows==numberRows_&& |
---|
| 1220 | newNumberColumns==numberColumns_) |
---|
| 1221 | return; // nothing to do |
---|
| 1222 | whatsChanged_ = 0; |
---|
[1197] | 1223 | int numberRows2=newNumberRows; |
---|
| 1224 | int numberColumns2=newNumberColumns; |
---|
| 1225 | if (numberRows2<maximumRows_) |
---|
| 1226 | numberRows2=maximumRows_; |
---|
| 1227 | if (numberColumns2<maximumColumns_) |
---|
| 1228 | numberColumns2=maximumColumns_; |
---|
| 1229 | if (numberRows2>maximumRows_) { |
---|
| 1230 | rowActivity_ = resizeDouble(rowActivity_,numberRows_, |
---|
| 1231 | newNumberRows,0.0,true); |
---|
| 1232 | dual_ = resizeDouble(dual_,numberRows_, |
---|
| 1233 | newNumberRows,0.0,true); |
---|
| 1234 | rowObjective_ = resizeDouble(rowObjective_,numberRows_, |
---|
| 1235 | newNumberRows,0.0,false); |
---|
| 1236 | rowLower_ = resizeDouble(rowLower_,numberRows_, |
---|
| 1237 | newNumberRows,-COIN_DBL_MAX,true); |
---|
| 1238 | rowUpper_ = resizeDouble(rowUpper_,numberRows_, |
---|
| 1239 | newNumberRows,COIN_DBL_MAX,true); |
---|
| 1240 | } |
---|
| 1241 | if (numberColumns2>maximumColumns_) { |
---|
| 1242 | columnActivity_ = resizeDouble(columnActivity_,numberColumns_, |
---|
| 1243 | newNumberColumns,0.0,true); |
---|
| 1244 | reducedCost_ = resizeDouble(reducedCost_,numberColumns_, |
---|
| 1245 | newNumberColumns,0.0,true); |
---|
| 1246 | } |
---|
| 1247 | if (savedRowScale_&&numberRows2>maximumInternalRows_) { |
---|
| 1248 | double * temp; |
---|
| 1249 | temp = new double [4*newNumberRows]; |
---|
| 1250 | CoinFillN(temp,4*newNumberRows,1.0); |
---|
| 1251 | CoinMemcpyN(savedRowScale_,numberRows_,temp); |
---|
| 1252 | CoinMemcpyN(savedRowScale_+maximumInternalRows_,numberRows_,temp+newNumberRows); |
---|
| 1253 | CoinMemcpyN(savedRowScale_+2*maximumInternalRows_,numberRows_,temp+2*newNumberRows); |
---|
| 1254 | CoinMemcpyN(savedRowScale_+3*maximumInternalRows_,numberRows_,temp+3*newNumberRows); |
---|
| 1255 | delete [] savedRowScale_; |
---|
| 1256 | savedRowScale_ = temp; |
---|
| 1257 | } |
---|
| 1258 | if (savedColumnScale_&&numberColumns2>maximumInternalColumns_) { |
---|
| 1259 | double * temp; |
---|
| 1260 | temp = new double [4*newNumberColumns]; |
---|
| 1261 | CoinFillN(temp,4*newNumberColumns,1.0); |
---|
| 1262 | CoinMemcpyN(savedColumnScale_,numberColumns_,temp); |
---|
| 1263 | CoinMemcpyN(savedColumnScale_+maximumInternalColumns_,numberColumns_,temp+newNumberColumns); |
---|
| 1264 | CoinMemcpyN(savedColumnScale_+2*maximumInternalColumns_,numberColumns_,temp+2*newNumberColumns); |
---|
| 1265 | CoinMemcpyN(savedColumnScale_+3*maximumInternalColumns_,numberColumns_,temp+3*newNumberColumns); |
---|
| 1266 | delete [] savedColumnScale_; |
---|
| 1267 | savedColumnScale_ = temp; |
---|
| 1268 | } |
---|
| 1269 | if (objective_&&numberColumns2>maximumColumns_) |
---|
[123] | 1270 | objective_->resize(newNumberColumns); |
---|
[1197] | 1271 | else if (!objective_) |
---|
[123] | 1272 | objective_ = new ClpLinearObjective(NULL,newNumberColumns); |
---|
[1197] | 1273 | if (numberColumns2>maximumColumns_) { |
---|
| 1274 | columnLower_ = resizeDouble(columnLower_,numberColumns_, |
---|
| 1275 | newNumberColumns,0.0,true); |
---|
| 1276 | columnUpper_ = resizeDouble(columnUpper_,numberColumns_, |
---|
| 1277 | newNumberColumns,COIN_DBL_MAX,true); |
---|
| 1278 | } |
---|
[2] | 1279 | if (newNumberRows<numberRows_) { |
---|
| 1280 | int * which = new int[numberRows_-newNumberRows]; |
---|
| 1281 | int i; |
---|
| 1282 | for (i=newNumberRows;i<numberRows_;i++) |
---|
| 1283 | which[i-newNumberRows]=i; |
---|
| 1284 | matrix_->deleteRows(numberRows_-newNumberRows,which); |
---|
| 1285 | delete [] which; |
---|
| 1286 | } |
---|
| 1287 | if (numberRows_!=newNumberRows||numberColumns_!=newNumberColumns) { |
---|
| 1288 | // set state back to unknown |
---|
| 1289 | problemStatus_ = -1; |
---|
[225] | 1290 | secondaryStatus_ = 0; |
---|
[2] | 1291 | delete [] ray_; |
---|
| 1292 | ray_ = NULL; |
---|
| 1293 | } |
---|
[1147] | 1294 | setRowScale(NULL); |
---|
| 1295 | setColumnScale(NULL); |
---|
[50] | 1296 | if (status_) { |
---|
[465] | 1297 | if (newNumberColumns+newNumberRows) { |
---|
[1197] | 1298 | if (newNumberColumns+newNumberRows>maximumRows_+maximumColumns_) { |
---|
| 1299 | unsigned char * tempC = new unsigned char [newNumberColumns+newNumberRows]; |
---|
| 1300 | unsigned char * tempR = tempC + newNumberColumns; |
---|
| 1301 | memset(tempC,3,newNumberColumns*sizeof(unsigned char)); |
---|
| 1302 | memset(tempR,1,newNumberRows*sizeof(unsigned char)); |
---|
| 1303 | CoinMemcpyN(status_,CoinMin(newNumberColumns,numberColumns_),tempC); |
---|
| 1304 | CoinMemcpyN(status_+numberColumns_,CoinMin(newNumberRows,numberRows_),tempR); |
---|
| 1305 | delete [] status_; |
---|
| 1306 | status_ = tempC; |
---|
| 1307 | } else if (newNumberColumns<numberColumns_) { |
---|
| 1308 | memmove(status_+newNumberColumns,status_+numberColumns_, |
---|
| 1309 | newNumberRows); |
---|
| 1310 | } else if (newNumberColumns>numberColumns_) { |
---|
| 1311 | memset(status_+numberColumns_,3,newNumberColumns-numberColumns_); |
---|
| 1312 | memmove(status_+newNumberColumns,status_+numberColumns_, |
---|
| 1313 | newNumberRows); |
---|
| 1314 | } |
---|
[465] | 1315 | } else { |
---|
| 1316 | // empty model - some systems don't like new [0] |
---|
| 1317 | delete [] status_; |
---|
| 1318 | status_ = NULL; |
---|
| 1319 | } |
---|
[50] | 1320 | } |
---|
[733] | 1321 | #ifndef CLP_NO_STD |
---|
| 1322 | if (lengthNames_) { |
---|
| 1323 | // redo row and column names |
---|
| 1324 | if (numberRows_ < newNumberRows) { |
---|
| 1325 | rowNames_.resize(newNumberRows); |
---|
| 1326 | lengthNames_ = CoinMax(lengthNames_,8); |
---|
| 1327 | char name[9]; |
---|
| 1328 | for (int iRow = numberRows_;iRow<newNumberRows;iRow++) { |
---|
| 1329 | sprintf(name,"R%7.7d",iRow); |
---|
| 1330 | rowNames_[iRow]=name; |
---|
| 1331 | } |
---|
| 1332 | } |
---|
| 1333 | if (numberColumns_ < newNumberColumns) { |
---|
| 1334 | columnNames_.resize(newNumberColumns); |
---|
| 1335 | lengthNames_ = CoinMax(lengthNames_,8); |
---|
| 1336 | char name[9]; |
---|
| 1337 | for (int iColumn = numberColumns_;iColumn<newNumberColumns;iColumn++) { |
---|
| 1338 | sprintf(name,"C%7.7d",iColumn); |
---|
| 1339 | columnNames_[iColumn]=name; |
---|
| 1340 | } |
---|
| 1341 | } |
---|
| 1342 | } |
---|
| 1343 | #endif |
---|
[2] | 1344 | numberRows_ = newNumberRows; |
---|
[465] | 1345 | if (newNumberColumns<numberColumns_&&matrix_->getNumCols()) { |
---|
[2] | 1346 | int * which = new int[numberColumns_-newNumberColumns]; |
---|
| 1347 | int i; |
---|
| 1348 | for (i=newNumberColumns;i<numberColumns_;i++) |
---|
| 1349 | which[i-newNumberColumns]=i; |
---|
| 1350 | matrix_->deleteCols(numberColumns_-newNumberColumns,which); |
---|
| 1351 | delete [] which; |
---|
| 1352 | } |
---|
[1197] | 1353 | if (integerType_&&numberColumns2>maximumColumns_) { |
---|
[50] | 1354 | char * temp = new char [newNumberColumns]; |
---|
[706] | 1355 | CoinZeroN(temp,newNumberColumns); |
---|
| 1356 | CoinMemcpyN(integerType_, |
---|
| 1357 | CoinMin(newNumberColumns,numberColumns_),temp); |
---|
[50] | 1358 | delete [] integerType_; |
---|
| 1359 | integerType_ = temp; |
---|
| 1360 | } |
---|
[2] | 1361 | numberColumns_ = newNumberColumns; |
---|
[1197] | 1362 | if ((specialOptions_&65536)!=0) { |
---|
| 1363 | // leave until next create rim to up numbers |
---|
| 1364 | } |
---|
| 1365 | if (maximumRows_>=0) { |
---|
| 1366 | if (numberRows_>maximumRows_) |
---|
| 1367 | printf("resize %d rows, %d old maximum rows\n", |
---|
| 1368 | numberRows_,maximumRows_); |
---|
| 1369 | maximumRows_ = CoinMax(maximumRows_,numberRows_); |
---|
| 1370 | maximumColumns_ = CoinMax(maximumColumns_,numberColumns_); |
---|
| 1371 | } |
---|
[2] | 1372 | } |
---|
| 1373 | // Deletes rows |
---|
| 1374 | void |
---|
| 1375 | ClpModel::deleteRows(int number, const int * which) |
---|
| 1376 | { |
---|
[472] | 1377 | if (!number) |
---|
| 1378 | return; // nothing to do |
---|
| 1379 | whatsChanged_ &= ~(1+2+4+8+16+32); // all except columns changed |
---|
[2] | 1380 | int newSize=0; |
---|
[1197] | 1381 | if (maximumRows_<0) { |
---|
| 1382 | rowActivity_ = deleteDouble(rowActivity_,numberRows_, |
---|
| 1383 | number, which, newSize); |
---|
| 1384 | dual_ = deleteDouble(dual_,numberRows_, |
---|
| 1385 | number, which, newSize); |
---|
| 1386 | rowObjective_ = deleteDouble(rowObjective_,numberRows_, |
---|
| 1387 | number, which, newSize); |
---|
| 1388 | rowLower_ = deleteDouble(rowLower_,numberRows_, |
---|
| 1389 | number, which, newSize); |
---|
| 1390 | rowUpper_ = deleteDouble(rowUpper_,numberRows_, |
---|
| 1391 | number, which, newSize); |
---|
| 1392 | if (matrix_->getNumRows()) |
---|
| 1393 | matrix_->deleteRows(number,which); |
---|
| 1394 | //matrix_->removeGaps(); |
---|
| 1395 | // status |
---|
| 1396 | if (status_) { |
---|
| 1397 | if (numberColumns_+newSize) { |
---|
| 1398 | unsigned char * tempR = (unsigned char *) deleteChar((char *)status_+numberColumns_, |
---|
| 1399 | numberRows_, |
---|
| 1400 | number, which, newSize,false); |
---|
| 1401 | unsigned char * tempC = new unsigned char [numberColumns_+newSize]; |
---|
| 1402 | CoinMemcpyN(status_,numberColumns_,tempC); |
---|
| 1403 | CoinMemcpyN(tempR,newSize,tempC+numberColumns_); |
---|
| 1404 | delete [] tempR; |
---|
| 1405 | delete [] status_; |
---|
| 1406 | status_ = tempC; |
---|
| 1407 | } else { |
---|
| 1408 | // empty model - some systems don't like new [0] |
---|
| 1409 | delete [] status_; |
---|
| 1410 | status_ = NULL; |
---|
| 1411 | } |
---|
[465] | 1412 | } |
---|
[1197] | 1413 | } else { |
---|
| 1414 | char * deleted = new char [numberRows_]; |
---|
| 1415 | int i; |
---|
| 1416 | int numberDeleted=0; |
---|
| 1417 | CoinZeroN(deleted,numberRows_); |
---|
| 1418 | for (i=0;i<number;i++) { |
---|
| 1419 | int j = which[i]; |
---|
| 1420 | if (j>=0&&j<numberRows_&&!deleted[j]) { |
---|
| 1421 | numberDeleted++; |
---|
| 1422 | deleted[j]=1; |
---|
| 1423 | } |
---|
| 1424 | } |
---|
| 1425 | assert (!rowObjective_); |
---|
| 1426 | unsigned char * status2 = status_+numberColumns_; |
---|
| 1427 | for (i=0;i<numberRows_;i++) { |
---|
| 1428 | if (!deleted[i]) { |
---|
| 1429 | rowActivity_[newSize]=rowActivity_[i]; |
---|
| 1430 | dual_[newSize] = dual_[i]; |
---|
| 1431 | rowLower_[newSize] = rowLower_[i]; |
---|
| 1432 | rowUpper_[newSize] = rowUpper_[i]; |
---|
| 1433 | status2[newSize] = status2[i]; |
---|
| 1434 | newSize++; |
---|
| 1435 | } |
---|
| 1436 | } |
---|
| 1437 | if (matrix_->getNumRows()) |
---|
| 1438 | matrix_->deleteRows(number,which); |
---|
| 1439 | //matrix_->removeGaps(); |
---|
| 1440 | delete [] deleted; |
---|
[50] | 1441 | } |
---|
[653] | 1442 | #ifndef CLP_NO_STD |
---|
[648] | 1443 | // Now works if which out of order |
---|
[304] | 1444 | if (lengthNames_) { |
---|
[648] | 1445 | char * mark = new char [numberRows_]; |
---|
[706] | 1446 | CoinZeroN(mark,numberRows_); |
---|
[648] | 1447 | int i; |
---|
| 1448 | for (i=0;i<number;i++) |
---|
| 1449 | mark[which[i]]=1; |
---|
| 1450 | int k=0; |
---|
| 1451 | for ( i = 0; i < numberRows_; ++i) { |
---|
| 1452 | if (!mark[i]) |
---|
[301] | 1453 | rowNames_[k++] = rowNames_[i]; |
---|
[304] | 1454 | } |
---|
| 1455 | rowNames_.erase(rowNames_.begin()+k, rowNames_.end()); |
---|
[648] | 1456 | delete [] mark; |
---|
[301] | 1457 | } |
---|
| 1458 | #endif |
---|
[77] | 1459 | numberRows_=newSize; |
---|
| 1460 | // set state back to unknown |
---|
| 1461 | problemStatus_ = -1; |
---|
[225] | 1462 | secondaryStatus_ = 0; |
---|
[77] | 1463 | delete [] ray_; |
---|
| 1464 | ray_ = NULL; |
---|
[1147] | 1465 | if (savedRowScale_!=rowScale_) { |
---|
| 1466 | delete [] rowScale_; |
---|
| 1467 | delete [] columnScale_; |
---|
| 1468 | } |
---|
[372] | 1469 | rowScale_ = NULL; |
---|
| 1470 | columnScale_ = NULL; |
---|
[2] | 1471 | } |
---|
| 1472 | // Deletes columns |
---|
| 1473 | void |
---|
| 1474 | ClpModel::deleteColumns(int number, const int * which) |
---|
| 1475 | { |
---|
[472] | 1476 | if (!number) |
---|
| 1477 | return; // nothing to do |
---|
[1197] | 1478 | assert (maximumColumns_<0); |
---|
[472] | 1479 | whatsChanged_ &= ~(1+2+4+8+64+128+256); // all except rows changed |
---|
[2] | 1480 | int newSize=0; |
---|
| 1481 | columnActivity_ = deleteDouble(columnActivity_,numberColumns_, |
---|
| 1482 | number, which, newSize); |
---|
| 1483 | reducedCost_ = deleteDouble(reducedCost_,numberColumns_, |
---|
| 1484 | number, which, newSize); |
---|
[119] | 1485 | objective_->deleteSome(number, which); |
---|
[2] | 1486 | columnLower_ = deleteDouble(columnLower_,numberColumns_, |
---|
| 1487 | number, which, newSize); |
---|
| 1488 | columnUpper_ = deleteDouble(columnUpper_,numberColumns_, |
---|
| 1489 | number, which, newSize); |
---|
[381] | 1490 | // possible matrix is not full |
---|
| 1491 | if (matrix_->getNumCols()<numberColumns_) { |
---|
| 1492 | int * which2 = new int [number]; |
---|
| 1493 | int n=0; |
---|
| 1494 | int nMatrix = matrix_->getNumCols(); |
---|
| 1495 | for (int i=0;i<number;i++) { |
---|
| 1496 | if (which[i]<nMatrix) |
---|
| 1497 | which2[n++]=which[i]; |
---|
| 1498 | } |
---|
| 1499 | matrix_->deleteCols(n,which2); |
---|
| 1500 | delete [] which2; |
---|
| 1501 | } else { |
---|
| 1502 | matrix_->deleteCols(number,which); |
---|
| 1503 | } |
---|
[225] | 1504 | //matrix_->removeGaps(); |
---|
[50] | 1505 | // status |
---|
| 1506 | if (status_) { |
---|
[465] | 1507 | if (numberRows_+newSize) { |
---|
| 1508 | unsigned char * tempC = (unsigned char *) deleteChar((char *)status_, |
---|
| 1509 | numberColumns_, |
---|
| 1510 | number, which, newSize,false); |
---|
| 1511 | unsigned char * temp = new unsigned char [numberRows_+newSize]; |
---|
[1197] | 1512 | CoinMemcpyN(tempC,newSize,temp); |
---|
| 1513 | CoinMemcpyN(status_+numberColumns_, numberRows_,temp+newSize); |
---|
[465] | 1514 | delete [] tempC; |
---|
| 1515 | delete [] status_; |
---|
| 1516 | status_ = temp; |
---|
| 1517 | } else { |
---|
| 1518 | // empty model - some systems don't like new [0] |
---|
| 1519 | delete [] status_; |
---|
| 1520 | status_ = NULL; |
---|
| 1521 | } |
---|
[50] | 1522 | } |
---|
[225] | 1523 | integerType_ = deleteChar(integerType_,numberColumns_, |
---|
| 1524 | number, which, newSize,true); |
---|
[653] | 1525 | #ifndef CLP_NO_STD |
---|
[648] | 1526 | // Now works if which out of order |
---|
[304] | 1527 | if (lengthNames_) { |
---|
[648] | 1528 | char * mark = new char [numberColumns_]; |
---|
[706] | 1529 | CoinZeroN(mark,numberColumns_); |
---|
[648] | 1530 | int i; |
---|
| 1531 | for (i=0;i<number;i++) |
---|
| 1532 | mark[which[i]]=1; |
---|
| 1533 | int k=0; |
---|
| 1534 | for ( i = 0; i < numberColumns_; ++i) { |
---|
| 1535 | if (!mark[i]) |
---|
[301] | 1536 | columnNames_[k++] = columnNames_[i]; |
---|
[304] | 1537 | } |
---|
| 1538 | columnNames_.erase(columnNames_.begin()+k, columnNames_.end()); |
---|
[648] | 1539 | delete [] mark; |
---|
[301] | 1540 | } |
---|
| 1541 | #endif |
---|
[77] | 1542 | numberColumns_=newSize; |
---|
| 1543 | // set state back to unknown |
---|
| 1544 | problemStatus_ = -1; |
---|
[225] | 1545 | secondaryStatus_ = 0; |
---|
[77] | 1546 | delete [] ray_; |
---|
| 1547 | ray_ = NULL; |
---|
[1147] | 1548 | setRowScale(NULL); |
---|
| 1549 | setColumnScale(NULL); |
---|
[2] | 1550 | } |
---|
[527] | 1551 | // Add one row |
---|
| 1552 | void |
---|
| 1553 | ClpModel::addRow(int numberInRow, const int * columns, |
---|
| 1554 | const double * elements, double rowLower, double rowUpper) |
---|
| 1555 | { |
---|
[653] | 1556 | CoinBigIndex starts[2]; |
---|
| 1557 | starts[0]=0; |
---|
| 1558 | starts[1]=numberInRow; |
---|
| 1559 | addRows(1, &rowLower, &rowUpper,starts,columns,elements); |
---|
[527] | 1560 | } |
---|
[169] | 1561 | // Add rows |
---|
| 1562 | void |
---|
| 1563 | ClpModel::addRows(int number, const double * rowLower, |
---|
| 1564 | const double * rowUpper, |
---|
| 1565 | const int * rowStarts, const int * columns, |
---|
| 1566 | const double * elements) |
---|
| 1567 | { |
---|
| 1568 | if (number) { |
---|
[653] | 1569 | whatsChanged_ &= ~(1+2+8+16+32); // all except columns changed |
---|
| 1570 | int numberRowsNow = numberRows_; |
---|
| 1571 | resize(numberRowsNow+number,numberColumns_); |
---|
| 1572 | double * lower = rowLower_+numberRowsNow; |
---|
| 1573 | double * upper = rowUpper_+numberRowsNow; |
---|
[169] | 1574 | int iRow; |
---|
[653] | 1575 | if (rowLower) { |
---|
| 1576 | for (iRow = 0; iRow < number; iRow++) { |
---|
| 1577 | double value = rowLower[iRow]; |
---|
| 1578 | if (value<-1.0e20) |
---|
| 1579 | value = -COIN_DBL_MAX; |
---|
| 1580 | lower[iRow]= value; |
---|
| 1581 | } |
---|
| 1582 | } else { |
---|
| 1583 | for (iRow = 0; iRow < number; iRow++) { |
---|
| 1584 | lower[iRow]= -COIN_DBL_MAX; |
---|
| 1585 | } |
---|
[169] | 1586 | } |
---|
[653] | 1587 | if (rowUpper) { |
---|
| 1588 | for (iRow = 0; iRow < number; iRow++) { |
---|
| 1589 | double value = rowUpper[iRow]; |
---|
| 1590 | if (value>1.0e20) |
---|
| 1591 | value = COIN_DBL_MAX; |
---|
| 1592 | upper[iRow]= value; |
---|
| 1593 | } |
---|
| 1594 | } else { |
---|
| 1595 | for (iRow = 0; iRow < number; iRow++) { |
---|
| 1596 | upper[iRow]= COIN_DBL_MAX; |
---|
| 1597 | } |
---|
| 1598 | } |
---|
| 1599 | // Deal with matrix |
---|
| 1600 | |
---|
| 1601 | delete rowCopy_; |
---|
| 1602 | rowCopy_=NULL; |
---|
[1150] | 1603 | delete scaledMatrix_; |
---|
| 1604 | scaledMatrix_=NULL; |
---|
[653] | 1605 | if (!matrix_) |
---|
| 1606 | createEmptyMatrix(); |
---|
[1147] | 1607 | setRowScale(NULL); |
---|
| 1608 | setColumnScale(NULL); |
---|
[653] | 1609 | #ifndef CLP_NO_STD |
---|
| 1610 | if (lengthNames_) { |
---|
| 1611 | rowNames_.resize(numberRows_); |
---|
| 1612 | } |
---|
| 1613 | #endif |
---|
[1153] | 1614 | if (rowStarts) |
---|
| 1615 | matrix_->appendMatrix(number,0,rowStarts,columns,elements); |
---|
[169] | 1616 | } |
---|
| 1617 | } |
---|
[225] | 1618 | // Add rows |
---|
[169] | 1619 | void |
---|
| 1620 | ClpModel::addRows(int number, const double * rowLower, |
---|
| 1621 | const double * rowUpper, |
---|
[225] | 1622 | const int * rowStarts, |
---|
| 1623 | const int * rowLengths, const int * columns, |
---|
| 1624 | const double * elements) |
---|
| 1625 | { |
---|
| 1626 | if (number) { |
---|
[653] | 1627 | CoinBigIndex numberElements=0; |
---|
[225] | 1628 | int iRow; |
---|
[653] | 1629 | for (iRow=0;iRow<number;iRow++) |
---|
| 1630 | numberElements += rowLengths[iRow]; |
---|
| 1631 | int * newStarts = new int[number+1]; |
---|
| 1632 | int * newIndex = new int[numberElements]; |
---|
| 1633 | double * newElements = new double[numberElements]; |
---|
| 1634 | numberElements=0; |
---|
| 1635 | newStarts[0]=0; |
---|
[225] | 1636 | for (iRow=0;iRow<number;iRow++) { |
---|
| 1637 | int iStart = rowStarts[iRow]; |
---|
[653] | 1638 | int length = rowLengths[iRow]; |
---|
[706] | 1639 | CoinMemcpyN(columns+iStart,length,newIndex+numberElements); |
---|
| 1640 | CoinMemcpyN(elements+iStart,length,newElements+numberElements); |
---|
[653] | 1641 | numberElements += length; |
---|
| 1642 | newStarts[iRow+1]=numberElements; |
---|
[225] | 1643 | } |
---|
| 1644 | addRows(number, rowLower, rowUpper, |
---|
[653] | 1645 | newStarts,newIndex,newElements); |
---|
| 1646 | delete [] newStarts; |
---|
| 1647 | delete [] newIndex; |
---|
| 1648 | delete [] newElements; |
---|
[225] | 1649 | } |
---|
| 1650 | } |
---|
[653] | 1651 | #ifndef CLP_NO_VECTOR |
---|
[225] | 1652 | void |
---|
| 1653 | ClpModel::addRows(int number, const double * rowLower, |
---|
| 1654 | const double * rowUpper, |
---|
[169] | 1655 | const CoinPackedVectorBase * const * rows) |
---|
| 1656 | { |
---|
| 1657 | if (!number) |
---|
| 1658 | return; |
---|
[472] | 1659 | whatsChanged_ &= ~(1+2+8+16+32); // all except columns changed |
---|
[169] | 1660 | int numberRowsNow = numberRows_; |
---|
| 1661 | resize(numberRowsNow+number,numberColumns_); |
---|
| 1662 | double * lower = rowLower_+numberRowsNow; |
---|
| 1663 | double * upper = rowUpper_+numberRowsNow; |
---|
| 1664 | int iRow; |
---|
| 1665 | if (rowLower) { |
---|
| 1666 | for (iRow = 0; iRow < number; iRow++) { |
---|
| 1667 | double value = rowLower[iRow]; |
---|
| 1668 | if (value<-1.0e20) |
---|
| 1669 | value = -COIN_DBL_MAX; |
---|
| 1670 | lower[iRow]= value; |
---|
| 1671 | } |
---|
| 1672 | } else { |
---|
| 1673 | for (iRow = 0; iRow < number; iRow++) { |
---|
| 1674 | lower[iRow]= -COIN_DBL_MAX; |
---|
| 1675 | } |
---|
| 1676 | } |
---|
| 1677 | if (rowUpper) { |
---|
| 1678 | for (iRow = 0; iRow < number; iRow++) { |
---|
| 1679 | double value = rowUpper[iRow]; |
---|
| 1680 | if (value>1.0e20) |
---|
| 1681 | value = COIN_DBL_MAX; |
---|
| 1682 | upper[iRow]= value; |
---|
| 1683 | } |
---|
| 1684 | } else { |
---|
| 1685 | for (iRow = 0; iRow < number; iRow++) { |
---|
| 1686 | upper[iRow]= COIN_DBL_MAX; |
---|
| 1687 | } |
---|
| 1688 | } |
---|
| 1689 | // Deal with matrix |
---|
| 1690 | |
---|
| 1691 | delete rowCopy_; |
---|
| 1692 | rowCopy_=NULL; |
---|
[1150] | 1693 | delete scaledMatrix_; |
---|
| 1694 | scaledMatrix_=NULL; |
---|
[169] | 1695 | if (!matrix_) |
---|
| 1696 | createEmptyMatrix(); |
---|
[557] | 1697 | if (rows) |
---|
| 1698 | matrix_->appendRows(number,rows); |
---|
[1147] | 1699 | setRowScale(NULL); |
---|
| 1700 | setColumnScale(NULL); |
---|
[648] | 1701 | if (lengthNames_) { |
---|
| 1702 | rowNames_.resize(numberRows_); |
---|
| 1703 | } |
---|
[169] | 1704 | } |
---|
[653] | 1705 | #endif |
---|
[650] | 1706 | #ifndef SLIM_CLP |
---|
[538] | 1707 | // Add rows from a build object |
---|
[577] | 1708 | int |
---|
| 1709 | ClpModel::addRows(const CoinBuild & buildObject,bool tryPlusMinusOne,bool checkDuplicates) |
---|
[538] | 1710 | { |
---|
[560] | 1711 | CoinAssertHint (buildObject.type()==0,"Looks as if both addRows and addCols being used"); // check correct |
---|
[538] | 1712 | int number = buildObject.numberRows(); |
---|
[577] | 1713 | int numberErrors=0; |
---|
[538] | 1714 | if (number) { |
---|
[558] | 1715 | CoinBigIndex size=0; |
---|
[538] | 1716 | int iRow; |
---|
| 1717 | double * lower = new double [number]; |
---|
| 1718 | double * upper = new double [number]; |
---|
[559] | 1719 | if ((!matrix_||!matrix_->getNumElements())&&tryPlusMinusOne) { |
---|
[558] | 1720 | // See if can be +-1 |
---|
| 1721 | for (iRow=0;iRow<number;iRow++) { |
---|
| 1722 | const int * columns; |
---|
| 1723 | const double * elements; |
---|
| 1724 | int numberElements = buildObject.row(iRow,lower[iRow], |
---|
| 1725 | upper[iRow], |
---|
| 1726 | columns,elements); |
---|
| 1727 | for (int i=0;i<numberElements;i++) { |
---|
| 1728 | // allow for zero elements |
---|
| 1729 | if (elements[i]) { |
---|
| 1730 | if (fabs(elements[i])==1.0) { |
---|
| 1731 | size++; |
---|
| 1732 | } else { |
---|
| 1733 | // bad |
---|
| 1734 | tryPlusMinusOne=false; |
---|
| 1735 | } |
---|
| 1736 | } |
---|
| 1737 | } |
---|
| 1738 | if (!tryPlusMinusOne) |
---|
| 1739 | break; |
---|
| 1740 | } |
---|
| 1741 | } else { |
---|
| 1742 | // Will add to whatever sort of matrix exists |
---|
| 1743 | tryPlusMinusOne=false; |
---|
[538] | 1744 | } |
---|
[558] | 1745 | if (!tryPlusMinusOne) { |
---|
[577] | 1746 | CoinBigIndex numberElements = buildObject.numberElements(); |
---|
| 1747 | CoinBigIndex * starts = new CoinBigIndex [number+1]; |
---|
| 1748 | int * column = new int[numberElements]; |
---|
| 1749 | double * element = new double[numberElements]; |
---|
| 1750 | starts[0]=0; |
---|
| 1751 | numberElements=0; |
---|
| 1752 | for (iRow=0;iRow<number;iRow++) { |
---|
| 1753 | const int * columns; |
---|
| 1754 | const double * elements; |
---|
| 1755 | int numberElementsThis = buildObject.row(iRow,lower[iRow],upper[iRow], |
---|
| 1756 | columns,elements); |
---|
| 1757 | CoinMemcpyN(columns,numberElementsThis,column+numberElements); |
---|
| 1758 | CoinMemcpyN(elements,numberElementsThis,element+numberElements); |
---|
| 1759 | numberElements += numberElementsThis; |
---|
| 1760 | starts[iRow+1]=numberElements; |
---|
| 1761 | } |
---|
| 1762 | addRows(number, lower, upper,NULL); |
---|
| 1763 | // make sure matrix has enough columns |
---|
| 1764 | matrix_->setDimensions(-1,numberColumns_); |
---|
| 1765 | numberErrors=matrix_->appendMatrix(number,0,starts,column,element, |
---|
| 1766 | checkDuplicates ? numberColumns_ : -1); |
---|
| 1767 | delete [] starts; |
---|
| 1768 | delete [] column; |
---|
| 1769 | delete [] element; |
---|
| 1770 | } else { |
---|
| 1771 | char * which=NULL; // for duplicates |
---|
| 1772 | if (checkDuplicates) { |
---|
| 1773 | which = new char[numberColumns_]; |
---|
[706] | 1774 | CoinZeroN(which,numberColumns_); |
---|
[577] | 1775 | } |
---|
| 1776 | // build +-1 matrix |
---|
| 1777 | // arrays already filled in |
---|
| 1778 | addRows(number, lower, upper,NULL); |
---|
| 1779 | CoinBigIndex * startPositive = new CoinBigIndex [numberColumns_+1]; |
---|
| 1780 | CoinBigIndex * startNegative = new CoinBigIndex [numberColumns_]; |
---|
| 1781 | int * indices = new int [size]; |
---|
[706] | 1782 | CoinZeroN(startPositive,numberColumns_); |
---|
| 1783 | CoinZeroN(startNegative,numberColumns_); |
---|
[577] | 1784 | int maxColumn=-1; |
---|
| 1785 | // need two passes |
---|
| 1786 | for (iRow=0;iRow<number;iRow++) { |
---|
| 1787 | const int * columns; |
---|
| 1788 | const double * elements; |
---|
| 1789 | int numberElements = buildObject.row(iRow,lower[iRow], |
---|
| 1790 | upper[iRow], |
---|
| 1791 | columns,elements); |
---|
| 1792 | for (int i=0;i<numberElements;i++) { |
---|
| 1793 | int iColumn=columns[i]; |
---|
| 1794 | if (checkDuplicates) { |
---|
| 1795 | if (iColumn>=numberColumns_) { |
---|
| 1796 | if(which[iColumn]) |
---|
| 1797 | numberErrors++; |
---|
| 1798 | else |
---|
| 1799 | which[iColumn]=1; |
---|
| 1800 | } else { |
---|
| 1801 | numberErrors++; |
---|
| 1802 | // and may as well switch off |
---|
| 1803 | checkDuplicates=false; |
---|
| 1804 | } |
---|
| 1805 | } |
---|
| 1806 | maxColumn = CoinMax(maxColumn,iColumn); |
---|
| 1807 | if (elements[i]==1.0) { |
---|
| 1808 | startPositive[iColumn]++; |
---|
| 1809 | } else if (elements[i]==-1.0) { |
---|
| 1810 | startNegative[iColumn]++; |
---|
| 1811 | } |
---|
| 1812 | } |
---|
| 1813 | if (checkDuplicates) { |
---|
| 1814 | for (int i=0;i<numberElements;i++) { |
---|
| 1815 | int iColumn=columns[i]; |
---|
| 1816 | which[iColumn]=0; |
---|
| 1817 | } |
---|
| 1818 | } |
---|
| 1819 | } |
---|
| 1820 | // check size |
---|
| 1821 | int numberColumns = maxColumn+1; |
---|
| 1822 | CoinAssertHint (numberColumns<=numberColumns_, |
---|
| 1823 | "rows having column indices >= numberColumns_"); |
---|
| 1824 | size=0; |
---|
| 1825 | int iColumn; |
---|
| 1826 | for (iColumn=0;iColumn<numberColumns_;iColumn++) { |
---|
| 1827 | CoinBigIndex n=startPositive[iColumn]; |
---|
| 1828 | startPositive[iColumn]=size; |
---|
| 1829 | size+= n; |
---|
| 1830 | n=startNegative[iColumn]; |
---|
| 1831 | startNegative[iColumn]=size; |
---|
| 1832 | size+= n; |
---|
| 1833 | } |
---|
| 1834 | startPositive[numberColumns_]=size; |
---|
| 1835 | for (iRow=0;iRow<number;iRow++) { |
---|
| 1836 | const int * columns; |
---|
| 1837 | const double * elements; |
---|
| 1838 | int numberElements = buildObject.row(iRow,lower[iRow], |
---|
| 1839 | upper[iRow], |
---|
| 1840 | columns,elements); |
---|
| 1841 | for (int i=0;i<numberElements;i++) { |
---|
| 1842 | int iColumn=columns[i]; |
---|
| 1843 | maxColumn = CoinMax(maxColumn,iColumn); |
---|
| 1844 | if (elements[i]==1.0) { |
---|
| 1845 | CoinBigIndex position = startPositive[iColumn]; |
---|
| 1846 | indices[position]=iRow; |
---|
| 1847 | startPositive[iColumn]++; |
---|
| 1848 | } else if (elements[i]==-1.0) { |
---|
| 1849 | CoinBigIndex position = startNegative[iColumn]; |
---|
| 1850 | indices[position]=iRow; |
---|
| 1851 | startNegative[iColumn]++; |
---|
| 1852 | } |
---|
| 1853 | } |
---|
| 1854 | } |
---|
| 1855 | // and now redo starts |
---|
| 1856 | for (iColumn=numberColumns_-1;iColumn>=0;iColumn--) { |
---|
| 1857 | startPositive[iColumn+1]=startNegative[iColumn]; |
---|
| 1858 | startNegative[iColumn]=startPositive[iColumn]; |
---|
| 1859 | } |
---|
| 1860 | startPositive[0]=0; |
---|
| 1861 | for (iColumn=0;iColumn<numberColumns_;iColumn++) { |
---|
| 1862 | CoinBigIndex start = startPositive[iColumn]; |
---|
| 1863 | CoinBigIndex end = startNegative[iColumn]; |
---|
| 1864 | std::sort(indices+start,indices+end); |
---|
| 1865 | start = startNegative[iColumn]; |
---|
| 1866 | end = startPositive[iColumn+1]; |
---|
| 1867 | std::sort(indices+start,indices+end); |
---|
| 1868 | } |
---|
| 1869 | // Get good object |
---|
| 1870 | delete matrix_; |
---|
| 1871 | ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix(); |
---|
| 1872 | matrix->passInCopy(numberRows_,numberColumns, |
---|
| 1873 | true,indices,startPositive,startNegative); |
---|
| 1874 | matrix_=matrix; |
---|
| 1875 | delete [] which; |
---|
| 1876 | } |
---|
| 1877 | delete [] lower; |
---|
| 1878 | delete [] upper; |
---|
| 1879 | // make sure matrix correct size |
---|
| 1880 | matrix_->setDimensions(numberRows_,numberColumns_); |
---|
| 1881 | } |
---|
| 1882 | return numberErrors; |
---|
| 1883 | } |
---|
[650] | 1884 | #endif |
---|
[651] | 1885 | #ifndef SLIM_NOIO |
---|
[577] | 1886 | // Add rows from a model object |
---|
| 1887 | int |
---|
[580] | 1888 | ClpModel::addRows( CoinModel & modelObject,bool tryPlusMinusOne,bool checkDuplicates) |
---|
[577] | 1889 | { |
---|
[618] | 1890 | if (modelObject.numberElements()==0) |
---|
| 1891 | return 0; |
---|
[577] | 1892 | bool goodState=true; |
---|
| 1893 | int numberErrors=0; |
---|
| 1894 | if (modelObject.columnLowerArray()) { |
---|
| 1895 | // some column information exists |
---|
| 1896 | int numberColumns2 = modelObject.numberColumns(); |
---|
| 1897 | const double * columnLower = modelObject.columnLowerArray(); |
---|
| 1898 | const double * columnUpper = modelObject.columnUpperArray(); |
---|
| 1899 | const double * objective = modelObject.objectiveArray(); |
---|
| 1900 | const int * integerType = modelObject.integerTypeArray(); |
---|
| 1901 | for (int i=0;i<numberColumns2;i++) { |
---|
| 1902 | if (columnLower[i]!=0.0) |
---|
| 1903 | goodState=false; |
---|
| 1904 | if (columnUpper[i]!=COIN_DBL_MAX) |
---|
| 1905 | goodState=false; |
---|
| 1906 | if (objective[i]!=0.0) |
---|
| 1907 | goodState=false; |
---|
| 1908 | if (integerType[i]!=0) |
---|
| 1909 | goodState=false; |
---|
| 1910 | } |
---|
| 1911 | } |
---|
| 1912 | if (goodState) { |
---|
| 1913 | // can do addRows |
---|
| 1914 | // Set arrays for normal use |
---|
| 1915 | double * rowLower = modelObject.rowLowerArray(); |
---|
| 1916 | double * rowUpper = modelObject.rowUpperArray(); |
---|
| 1917 | double * columnLower = modelObject.columnLowerArray(); |
---|
| 1918 | double * columnUpper = modelObject.columnUpperArray(); |
---|
| 1919 | double * objective = modelObject.objectiveArray(); |
---|
| 1920 | int * integerType = modelObject.integerTypeArray(); |
---|
| 1921 | double * associated = modelObject.associatedArray(); |
---|
| 1922 | // If strings then do copies |
---|
| 1923 | if (modelObject.stringsExist()) { |
---|
| 1924 | numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper, |
---|
| 1925 | objective, integerType,associated); |
---|
| 1926 | } |
---|
| 1927 | int numberRows = numberRows_; // save number of rows |
---|
| 1928 | int numberRows2 = modelObject.numberRows(); |
---|
| 1929 | if (numberRows2&&!numberErrors) { |
---|
| 1930 | CoinBigIndex * startPositive = NULL; |
---|
| 1931 | CoinBigIndex * startNegative = NULL; |
---|
| 1932 | int numberColumns = modelObject.numberColumns(); |
---|
| 1933 | if ((!matrix_||!matrix_->getNumElements())&&!numberRows&&tryPlusMinusOne) { |
---|
| 1934 | startPositive = new CoinBigIndex[numberColumns+1]; |
---|
| 1935 | startNegative = new CoinBigIndex[numberColumns]; |
---|
| 1936 | modelObject.countPlusMinusOne(startPositive,startNegative,associated); |
---|
| 1937 | if (startPositive[0]<0) { |
---|
| 1938 | // no good |
---|
| 1939 | tryPlusMinusOne=false; |
---|
| 1940 | delete [] startPositive; |
---|
| 1941 | delete [] startNegative; |
---|
| 1942 | } |
---|
| 1943 | } else { |
---|
| 1944 | // Will add to whatever sort of matrix exists |
---|
| 1945 | tryPlusMinusOne=false; |
---|
| 1946 | } |
---|
| 1947 | assert (rowLower); |
---|
[653] | 1948 | addRows(numberRows2, rowLower, rowUpper,NULL,NULL,NULL); |
---|
[650] | 1949 | #ifndef SLIM_CLP |
---|
[577] | 1950 | if (!tryPlusMinusOne) { |
---|
[650] | 1951 | #endif |
---|
[577] | 1952 | CoinPackedMatrix matrix; |
---|
| 1953 | modelObject.createPackedMatrix(matrix,associated); |
---|
| 1954 | assert (!matrix.getExtraGap()); |
---|
| 1955 | if (matrix_->getNumRows()) { |
---|
| 1956 | // matrix by rows |
---|
| 1957 | matrix.reverseOrdering(); |
---|
| 1958 | assert (!matrix.getExtraGap()); |
---|
| 1959 | const int * column = matrix.getIndices(); |
---|
| 1960 | //const int * rowLength = matrix.getVectorLengths(); |
---|
| 1961 | const CoinBigIndex * rowStart = matrix.getVectorStarts(); |
---|
| 1962 | const double * element = matrix.getElements(); |
---|
| 1963 | // make sure matrix has enough columns |
---|
| 1964 | matrix_->setDimensions(-1,numberColumns_); |
---|
| 1965 | numberErrors+=matrix_->appendMatrix(numberRows2,0,rowStart,column,element, |
---|
| 1966 | checkDuplicates ? numberColumns_ : -1); |
---|
| 1967 | } else { |
---|
| 1968 | delete matrix_; |
---|
| 1969 | matrix_ = new ClpPackedMatrix(matrix); |
---|
| 1970 | } |
---|
[650] | 1971 | #ifndef SLIM_CLP |
---|
[577] | 1972 | } else { |
---|
| 1973 | // create +-1 matrix |
---|
| 1974 | CoinBigIndex size = startPositive[numberColumns]; |
---|
| 1975 | int * indices = new int[size]; |
---|
| 1976 | modelObject.createPlusMinusOne(startPositive,startNegative,indices, |
---|
| 1977 | associated); |
---|
| 1978 | // Get good object |
---|
| 1979 | ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix(); |
---|
| 1980 | matrix->passInCopy(numberRows2,numberColumns, |
---|
| 1981 | true,indices,startPositive,startNegative); |
---|
| 1982 | delete matrix_; |
---|
| 1983 | matrix_=matrix; |
---|
| 1984 | } |
---|
| 1985 | // Do names if wanted |
---|
| 1986 | if (modelObject.rowNames()->numberItems()) { |
---|
| 1987 | const char *const * rowNames=modelObject.rowNames()->names(); |
---|
| 1988 | copyRowNames(rowNames,numberRows,numberRows_); |
---|
| 1989 | } |
---|
[650] | 1990 | #endif |
---|
[577] | 1991 | } |
---|
| 1992 | if (rowLower!=modelObject.rowLowerArray()) { |
---|
| 1993 | delete [] rowLower; |
---|
| 1994 | delete [] rowUpper; |
---|
| 1995 | delete [] columnLower; |
---|
| 1996 | delete [] columnUpper; |
---|
| 1997 | delete [] objective; |
---|
| 1998 | delete [] integerType; |
---|
| 1999 | delete [] associated; |
---|
| 2000 | if (numberErrors) |
---|
| 2001 | handler_->message(CLP_BAD_STRING_VALUES,messages_) |
---|
| 2002 | <<numberErrors |
---|
| 2003 | <<CoinMessageEol; |
---|
| 2004 | } |
---|
| 2005 | return numberErrors; |
---|
| 2006 | } else { |
---|
| 2007 | // not suitable for addRows |
---|
| 2008 | handler_->message(CLP_COMPLICATED_MODEL,messages_) |
---|
| 2009 | <<modelObject.numberRows() |
---|
| 2010 | <<modelObject.numberColumns() |
---|
| 2011 | <<CoinMessageEol; |
---|
| 2012 | return -1; |
---|
| 2013 | } |
---|
| 2014 | } |
---|
[651] | 2015 | #endif |
---|
[527] | 2016 | // Add one column |
---|
| 2017 | void |
---|
| 2018 | ClpModel::addColumn(int numberInColumn, |
---|
| 2019 | const int * rows, |
---|
| 2020 | const double * elements, |
---|
| 2021 | double columnLower, |
---|
| 2022 | double columnUpper, |
---|
| 2023 | double objective) |
---|
| 2024 | { |
---|
[653] | 2025 | CoinBigIndex starts[2]; |
---|
| 2026 | starts[0]=0; |
---|
| 2027 | starts[1]=numberInColumn; |
---|
| 2028 | addColumns(1, &columnLower, &columnUpper,&objective,starts,rows,elements); |
---|
[527] | 2029 | } |
---|
[169] | 2030 | // Add columns |
---|
| 2031 | void |
---|
| 2032 | ClpModel::addColumns(int number, const double * columnLower, |
---|
| 2033 | const double * columnUpper, |
---|
| 2034 | const double * objIn, |
---|
| 2035 | const int * columnStarts, const int * rows, |
---|
| 2036 | const double * elements) |
---|
| 2037 | { |
---|
| 2038 | // Create a list of CoinPackedVectors |
---|
| 2039 | if (number) { |
---|
[472] | 2040 | whatsChanged_ &= ~(1+2+4+64+128+256); // all except rows changed |
---|
[653] | 2041 | int numberColumnsNow = numberColumns_; |
---|
| 2042 | resize(numberRows_,numberColumnsNow+number); |
---|
| 2043 | double * lower = columnLower_+numberColumnsNow; |
---|
| 2044 | double * upper = columnUpper_+numberColumnsNow; |
---|
| 2045 | double * obj = objective()+numberColumnsNow; |
---|
[169] | 2046 | int iColumn; |
---|
[653] | 2047 | if (columnLower) { |
---|
| 2048 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
| 2049 | double value = columnLower[iColumn]; |
---|
| 2050 | if (value<-1.0e20) |
---|
| 2051 | value = -COIN_DBL_MAX; |
---|
| 2052 | lower[iColumn]= value; |
---|
| 2053 | } |
---|
| 2054 | } else { |
---|
| 2055 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
| 2056 | lower[iColumn]= 0.0; |
---|
| 2057 | } |
---|
[169] | 2058 | } |
---|
[653] | 2059 | if (columnUpper) { |
---|
| 2060 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
| 2061 | double value = columnUpper[iColumn]; |
---|
| 2062 | if (value>1.0e20) |
---|
| 2063 | value = COIN_DBL_MAX; |
---|
| 2064 | upper[iColumn]= value; |
---|
| 2065 | } |
---|
| 2066 | } else { |
---|
| 2067 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
| 2068 | upper[iColumn]= COIN_DBL_MAX; |
---|
| 2069 | } |
---|
| 2070 | } |
---|
| 2071 | if (objIn) { |
---|
| 2072 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
| 2073 | obj[iColumn] = objIn[iColumn]; |
---|
| 2074 | } |
---|
| 2075 | } else { |
---|
| 2076 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
| 2077 | obj[iColumn]= 0.0; |
---|
| 2078 | } |
---|
| 2079 | } |
---|
| 2080 | // Deal with matrix |
---|
| 2081 | |
---|
| 2082 | delete rowCopy_; |
---|
| 2083 | rowCopy_=NULL; |
---|
[1150] | 2084 | delete scaledMatrix_; |
---|
| 2085 | scaledMatrix_=NULL; |
---|
[653] | 2086 | if (!matrix_) |
---|
| 2087 | createEmptyMatrix(); |
---|
[1147] | 2088 | setRowScale(NULL); |
---|
| 2089 | setColumnScale(NULL); |
---|
[653] | 2090 | #ifndef CLP_NO_STD |
---|
| 2091 | if (lengthNames_) { |
---|
| 2092 | columnNames_.resize(numberColumns_); |
---|
| 2093 | } |
---|
| 2094 | #endif |
---|
[1034] | 2095 | //if (elements) |
---|
| 2096 | matrix_->appendMatrix(number,1,columnStarts,rows,elements); |
---|
[169] | 2097 | } |
---|
| 2098 | } |
---|
[225] | 2099 | // Add columns |
---|
[169] | 2100 | void |
---|
| 2101 | ClpModel::addColumns(int number, const double * columnLower, |
---|
| 2102 | const double * columnUpper, |
---|
| 2103 | const double * objIn, |
---|
[225] | 2104 | const int * columnStarts, |
---|
| 2105 | const int * columnLengths, const int * rows, |
---|
| 2106 | const double * elements) |
---|
| 2107 | { |
---|
| 2108 | if (number) { |
---|
[653] | 2109 | CoinBigIndex numberElements=0; |
---|
[225] | 2110 | int iColumn; |
---|
[653] | 2111 | for (iColumn=0;iColumn<number;iColumn++) |
---|
| 2112 | numberElements += columnLengths[iColumn]; |
---|
| 2113 | int * newStarts = new int[number+1]; |
---|
| 2114 | int * newIndex = new int[numberElements]; |
---|
| 2115 | double * newElements = new double[numberElements]; |
---|
| 2116 | numberElements=0; |
---|
| 2117 | newStarts[0]=0; |
---|
[225] | 2118 | for (iColumn=0;iColumn<number;iColumn++) { |
---|
| 2119 | int iStart = columnStarts[iColumn]; |
---|
[653] | 2120 | int length = columnLengths[iColumn]; |
---|
[706] | 2121 | CoinMemcpyN(rows+iStart,length,newIndex+numberElements); |
---|
| 2122 | CoinMemcpyN(elements+iStart,length,newElements+numberElements); |
---|
[653] | 2123 | numberElements += length; |
---|
| 2124 | newStarts[iColumn+1]=numberElements; |
---|
[225] | 2125 | } |
---|
[653] | 2126 | addColumns(number, columnLower, columnUpper,objIn, |
---|
| 2127 | newStarts,newIndex,newElements); |
---|
| 2128 | delete [] newStarts; |
---|
| 2129 | delete [] newIndex; |
---|
| 2130 | delete [] newElements; |
---|
[225] | 2131 | } |
---|
| 2132 | } |
---|
[653] | 2133 | #ifndef CLP_NO_VECTOR |
---|
[225] | 2134 | void |
---|
| 2135 | ClpModel::addColumns(int number, const double * columnLower, |
---|
| 2136 | const double * columnUpper, |
---|
| 2137 | const double * objIn, |
---|
[169] | 2138 | const CoinPackedVectorBase * const * columns) |
---|
| 2139 | { |
---|
| 2140 | if (!number) |
---|
| 2141 | return; |
---|
[472] | 2142 | whatsChanged_ &= ~(1+2+4+64+128+256); // all except rows changed |
---|
[169] | 2143 | int numberColumnsNow = numberColumns_; |
---|
| 2144 | resize(numberRows_,numberColumnsNow+number); |
---|
| 2145 | double * lower = columnLower_+numberColumnsNow; |
---|
| 2146 | double * upper = columnUpper_+numberColumnsNow; |
---|
| 2147 | double * obj = objective()+numberColumnsNow; |
---|
| 2148 | int iColumn; |
---|
| 2149 | if (columnLower) { |
---|
| 2150 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
| 2151 | double value = columnLower[iColumn]; |
---|
| 2152 | if (value<-1.0e20) |
---|
| 2153 | value = -COIN_DBL_MAX; |
---|
| 2154 | lower[iColumn]= value; |
---|
| 2155 | } |
---|
| 2156 | } else { |
---|
| 2157 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
| 2158 | lower[iColumn]= 0.0; |
---|
| 2159 | } |
---|
| 2160 | } |
---|
| 2161 | if (columnUpper) { |
---|
| 2162 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
| 2163 | double value = columnUpper[iColumn]; |
---|
| 2164 | if (value>1.0e20) |
---|
| 2165 | value = COIN_DBL_MAX; |
---|
| 2166 | upper[iColumn]= value; |
---|
| 2167 | } |
---|
| 2168 | } else { |
---|
| 2169 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
| 2170 | upper[iColumn]= COIN_DBL_MAX; |
---|
| 2171 | } |
---|
| 2172 | } |
---|
| 2173 | if (objIn) { |
---|
| 2174 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
| 2175 | obj[iColumn] = objIn[iColumn]; |
---|
| 2176 | } |
---|
| 2177 | } else { |
---|
| 2178 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
| 2179 | obj[iColumn]= 0.0; |
---|
| 2180 | } |
---|
| 2181 | } |
---|
| 2182 | // Deal with matrix |
---|
| 2183 | |
---|
| 2184 | delete rowCopy_; |
---|
| 2185 | rowCopy_=NULL; |
---|
[1150] | 2186 | delete scaledMatrix_; |
---|
| 2187 | scaledMatrix_=NULL; |
---|
[169] | 2188 | if (!matrix_) |
---|
| 2189 | createEmptyMatrix(); |
---|
[557] | 2190 | if (columns) |
---|
| 2191 | matrix_->appendCols(number,columns); |
---|
[1147] | 2192 | setRowScale(NULL); |
---|
| 2193 | setColumnScale(NULL); |
---|
[648] | 2194 | if (lengthNames_) { |
---|
| 2195 | columnNames_.resize(numberColumns_); |
---|
| 2196 | } |
---|
[169] | 2197 | } |
---|
[653] | 2198 | #endif |
---|
[650] | 2199 | #ifndef SLIM_CLP |
---|
[545] | 2200 | // Add columns from a build object |
---|
[577] | 2201 | int |
---|
| 2202 | ClpModel::addColumns(const CoinBuild & buildObject,bool tryPlusMinusOne,bool checkDuplicates) |
---|
[545] | 2203 | { |
---|
[560] | 2204 | CoinAssertHint (buildObject.type()==1,"Looks as if both addRows and addCols being used"); // check correct |
---|
[545] | 2205 | int number = buildObject.numberColumns(); |
---|
[577] | 2206 | int numberErrors=0; |
---|
[545] | 2207 | if (number) { |
---|
[558] | 2208 | CoinBigIndex size=0; |
---|
| 2209 | int maximumLength=0; |
---|
[557] | 2210 | double * lower = new double [number]; |
---|
| 2211 | double * upper = new double [number]; |
---|
[545] | 2212 | int iColumn; |
---|
| 2213 | double * objective = new double [number]; |
---|
[559] | 2214 | if ((!matrix_||!matrix_->getNumElements())&&tryPlusMinusOne) { |
---|
[557] | 2215 | // See if can be +-1 |
---|
| 2216 | for (iColumn=0;iColumn<number;iColumn++) { |
---|
| 2217 | const int * rows; |
---|
| 2218 | const double * elements; |
---|
| 2219 | int numberElements = buildObject.column(iColumn,lower[iColumn], |
---|
| 2220 | upper[iColumn],objective[iColumn], |
---|
| 2221 | rows,elements); |
---|
| 2222 | maximumLength = CoinMax(maximumLength,numberElements); |
---|
| 2223 | for (int i=0;i<numberElements;i++) { |
---|
| 2224 | // allow for zero elements |
---|
| 2225 | if (elements[i]) { |
---|
| 2226 | if (fabs(elements[i])==1.0) { |
---|
| 2227 | size++; |
---|
| 2228 | } else { |
---|
| 2229 | // bad |
---|
| 2230 | tryPlusMinusOne=false; |
---|
| 2231 | } |
---|
| 2232 | } |
---|
| 2233 | } |
---|
| 2234 | if (!tryPlusMinusOne) |
---|
| 2235 | break; |
---|
| 2236 | } |
---|
| 2237 | } else { |
---|
| 2238 | // Will add to whatever sort of matrix exists |
---|
| 2239 | tryPlusMinusOne=false; |
---|
[545] | 2240 | } |
---|
[557] | 2241 | if (!tryPlusMinusOne) { |
---|
[577] | 2242 | CoinBigIndex numberElements = buildObject.numberElements(); |
---|
| 2243 | CoinBigIndex * starts = new CoinBigIndex [number+1]; |
---|
| 2244 | int * row = new int[numberElements]; |
---|
| 2245 | double * element = new double[numberElements]; |
---|
| 2246 | starts[0]=0; |
---|
| 2247 | numberElements=0; |
---|
| 2248 | for (iColumn=0;iColumn<number;iColumn++) { |
---|
| 2249 | const int * rows; |
---|
| 2250 | const double * elements; |
---|
| 2251 | int numberElementsThis = buildObject.column(iColumn,lower[iColumn],upper[iColumn], |
---|
| 2252 | objective[iColumn],rows,elements); |
---|
| 2253 | CoinMemcpyN(rows,numberElementsThis,row+numberElements); |
---|
| 2254 | CoinMemcpyN(elements,numberElementsThis,element+numberElements); |
---|
| 2255 | numberElements += numberElementsThis; |
---|
| 2256 | starts[iColumn+1]=numberElements; |
---|
| 2257 | } |
---|
| 2258 | addColumns(number, lower, upper,objective,NULL); |
---|
| 2259 | // make sure matrix has enough rows |
---|
| 2260 | matrix_->setDimensions(numberRows_,-1); |
---|
| 2261 | numberErrors=matrix_->appendMatrix(number,1,starts,row,element, |
---|
| 2262 | checkDuplicates ? numberRows_ : -1); |
---|
| 2263 | delete [] starts; |
---|
| 2264 | delete [] row; |
---|
| 2265 | delete [] element; |
---|
| 2266 | } else { |
---|
| 2267 | // arrays already filled in |
---|
| 2268 | addColumns(number, lower, upper,objective,NULL); |
---|
| 2269 | char * which=NULL; // for duplicates |
---|
| 2270 | if (checkDuplicates) { |
---|
| 2271 | which = new char[numberRows_]; |
---|
[706] | 2272 | CoinZeroN(which,numberRows_); |
---|
[577] | 2273 | } |
---|
| 2274 | // build +-1 matrix |
---|
| 2275 | CoinBigIndex * startPositive = new CoinBigIndex [number+1]; |
---|
| 2276 | CoinBigIndex * startNegative = new CoinBigIndex [number]; |
---|
| 2277 | int * indices = new int [size]; |
---|
| 2278 | int * neg = new int[maximumLength]; |
---|
| 2279 | startPositive[0]=0; |
---|
| 2280 | size=0; |
---|
| 2281 | int maxRow=-1; |
---|
| 2282 | for (iColumn=0;iColumn<number;iColumn++) { |
---|
| 2283 | const int * rows; |
---|
| 2284 | const double * elements; |
---|
| 2285 | int numberElements = buildObject.column(iColumn,lower[iColumn], |
---|
| 2286 | upper[iColumn],objective[iColumn], |
---|
| 2287 | rows,elements); |
---|
| 2288 | int nNeg=0; |
---|
| 2289 | CoinBigIndex start = size; |
---|
| 2290 | for (int i=0;i<numberElements;i++) { |
---|
| 2291 | int iRow=rows[i]; |
---|
| 2292 | if (checkDuplicates) { |
---|
| 2293 | if (iRow>=numberRows_) { |
---|
| 2294 | if(which[iRow]) |
---|
| 2295 | numberErrors++; |
---|
| 2296 | else |
---|
| 2297 | which[iRow]=1; |
---|
| 2298 | } else { |
---|
| 2299 | numberErrors++; |
---|
| 2300 | // and may as well switch off |
---|
| 2301 | checkDuplicates=false; |
---|
| 2302 | } |
---|
| 2303 | } |
---|
| 2304 | maxRow = CoinMax(maxRow,iRow); |
---|
| 2305 | if (elements[i]==1.0) { |
---|
| 2306 | indices[size++]=iRow; |
---|
| 2307 | } else if (elements[i]==-1.0) { |
---|
| 2308 | neg[nNeg++]=iRow; |
---|
| 2309 | } |
---|
| 2310 | } |
---|
| 2311 | std::sort(indices+start,indices+size); |
---|
| 2312 | std::sort(neg,neg+nNeg); |
---|
| 2313 | startNegative[iColumn]=size; |
---|
[706] | 2314 | CoinMemcpyN(neg,nNeg,indices+size); |
---|
[577] | 2315 | size += nNeg; |
---|
| 2316 | startPositive[iColumn+1]=size; |
---|
| 2317 | } |
---|
| 2318 | delete [] neg; |
---|
| 2319 | // check size |
---|
| 2320 | assert (maxRow+1<=numberRows_); |
---|
| 2321 | // Get good object |
---|
| 2322 | delete matrix_; |
---|
| 2323 | ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix(); |
---|
| 2324 | matrix->passInCopy(numberRows_,number,true,indices,startPositive,startNegative); |
---|
| 2325 | matrix_=matrix; |
---|
| 2326 | delete [] which; |
---|
| 2327 | } |
---|
| 2328 | delete [] objective; |
---|
| 2329 | delete [] lower; |
---|
| 2330 | delete [] upper; |
---|
| 2331 | } |
---|
| 2332 | return 0; |
---|
| 2333 | } |
---|
[650] | 2334 | #endif |
---|
[651] | 2335 | #ifndef SLIM_NOIO |
---|
[577] | 2336 | // Add columns from a model object |
---|
| 2337 | int |
---|
[580] | 2338 | ClpModel::addColumns( CoinModel & modelObject,bool tryPlusMinusOne,bool checkDuplicates) |
---|
[577] | 2339 | { |
---|
[618] | 2340 | if (modelObject.numberElements()==0) |
---|
| 2341 | return 0; |
---|
[577] | 2342 | bool goodState=true; |
---|
| 2343 | if (modelObject.rowLowerArray()) { |
---|
| 2344 | // some row information exists |
---|
| 2345 | int numberRows2 = modelObject.numberRows(); |
---|
| 2346 | const double * rowLower = modelObject.rowLowerArray(); |
---|
| 2347 | const double * rowUpper = modelObject.rowUpperArray(); |
---|
| 2348 | for (int i=0;i<numberRows2;i++) { |
---|
| 2349 | if (rowLower[i]!=-COIN_DBL_MAX) |
---|
| 2350 | goodState=false; |
---|
| 2351 | if (rowUpper[i]!=COIN_DBL_MAX) |
---|
| 2352 | goodState=false; |
---|
| 2353 | } |
---|
| 2354 | } |
---|
| 2355 | if (goodState) { |
---|
| 2356 | // can do addColumns |
---|
| 2357 | int numberErrors = 0; |
---|
| 2358 | // Set arrays for normal use |
---|
| 2359 | double * rowLower = modelObject.rowLowerArray(); |
---|
| 2360 | double * rowUpper = modelObject.rowUpperArray(); |
---|
| 2361 | double * columnLower = modelObject.columnLowerArray(); |
---|
| 2362 | double * columnUpper = modelObject.columnUpperArray(); |
---|
| 2363 | double * objective = modelObject.objectiveArray(); |
---|
| 2364 | int * integerType = modelObject.integerTypeArray(); |
---|
| 2365 | double * associated = modelObject.associatedArray(); |
---|
| 2366 | // If strings then do copies |
---|
| 2367 | if (modelObject.stringsExist()) { |
---|
| 2368 | numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper, |
---|
| 2369 | objective, integerType,associated); |
---|
| 2370 | } |
---|
| 2371 | int numberColumns = numberColumns_; // save number of columns |
---|
| 2372 | int numberColumns2 = modelObject.numberColumns(); |
---|
| 2373 | if (numberColumns2&&!numberErrors) { |
---|
| 2374 | CoinBigIndex * startPositive = NULL; |
---|
| 2375 | CoinBigIndex * startNegative = NULL; |
---|
| 2376 | if ((!matrix_||!matrix_->getNumElements())&&!numberColumns&&tryPlusMinusOne) { |
---|
| 2377 | startPositive = new CoinBigIndex[numberColumns2+1]; |
---|
| 2378 | startNegative = new CoinBigIndex[numberColumns2]; |
---|
| 2379 | modelObject.countPlusMinusOne(startPositive,startNegative,associated); |
---|
| 2380 | if (startPositive[0]<0) { |
---|
| 2381 | // no good |
---|
| 2382 | tryPlusMinusOne=false; |
---|
| 2383 | delete [] startPositive; |
---|
| 2384 | delete [] startNegative; |
---|
| 2385 | } |
---|
| 2386 | } else { |
---|
| 2387 | // Will add to whatever sort of matrix exists |
---|
| 2388 | tryPlusMinusOne=false; |
---|
| 2389 | } |
---|
| 2390 | assert (columnLower); |
---|
[653] | 2391 | addColumns(numberColumns2, columnLower, columnUpper,objective, NULL,NULL,NULL); |
---|
[650] | 2392 | #ifndef SLIM_CLP |
---|
[577] | 2393 | if (!tryPlusMinusOne) { |
---|
[650] | 2394 | #endif |
---|
[577] | 2395 | CoinPackedMatrix matrix; |
---|
| 2396 | modelObject.createPackedMatrix(matrix,associated); |
---|
| 2397 | assert (!matrix.getExtraGap()); |
---|
| 2398 | if (matrix_->getNumCols()) { |
---|
| 2399 | const int * row = matrix.getIndices(); |
---|
| 2400 | //const int * columnLength = matrix.getVectorLengths(); |
---|
| 2401 | const CoinBigIndex * columnStart = matrix.getVectorStarts(); |
---|
| 2402 | const double * element = matrix.getElements(); |
---|
| 2403 | // make sure matrix has enough rows |
---|
| 2404 | matrix_->setDimensions(numberRows_,-1); |
---|
| 2405 | numberErrors+=matrix_->appendMatrix(numberColumns2,1,columnStart,row,element, |
---|
| 2406 | checkDuplicates ? numberRows_ : -1); |
---|
| 2407 | } else { |
---|
| 2408 | delete matrix_; |
---|
| 2409 | matrix_ = new ClpPackedMatrix(matrix); |
---|
| 2410 | } |
---|
[650] | 2411 | #ifndef SLIM_CLP |
---|
[577] | 2412 | } else { |
---|
| 2413 | // create +-1 matrix |
---|
| 2414 | CoinBigIndex size = startPositive[numberColumns2]; |
---|
| 2415 | int * indices = new int[size]; |
---|
| 2416 | modelObject.createPlusMinusOne(startPositive,startNegative,indices, |
---|
| 2417 | associated); |
---|
| 2418 | // Get good object |
---|
| 2419 | ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix(); |
---|
| 2420 | matrix->passInCopy(numberRows_,numberColumns2, |
---|
| 2421 | true,indices,startPositive,startNegative); |
---|
| 2422 | delete matrix_; |
---|
| 2423 | matrix_=matrix; |
---|
| 2424 | } |
---|
[650] | 2425 | #endif |
---|
[653] | 2426 | #ifndef CLP_NO_STD |
---|
[577] | 2427 | // Do names if wanted |
---|
| 2428 | if (modelObject.columnNames()->numberItems()) { |
---|
| 2429 | const char *const * columnNames=modelObject.columnNames()->names(); |
---|
| 2430 | copyColumnNames(columnNames,numberColumns,numberColumns_); |
---|
| 2431 | } |
---|
[653] | 2432 | #endif |
---|
[577] | 2433 | // Do integers if wanted |
---|
| 2434 | assert(integerType); |
---|
| 2435 | for (int iColumn=0;iColumn<numberColumns2;iColumn++) { |
---|
| 2436 | if (integerType[iColumn]) |
---|
| 2437 | setInteger(iColumn+numberColumns); |
---|
| 2438 | } |
---|
| 2439 | } |
---|
| 2440 | if (columnLower!=modelObject.columnLowerArray()) { |
---|
| 2441 | delete [] rowLower; |
---|
| 2442 | delete [] rowUpper; |
---|
| 2443 | delete [] columnLower; |
---|
| 2444 | delete [] columnUpper; |
---|
| 2445 | delete [] objective; |
---|
| 2446 | delete [] integerType; |
---|
| 2447 | delete [] associated; |
---|
| 2448 | if (numberErrors) |
---|
| 2449 | handler_->message(CLP_BAD_STRING_VALUES,messages_) |
---|
| 2450 | <<numberErrors |
---|
| 2451 | <<CoinMessageEol; |
---|
| 2452 | } |
---|
| 2453 | return numberErrors; |
---|
| 2454 | } else { |
---|
| 2455 | // not suitable for addColumns |
---|
| 2456 | handler_->message(CLP_COMPLICATED_MODEL,messages_) |
---|
| 2457 | <<modelObject.numberRows() |
---|
| 2458 | <<modelObject.numberColumns() |
---|
| 2459 | <<CoinMessageEol; |
---|
| 2460 | return -1; |
---|
| 2461 | } |
---|
| 2462 | } |
---|
[651] | 2463 | #endif |
---|
[409] | 2464 | // chgRowLower |
---|
| 2465 | void |
---|
| 2466 | ClpModel::chgRowLower(const double * rowLower) |
---|
| 2467 | { |
---|
| 2468 | int numberRows = numberRows_; |
---|
| 2469 | int iRow; |
---|
[472] | 2470 | whatsChanged_ = 0; // Use ClpSimplex stuff to keep |
---|
[409] | 2471 | if (rowLower) { |
---|
| 2472 | for (iRow = 0; iRow < numberRows; iRow++) { |
---|
| 2473 | double value = rowLower[iRow]; |
---|
| 2474 | if (value<-1.0e20) |
---|
| 2475 | value = -COIN_DBL_MAX; |
---|
| 2476 | rowLower_[iRow]= value; |
---|
| 2477 | } |
---|
| 2478 | } else { |
---|
| 2479 | for (iRow = 0; iRow < numberRows; iRow++) { |
---|
| 2480 | rowLower_[iRow]= -COIN_DBL_MAX; |
---|
| 2481 | } |
---|
| 2482 | } |
---|
| 2483 | } |
---|
| 2484 | // chgRowUpper |
---|
| 2485 | void |
---|
| 2486 | ClpModel::chgRowUpper(const double * rowUpper) |
---|
| 2487 | { |
---|
[472] | 2488 | whatsChanged_ = 0; // Use ClpSimplex stuff to keep |
---|
[409] | 2489 | int numberRows = numberRows_; |
---|
| 2490 | int iRow; |
---|
| 2491 | if (rowUpper) { |
---|
| 2492 | for (iRow = 0; iRow < numberRows; iRow++) { |
---|
| 2493 | double value = rowUpper[iRow]; |
---|
| 2494 | if (value>1.0e20) |
---|
| 2495 | value = COIN_DBL_MAX; |
---|
| 2496 | rowUpper_[iRow]= value; |
---|
| 2497 | } |
---|
| 2498 | } else { |
---|
| 2499 | for (iRow = 0; iRow < numberRows; iRow++) { |
---|
| 2500 | rowUpper_[iRow]= COIN_DBL_MAX;; |
---|
| 2501 | } |
---|
| 2502 | } |
---|
| 2503 | } |
---|
| 2504 | // chgColumnLower |
---|
| 2505 | void |
---|
| 2506 | ClpModel::chgColumnLower(const double * columnLower) |
---|
| 2507 | { |
---|
[472] | 2508 | whatsChanged_ = 0; // Use ClpSimplex stuff to keep |
---|
[409] | 2509 | int numberColumns = numberColumns_; |
---|
| 2510 | int iColumn; |
---|
| 2511 | if (columnLower) { |
---|
| 2512 | for (iColumn = 0; iColumn < numberColumns; iColumn++) { |
---|
| 2513 | double value = columnLower[iColumn]; |
---|
| 2514 | if (value<-1.0e20) |
---|
| 2515 | value = -COIN_DBL_MAX; |
---|
| 2516 | columnLower_[iColumn]= value; |
---|
| 2517 | } |
---|
| 2518 | } else { |
---|
| 2519 | for (iColumn = 0; iColumn < numberColumns; iColumn++) { |
---|
| 2520 | columnLower_[iColumn]= 0.0; |
---|
| 2521 | } |
---|
| 2522 | } |
---|
| 2523 | } |
---|
| 2524 | // chgColumnUpper |
---|
| 2525 | void |
---|
| 2526 | ClpModel::chgColumnUpper(const double * columnUpper) |
---|
| 2527 | { |
---|
[472] | 2528 | whatsChanged_ = 0; // Use ClpSimplex stuff to keep |
---|
[409] | 2529 | int numberColumns = numberColumns_; |
---|
| 2530 | int iColumn; |
---|
| 2531 | if (columnUpper) { |
---|
| 2532 | for (iColumn = 0; iColumn < numberColumns; iColumn++) { |
---|
| 2533 | double value = columnUpper[iColumn]; |
---|
| 2534 | if (value>1.0e20) |
---|
| 2535 | value = COIN_DBL_MAX; |
---|
| 2536 | columnUpper_[iColumn]= value; |
---|
| 2537 | } |
---|
| 2538 | } else { |
---|
| 2539 | for (iColumn = 0; iColumn < numberColumns; iColumn++) { |
---|
| 2540 | columnUpper_[iColumn]= COIN_DBL_MAX;; |
---|
| 2541 | } |
---|
| 2542 | } |
---|
| 2543 | } |
---|
| 2544 | // chgObjCoefficients |
---|
| 2545 | void |
---|
| 2546 | ClpModel::chgObjCoefficients(const double * objIn) |
---|
| 2547 | { |
---|
[472] | 2548 | whatsChanged_ = 0; // Use ClpSimplex stuff to keep |
---|
[409] | 2549 | double * obj = objective(); |
---|
| 2550 | int numberColumns = numberColumns_; |
---|
| 2551 | int iColumn; |
---|
| 2552 | if (objIn) { |
---|
| 2553 | for (iColumn = 0; iColumn < numberColumns; iColumn++) { |
---|
| 2554 | obj[iColumn] = objIn[iColumn]; |
---|
| 2555 | } |
---|
| 2556 | } else { |
---|
| 2557 | for (iColumn = 0; iColumn < numberColumns; iColumn++) { |
---|
| 2558 | obj[iColumn]= 0.0; |
---|
| 2559 | } |
---|
| 2560 | } |
---|
| 2561 | } |
---|
[2] | 2562 | // Infeasibility/unbounded ray (NULL returned if none/wrong) |
---|
| 2563 | double * |
---|
| 2564 | ClpModel::infeasibilityRay() const |
---|
| 2565 | { |
---|
| 2566 | double * array = NULL; |
---|
[1034] | 2567 | if (problemStatus_==1&&!secondaryStatus_) { |
---|
[50] | 2568 | array = ClpCopyOfArray(ray_,numberRows_); |
---|
[1034] | 2569 | #if 0 |
---|
| 2570 | // clean up |
---|
| 2571 | double largest=1.0e-30; |
---|
| 2572 | double smallest=COIN_DBL_MAX; |
---|
| 2573 | int i; |
---|
| 2574 | for (i=0;i<numberRows_;i++) { |
---|
| 2575 | double value = fabs(array[i]); |
---|
| 2576 | smallest = CoinMin(smallest,value); |
---|
| 2577 | largest = CoinMax(largest,value); |
---|
| 2578 | } |
---|
| 2579 | #endif |
---|
| 2580 | } |
---|
[2] | 2581 | return array; |
---|
| 2582 | } |
---|
| 2583 | double * |
---|
| 2584 | ClpModel::unboundedRay() const |
---|
| 2585 | { |
---|
| 2586 | double * array = NULL; |
---|
| 2587 | if (problemStatus_==2) |
---|
[50] | 2588 | array = ClpCopyOfArray(ray_,numberColumns_); |
---|
[2] | 2589 | return array; |
---|
| 2590 | } |
---|
| 2591 | void |
---|
| 2592 | ClpModel::setMaximumIterations(int value) |
---|
| 2593 | { |
---|
| 2594 | if(value>=0) |
---|
[82] | 2595 | intParam_[ClpMaxNumIteration]=value; |
---|
[2] | 2596 | } |
---|
[142] | 2597 | void |
---|
| 2598 | ClpModel::setMaximumSeconds(double value) |
---|
| 2599 | { |
---|
| 2600 | if(value>=0) |
---|
[225] | 2601 | dblParam_[ClpMaxSeconds]=value+CoinCpuTime(); |
---|
[142] | 2602 | else |
---|
| 2603 | dblParam_[ClpMaxSeconds]=-1.0; |
---|
| 2604 | } |
---|
| 2605 | // Returns true if hit maximum iterations (or time) |
---|
| 2606 | bool |
---|
| 2607 | ClpModel::hitMaximumIterations() const |
---|
| 2608 | { |
---|
[453] | 2609 | // replaced - compiler error? bool hitMax= (numberIterations_>=maximumIterations()); |
---|
| 2610 | bool hitMax = (numberIterations_ >= intParam_[ClpMaxNumIteration]); |
---|
[1060] | 2611 | if (dblParam_[ClpMaxSeconds]>=0.0&&!hitMax) { |
---|
[225] | 2612 | hitMax = (CoinCpuTime()>=dblParam_[ClpMaxSeconds]); |
---|
[1060] | 2613 | } |
---|
[142] | 2614 | return hitMax; |
---|
| 2615 | } |
---|
[1060] | 2616 | // On stopped - sets secondary status |
---|
| 2617 | void |
---|
| 2618 | ClpModel::onStopped() |
---|
| 2619 | { |
---|
| 2620 | if (problemStatus_==3) { |
---|
| 2621 | secondaryStatus_=0; |
---|
[1197] | 2622 | if (CoinCpuTime()>=dblParam_[ClpMaxSeconds]&&dblParam_[ClpMaxSeconds]>=0.0) |
---|
[1060] | 2623 | secondaryStatus_=9; |
---|
| 2624 | } |
---|
| 2625 | } |
---|
[2] | 2626 | // Pass in Message handler (not deleted at end) |
---|
| 2627 | void |
---|
[50] | 2628 | ClpModel::passInMessageHandler(CoinMessageHandler * handler) |
---|
[2] | 2629 | { |
---|
[72] | 2630 | if (defaultHandler_) |
---|
| 2631 | delete handler_; |
---|
[2] | 2632 | defaultHandler_=false; |
---|
| 2633 | handler_=handler; |
---|
| 2634 | } |
---|
[356] | 2635 | // Pass in Message handler (not deleted at end) and return current |
---|
| 2636 | CoinMessageHandler * |
---|
| 2637 | ClpModel::pushMessageHandler(CoinMessageHandler * handler, |
---|
| 2638 | bool & oldDefault) |
---|
| 2639 | { |
---|
| 2640 | CoinMessageHandler * returnValue = handler_; |
---|
| 2641 | oldDefault = defaultHandler_; |
---|
| 2642 | defaultHandler_=false; |
---|
| 2643 | handler_=handler; |
---|
| 2644 | return returnValue; |
---|
| 2645 | } |
---|
| 2646 | // back to previous message handler |
---|
| 2647 | void |
---|
| 2648 | ClpModel::popMessageHandler(CoinMessageHandler * oldHandler,bool oldDefault) |
---|
| 2649 | { |
---|
| 2650 | if (defaultHandler_) |
---|
| 2651 | delete handler_; |
---|
| 2652 | defaultHandler_=oldDefault; |
---|
| 2653 | handler_=oldHandler; |
---|
| 2654 | } |
---|
[2] | 2655 | // Set language |
---|
| 2656 | void |
---|
[50] | 2657 | ClpModel::newLanguage(CoinMessages::Language language) |
---|
[2] | 2658 | { |
---|
| 2659 | messages_ = ClpMessage(language); |
---|
| 2660 | } |
---|
[651] | 2661 | #ifndef SLIM_NOIO |
---|
[2] | 2662 | // Read an mps file from the given filename |
---|
| 2663 | int |
---|
| 2664 | ClpModel::readMps(const char *fileName, |
---|
| 2665 | bool keepNames, |
---|
| 2666 | bool ignoreErrors) |
---|
| 2667 | { |
---|
[150] | 2668 | if (!strcmp(fileName,"-")||!strcmp(fileName,"stdin")) { |
---|
[2] | 2669 | // stdin |
---|
| 2670 | } else { |
---|
[603] | 2671 | std::string name=fileName; |
---|
| 2672 | bool readable = fileCoinReadable(name); |
---|
[601] | 2673 | if (!readable) { |
---|
[2] | 2674 | handler_->message(CLP_UNABLE_OPEN,messages_) |
---|
[50] | 2675 | <<fileName<<CoinMessageEol; |
---|
[2] | 2676 | return -1; |
---|
| 2677 | } |
---|
| 2678 | } |
---|
[50] | 2679 | CoinMpsIO m; |
---|
[242] | 2680 | m.passInMessageHandler(handler_); |
---|
[701] | 2681 | *m.messagesPointer()=coinMessages(); |
---|
[225] | 2682 | bool savePrefix =m.messageHandler()->prefix(); |
---|
| 2683 | m.messageHandler()->setPrefix(handler_->prefix()); |
---|
| 2684 | double time1 = CoinCpuTime(),time2; |
---|
[608] | 2685 | int status=0; |
---|
| 2686 | try { |
---|
| 2687 | status=m.readMps(fileName,""); |
---|
| 2688 | } |
---|
| 2689 | catch (CoinError e) { |
---|
| 2690 | e.print(); |
---|
| 2691 | status=-1; |
---|
| 2692 | } |
---|
[225] | 2693 | m.messageHandler()->setPrefix(savePrefix); |
---|
[1034] | 2694 | if (!status||(ignoreErrors&&(status>0&&status<100000))) { |
---|
[2] | 2695 | loadProblem(*m.getMatrixByCol(), |
---|
| 2696 | m.getColLower(),m.getColUpper(), |
---|
| 2697 | m.getObjCoefficients(), |
---|
| 2698 | m.getRowLower(),m.getRowUpper()); |
---|
[50] | 2699 | if (m.integerColumns()) { |
---|
| 2700 | integerType_ = new char[numberColumns_]; |
---|
[706] | 2701 | CoinMemcpyN(m.integerColumns(),numberColumns_,integerType_); |
---|
[50] | 2702 | } else { |
---|
| 2703 | integerType_ = NULL; |
---|
| 2704 | } |
---|
[651] | 2705 | #ifndef SLIM_CLP |
---|
[389] | 2706 | // get quadratic part |
---|
| 2707 | if (m.reader()->whichSection ( ) == COIN_QUAD_SECTION ) { |
---|
| 2708 | int * start=NULL; |
---|
| 2709 | int * column = NULL; |
---|
| 2710 | double * element = NULL; |
---|
| 2711 | status=m.readQuadraticMps(NULL,start,column,element,2); |
---|
| 2712 | if (!status||ignoreErrors) |
---|
| 2713 | loadQuadraticObjective(numberColumns_,start,column,element); |
---|
| 2714 | delete [] start; |
---|
| 2715 | delete [] column; |
---|
| 2716 | delete [] element; |
---|
| 2717 | } |
---|
[653] | 2718 | #endif |
---|
| 2719 | #ifndef CLP_NO_STD |
---|
[50] | 2720 | // set problem name |
---|
| 2721 | setStrParam(ClpProbName,m.getProblemName()); |
---|
[2] | 2722 | // do names |
---|
| 2723 | if (keepNames) { |
---|
| 2724 | unsigned int maxLength=0; |
---|
| 2725 | int iRow; |
---|
[225] | 2726 | rowNames_ = std::vector<std::string> (); |
---|
| 2727 | columnNames_ = std::vector<std::string> (); |
---|
[2] | 2728 | rowNames_.reserve(numberRows_); |
---|
| 2729 | for (iRow=0;iRow<numberRows_;iRow++) { |
---|
| 2730 | const char * name = m.rowName(iRow); |
---|
[399] | 2731 | maxLength = CoinMax(maxLength,(unsigned int) strlen(name)); |
---|
[2] | 2732 | rowNames_.push_back(name); |
---|
| 2733 | } |
---|
| 2734 | |
---|
| 2735 | int iColumn; |
---|
| 2736 | columnNames_.reserve(numberColumns_); |
---|
| 2737 | for (iColumn=0;iColumn<numberColumns_;iColumn++) { |
---|
| 2738 | const char * name = m.columnName(iColumn); |
---|
[399] | 2739 | maxLength = CoinMax(maxLength,(unsigned int) strlen(name)); |
---|
[2] | 2740 | columnNames_.push_back(name); |
---|
| 2741 | } |
---|
| 2742 | lengthNames_=(int) maxLength; |
---|
| 2743 | } else { |
---|
| 2744 | lengthNames_=0; |
---|
| 2745 | } |
---|
[653] | 2746 | #endif |
---|
[50] | 2747 | setDblParam(ClpObjOffset,m.objectiveOffset()); |
---|
[225] | 2748 | time2 = CoinCpuTime(); |
---|
[2] | 2749 | handler_->message(CLP_IMPORT_RESULT,messages_) |
---|
| 2750 | <<fileName |
---|
[50] | 2751 | <<time2-time1<<CoinMessageEol; |
---|
[2] | 2752 | } else { |
---|
| 2753 | // errors |
---|
| 2754 | handler_->message(CLP_IMPORT_ERRORS,messages_) |
---|
[50] | 2755 | <<status<<fileName<<CoinMessageEol; |
---|
[2] | 2756 | } |
---|
| 2757 | |
---|
| 2758 | return status; |
---|
| 2759 | } |
---|
[575] | 2760 | // Read GMPL files from the given filenames |
---|
| 2761 | int |
---|
| 2762 | ClpModel::readGMPL(const char *fileName,const char * dataName, |
---|
| 2763 | bool keepNames) |
---|
| 2764 | { |
---|
| 2765 | FILE *fp=fopen(fileName,"r"); |
---|
| 2766 | if (fp) { |
---|
| 2767 | // can open - lets go for it |
---|
| 2768 | fclose(fp); |
---|
| 2769 | if (dataName) { |
---|
| 2770 | fp=fopen(dataName,"r"); |
---|
| 2771 | if (fp) { |
---|
| 2772 | fclose(fp); |
---|
| 2773 | } else { |
---|
| 2774 | handler_->message(CLP_UNABLE_OPEN,messages_) |
---|
| 2775 | <<dataName<<CoinMessageEol; |
---|
| 2776 | return -1; |
---|
| 2777 | } |
---|
| 2778 | } |
---|
| 2779 | } else { |
---|
| 2780 | handler_->message(CLP_UNABLE_OPEN,messages_) |
---|
| 2781 | <<fileName<<CoinMessageEol; |
---|
| 2782 | return -1; |
---|
| 2783 | } |
---|
| 2784 | CoinMpsIO m; |
---|
| 2785 | m.passInMessageHandler(handler_); |
---|
[701] | 2786 | *m.messagesPointer()=coinMessages(); |
---|
[575] | 2787 | bool savePrefix =m.messageHandler()->prefix(); |
---|
| 2788 | m.messageHandler()->setPrefix(handler_->prefix()); |
---|
| 2789 | double time1 = CoinCpuTime(),time2; |
---|
| 2790 | int status=m.readGMPL(fileName,dataName,keepNames); |
---|
| 2791 | m.messageHandler()->setPrefix(savePrefix); |
---|
| 2792 | if (!status) { |
---|
| 2793 | loadProblem(*m.getMatrixByCol(), |
---|
| 2794 | m.getColLower(),m.getColUpper(), |
---|
| 2795 | m.getObjCoefficients(), |
---|
| 2796 | m.getRowLower(),m.getRowUpper()); |
---|
| 2797 | if (m.integerColumns()) { |
---|
| 2798 | integerType_ = new char[numberColumns_]; |
---|
[706] | 2799 | CoinMemcpyN(m.integerColumns(),numberColumns_,integerType_); |
---|
[575] | 2800 | } else { |
---|
| 2801 | integerType_ = NULL; |
---|
| 2802 | } |
---|
[653] | 2803 | #ifndef CLP_NO_STD |
---|
[575] | 2804 | // set problem name |
---|
| 2805 | setStrParam(ClpProbName,m.getProblemName()); |
---|
| 2806 | // do names |
---|
| 2807 | if (keepNames) { |
---|
| 2808 | unsigned int maxLength=0; |
---|
| 2809 | int iRow; |
---|
| 2810 | rowNames_ = std::vector<std::string> (); |
---|
| 2811 | columnNames_ = std::vector<std::string> (); |
---|
| 2812 | rowNames_.reserve(numberRows_); |
---|
| 2813 | for (iRow=0;iRow<numberRows_;iRow++) { |
---|
| 2814 | const char * name = m.rowName(iRow); |
---|
| 2815 | maxLength = CoinMax(maxLength,(unsigned int) strlen(name)); |
---|
| 2816 | rowNames_.push_back(name); |
---|
| 2817 | } |
---|
| 2818 | |
---|
| 2819 | int iColumn; |
---|
| 2820 | columnNames_.reserve(numberColumns_); |
---|
| 2821 | for (iColumn=0;iColumn<numberColumns_;iColumn++) { |
---|
| 2822 | const char * name = m.columnName(iColumn); |
---|
| 2823 | maxLength = CoinMax(maxLength,(unsigned int) strlen(name)); |
---|
| 2824 | columnNames_.push_back(name); |
---|
| 2825 | } |
---|
| 2826 | lengthNames_=(int) maxLength; |
---|
| 2827 | } else { |
---|
| 2828 | lengthNames_=0; |
---|
| 2829 | } |
---|
[653] | 2830 | #endif |
---|
[575] | 2831 | setDblParam(ClpObjOffset,m.objectiveOffset()); |
---|
| 2832 | time2 = CoinCpuTime(); |
---|
| 2833 | handler_->message(CLP_IMPORT_RESULT,messages_) |
---|
| 2834 | <<fileName |
---|
| 2835 | <<time2-time1<<CoinMessageEol; |
---|
| 2836 | } else { |
---|
| 2837 | // errors |
---|
| 2838 | handler_->message(CLP_IMPORT_ERRORS,messages_) |
---|
| 2839 | <<status<<fileName<<CoinMessageEol; |
---|
| 2840 | } |
---|
| 2841 | return status; |
---|
| 2842 | } |
---|
[651] | 2843 | #endif |
---|
[50] | 2844 | bool ClpModel::isPrimalObjectiveLimitReached() const |
---|
| 2845 | { |
---|
| 2846 | double limit = 0.0; |
---|
| 2847 | getDblParam(ClpPrimalObjectiveLimit, limit); |
---|
| 2848 | if (limit > 1e30) { |
---|
| 2849 | // was not ever set |
---|
| 2850 | return false; |
---|
| 2851 | } |
---|
| 2852 | |
---|
| 2853 | const double obj = objectiveValue(); |
---|
[225] | 2854 | const double maxmin = optimizationDirection(); |
---|
[50] | 2855 | |
---|
| 2856 | if (problemStatus_ == 0) // optimal |
---|
[254] | 2857 | return maxmin > 0 ? (obj < limit) /*minim*/ : (-obj < limit) /*maxim*/; |
---|
[50] | 2858 | else if (problemStatus_==2) |
---|
| 2859 | return true; |
---|
| 2860 | else |
---|
| 2861 | return false; |
---|
| 2862 | } |
---|
| 2863 | |
---|
| 2864 | bool ClpModel::isDualObjectiveLimitReached() const |
---|
| 2865 | { |
---|
| 2866 | |
---|
| 2867 | double limit = 0.0; |
---|
| 2868 | getDblParam(ClpDualObjectiveLimit, limit); |
---|
| 2869 | if (limit > 1e30) { |
---|
| 2870 | // was not ever set |
---|
| 2871 | return false; |
---|
| 2872 | } |
---|
| 2873 | |
---|
| 2874 | const double obj = objectiveValue(); |
---|
[225] | 2875 | const double maxmin = optimizationDirection(); |
---|
[50] | 2876 | |
---|
| 2877 | if (problemStatus_ == 0) // optimal |
---|
[254] | 2878 | return maxmin > 0 ? (obj > limit) /*minim*/ : (-obj > limit) /*maxim*/; |
---|
[50] | 2879 | else if (problemStatus_==1) |
---|
| 2880 | return true; |
---|
| 2881 | else |
---|
| 2882 | return false; |
---|
| 2883 | |
---|
| 2884 | } |
---|
| 2885 | void |
---|
| 2886 | ClpModel::copyInIntegerInformation(const char * information) |
---|
| 2887 | { |
---|
| 2888 | delete [] integerType_; |
---|
| 2889 | if (information) { |
---|
| 2890 | integerType_ = new char[numberColumns_]; |
---|
[706] | 2891 | CoinMemcpyN(information,numberColumns_,integerType_); |
---|
[50] | 2892 | } else { |
---|
| 2893 | integerType_ = NULL; |
---|
| 2894 | } |
---|
| 2895 | } |
---|
[537] | 2896 | void |
---|
| 2897 | ClpModel::setContinuous(int index) |
---|
| 2898 | { |
---|
| 2899 | |
---|
| 2900 | if (integerType_) { |
---|
| 2901 | #ifndef NDEBUG |
---|
| 2902 | if (index<0||index>=numberColumns_) { |
---|
| 2903 | indexError(index,"setContinuous"); |
---|
| 2904 | } |
---|
| 2905 | #endif |
---|
| 2906 | integerType_[index]=0; |
---|
| 2907 | } |
---|
| 2908 | } |
---|
| 2909 | //----------------------------------------------------------------------------- |
---|
| 2910 | void |
---|
| 2911 | ClpModel::setInteger(int index) |
---|
| 2912 | { |
---|
| 2913 | if (!integerType_) { |
---|
| 2914 | integerType_ = new char[numberColumns_]; |
---|
[706] | 2915 | CoinZeroN ( integerType_, numberColumns_); |
---|
[537] | 2916 | } |
---|
| 2917 | #ifndef NDEBUG |
---|
| 2918 | if (index<0||index>=numberColumns_) { |
---|
| 2919 | indexError(index,"setInteger"); |
---|
| 2920 | } |
---|
| 2921 | #endif |
---|
| 2922 | integerType_[index]=1; |
---|
| 2923 | } |
---|
[627] | 2924 | /* Return true if the index-th variable is an integer variable */ |
---|
| 2925 | bool |
---|
| 2926 | ClpModel::isInteger(int index) const |
---|
| 2927 | { |
---|
| 2928 | if (!integerType_) { |
---|
| 2929 | return false; |
---|
| 2930 | } else { |
---|
| 2931 | #ifndef NDEBUG |
---|
| 2932 | if (index<0||index>=numberColumns_) { |
---|
| 2933 | indexError(index,"isInteger"); |
---|
| 2934 | } |
---|
| 2935 | #endif |
---|
| 2936 | return (integerType_[index]!=0); |
---|
| 2937 | } |
---|
| 2938 | } |
---|
[653] | 2939 | #ifndef CLP_NO_STD |
---|
[50] | 2940 | // Drops names - makes lengthnames 0 and names empty |
---|
| 2941 | void |
---|
| 2942 | ClpModel::dropNames() |
---|
| 2943 | { |
---|
| 2944 | lengthNames_=0; |
---|
| 2945 | rowNames_ = std::vector<std::string> (); |
---|
| 2946 | columnNames_ = std::vector<std::string> (); |
---|
| 2947 | } |
---|
[653] | 2948 | #endif |
---|
[50] | 2949 | // Drop integer informations |
---|
| 2950 | void |
---|
| 2951 | ClpModel::deleteIntegerInformation() |
---|
| 2952 | { |
---|
| 2953 | delete [] integerType_; |
---|
| 2954 | integerType_ = NULL; |
---|
| 2955 | } |
---|
| 2956 | /* Return copy of status array (char[numberRows+numberColumns]), |
---|
| 2957 | use delete [] */ |
---|
| 2958 | unsigned char * |
---|
| 2959 | ClpModel::statusCopy() const |
---|
| 2960 | { |
---|
| 2961 | return ClpCopyOfArray(status_,numberRows_+numberColumns_); |
---|
| 2962 | } |
---|
| 2963 | // Copy in status vector |
---|
| 2964 | void |
---|
| 2965 | ClpModel::copyinStatus(const unsigned char * statusArray) |
---|
| 2966 | { |
---|
| 2967 | delete [] status_; |
---|
| 2968 | if (statusArray) { |
---|
| 2969 | status_ = new unsigned char [numberRows_+numberColumns_]; |
---|
[1197] | 2970 | CoinMemcpyN(statusArray,(numberRows_+numberColumns_),status_); |
---|
[50] | 2971 | } else { |
---|
| 2972 | status_=NULL; |
---|
| 2973 | } |
---|
| 2974 | } |
---|
[650] | 2975 | #ifndef SLIM_CLP |
---|
[152] | 2976 | // Load up quadratic objective |
---|
| 2977 | void |
---|
| 2978 | ClpModel::loadQuadraticObjective(const int numberColumns, const CoinBigIndex * start, |
---|
| 2979 | const int * column, const double * element) |
---|
| 2980 | { |
---|
[472] | 2981 | whatsChanged_ = 0; // Use ClpSimplex stuff to keep |
---|
[560] | 2982 | CoinAssert (numberColumns==numberColumns_); |
---|
[225] | 2983 | assert ((dynamic_cast< ClpLinearObjective*>(objective_))); |
---|
| 2984 | double offset; |
---|
[393] | 2985 | ClpObjective * obj = new ClpQuadraticObjective(objective_->gradient(NULL,NULL,offset,false), |
---|
| 2986 | numberColumns, |
---|
| 2987 | start,column,element); |
---|
[225] | 2988 | delete objective_; |
---|
| 2989 | objective_ = obj; |
---|
| 2990 | |
---|
[152] | 2991 | } |
---|
| 2992 | void |
---|
| 2993 | ClpModel::loadQuadraticObjective ( const CoinPackedMatrix& matrix) |
---|
| 2994 | { |
---|
[472] | 2995 | whatsChanged_ = 0; // Use ClpSimplex stuff to keep |
---|
[560] | 2996 | CoinAssert (matrix.getNumCols()==numberColumns_); |
---|
[225] | 2997 | assert ((dynamic_cast< ClpLinearObjective*>(objective_))); |
---|
| 2998 | double offset; |
---|
| 2999 | ClpQuadraticObjective * obj = |
---|
[393] | 3000 | new ClpQuadraticObjective(objective_->gradient(NULL,NULL,offset,false), |
---|
| 3001 | numberColumns_, |
---|
| 3002 | NULL,NULL,NULL); |
---|
[225] | 3003 | delete objective_; |
---|
| 3004 | objective_ = obj; |
---|
| 3005 | obj->loadQuadraticObjective(matrix); |
---|
[152] | 3006 | } |
---|
| 3007 | // Get rid of quadratic objective |
---|
| 3008 | void |
---|
| 3009 | ClpModel::deleteQuadraticObjective() |
---|
| 3010 | { |
---|
[472] | 3011 | whatsChanged_ = 0; // Use ClpSimplex stuff to keep |
---|
[225] | 3012 | ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(objective_)); |
---|
| 3013 | if (obj) |
---|
| 3014 | obj->deleteQuadraticObjective(); |
---|
[152] | 3015 | } |
---|
[650] | 3016 | #endif |
---|
[225] | 3017 | void |
---|
| 3018 | ClpModel::setObjective(ClpObjective * objective) |
---|
| 3019 | { |
---|
[472] | 3020 | whatsChanged_ = 0; // Use ClpSimplex stuff to keep |
---|
[225] | 3021 | delete objective_; |
---|
| 3022 | objective_=objective->clone(); |
---|
| 3023 | } |
---|
| 3024 | // Returns resized array and updates size |
---|
| 3025 | double * whichDouble(double * array , int number, const int * which) |
---|
| 3026 | { |
---|
| 3027 | double * newArray=NULL; |
---|
| 3028 | if (array&&number) { |
---|
| 3029 | int i ; |
---|
| 3030 | newArray = new double[number]; |
---|
| 3031 | for (i=0;i<number;i++) |
---|
| 3032 | newArray[i]=array[which[i]]; |
---|
| 3033 | } |
---|
| 3034 | return newArray; |
---|
| 3035 | } |
---|
| 3036 | char * whichChar(char * array , int number, const int * which) |
---|
| 3037 | { |
---|
| 3038 | char * newArray=NULL; |
---|
| 3039 | if (array&&number) { |
---|
| 3040 | int i ; |
---|
| 3041 | newArray = new char[number]; |
---|
| 3042 | for (i=0;i<number;i++) |
---|
| 3043 | newArray[i]=array[which[i]]; |
---|
| 3044 | } |
---|
| 3045 | return newArray; |
---|
| 3046 | } |
---|
| 3047 | unsigned char * whichUnsignedChar(unsigned char * array , |
---|
| 3048 | int number, const int * which) |
---|
| 3049 | { |
---|
| 3050 | unsigned char * newArray=NULL; |
---|
| 3051 | if (array&&number) { |
---|
| 3052 | int i ; |
---|
| 3053 | newArray = new unsigned char[number]; |
---|
| 3054 | for (i=0;i<number;i++) |
---|
| 3055 | newArray[i]=array[which[i]]; |
---|
| 3056 | } |
---|
| 3057 | return newArray; |
---|
| 3058 | } |
---|
| 3059 | // Replace Clp Matrix (current is not deleted) |
---|
| 3060 | void |
---|
[410] | 3061 | ClpModel::replaceMatrix( ClpMatrixBase * matrix,bool deleteCurrent) |
---|
[225] | 3062 | { |
---|
[410] | 3063 | if (deleteCurrent) |
---|
| 3064 | delete matrix_; |
---|
[225] | 3065 | matrix_=matrix; |
---|
[472] | 3066 | whatsChanged_ = 0; // Too big a change |
---|
[225] | 3067 | } |
---|
| 3068 | // Subproblem constructor |
---|
| 3069 | ClpModel::ClpModel ( const ClpModel * rhs, |
---|
| 3070 | int numberRows, const int * whichRow, |
---|
| 3071 | int numberColumns, const int * whichColumn, |
---|
| 3072 | bool dropNames, bool dropIntegers) |
---|
[1147] | 3073 | : specialOptions_(rhs->specialOptions_), |
---|
| 3074 | maximumColumns_(-1), |
---|
| 3075 | maximumRows_(-1), |
---|
[1197] | 3076 | maximumInternalColumns_(-1), |
---|
| 3077 | maximumInternalRows_(-1), |
---|
[1147] | 3078 | savedRowScale_(NULL), |
---|
| 3079 | savedColumnScale_(NULL) |
---|
[225] | 3080 | { |
---|
| 3081 | defaultHandler_ = rhs->defaultHandler_; |
---|
| 3082 | if (defaultHandler_) |
---|
| 3083 | handler_ = new CoinMessageHandler(*rhs->handler_); |
---|
| 3084 | else |
---|
| 3085 | handler_ = rhs->handler_; |
---|
[344] | 3086 | eventHandler_ = rhs->eventHandler_->clone(); |
---|
[1141] | 3087 | randomNumberGenerator_ = rhs->randomNumberGenerator_; |
---|
[225] | 3088 | messages_ = rhs->messages_; |
---|
[701] | 3089 | coinMessages_ = rhs->coinMessages_; |
---|
[1147] | 3090 | maximumColumns_ = -1; |
---|
| 3091 | maximumRows_ = -1; |
---|
[1197] | 3092 | maximumInternalColumns_ = -1; |
---|
| 3093 | maximumInternalRows_ = -1; |
---|
[1147] | 3094 | savedRowScale_ = NULL; |
---|
| 3095 | savedColumnScale_ = NULL; |
---|
[225] | 3096 | intParam_[ClpMaxNumIteration] = rhs->intParam_[ClpMaxNumIteration]; |
---|
| 3097 | intParam_[ClpMaxNumIterationHotStart] = |
---|
| 3098 | rhs->intParam_[ClpMaxNumIterationHotStart]; |
---|
[1015] | 3099 | intParam_[ClpNameDiscipline] = rhs->intParam_[ClpNameDiscipline] ; |
---|
[225] | 3100 | |
---|
| 3101 | dblParam_[ClpDualObjectiveLimit] = rhs->dblParam_[ClpDualObjectiveLimit]; |
---|
| 3102 | dblParam_[ClpPrimalObjectiveLimit] = rhs->dblParam_[ClpPrimalObjectiveLimit]; |
---|
| 3103 | dblParam_[ClpDualTolerance] = rhs->dblParam_[ClpDualTolerance]; |
---|
| 3104 | dblParam_[ClpPrimalTolerance] = rhs->dblParam_[ClpPrimalTolerance]; |
---|
| 3105 | dblParam_[ClpObjOffset] = rhs->dblParam_[ClpObjOffset]; |
---|
| 3106 | dblParam_[ClpMaxSeconds] = rhs->dblParam_[ClpMaxSeconds]; |
---|
[708] | 3107 | dblParam_[ClpPresolveTolerance] = rhs->dblParam_[ClpPresolveTolerance]; |
---|
[653] | 3108 | #ifndef CLP_NO_STD |
---|
[225] | 3109 | strParam_[ClpProbName] = rhs->strParam_[ClpProbName]; |
---|
[653] | 3110 | #endif |
---|
[1034] | 3111 | specialOptions_ = rhs->specialOptions_; |
---|
[225] | 3112 | optimizationDirection_ = rhs->optimizationDirection_; |
---|
| 3113 | objectiveValue_=rhs->objectiveValue_; |
---|
| 3114 | smallElement_ = rhs->smallElement_; |
---|
[389] | 3115 | objectiveScale_ = rhs->objectiveScale_; |
---|
| 3116 | rhsScale_ = rhs->rhsScale_; |
---|
[225] | 3117 | numberIterations_ = rhs->numberIterations_; |
---|
| 3118 | solveType_ = rhs->solveType_; |
---|
[472] | 3119 | whatsChanged_ = 0; // Too big a change |
---|
[225] | 3120 | problemStatus_ = rhs->problemStatus_; |
---|
| 3121 | secondaryStatus_ = rhs->secondaryStatus_; |
---|
| 3122 | // check valid lists |
---|
| 3123 | int numberBad=0; |
---|
| 3124 | int i; |
---|
| 3125 | for (i=0;i<numberRows;i++) |
---|
| 3126 | if (whichRow[i]<0||whichRow[i]>=rhs->numberRows_) |
---|
| 3127 | numberBad++; |
---|
[561] | 3128 | CoinAssertHint(!numberBad,"Bad row list for subproblem constructor"); |
---|
[225] | 3129 | numberBad=0; |
---|
| 3130 | for (i=0;i<numberColumns;i++) |
---|
| 3131 | if (whichColumn[i]<0||whichColumn[i]>=rhs->numberColumns_) |
---|
| 3132 | numberBad++; |
---|
[561] | 3133 | CoinAssertHint(!numberBad,"Bad Column list for subproblem constructor"); |
---|
[225] | 3134 | numberRows_ = numberRows; |
---|
| 3135 | numberColumns_ = numberColumns; |
---|
[240] | 3136 | userPointer_ = rhs->userPointer_; |
---|
[740] | 3137 | numberThreads_=0; |
---|
[653] | 3138 | #ifndef CLP_NO_STD |
---|
[225] | 3139 | if (!dropNames) { |
---|
| 3140 | unsigned int maxLength=0; |
---|
| 3141 | int iRow; |
---|
| 3142 | rowNames_ = std::vector<std::string> (); |
---|
| 3143 | columnNames_ = std::vector<std::string> (); |
---|
| 3144 | rowNames_.reserve(numberRows_); |
---|
| 3145 | for (iRow=0;iRow<numberRows_;iRow++) { |
---|
[355] | 3146 | rowNames_.push_back(rhs->rowNames_[whichRow[iRow]]); |
---|
[399] | 3147 | maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames_[iRow].c_str())); |
---|
[225] | 3148 | } |
---|
| 3149 | int iColumn; |
---|
| 3150 | columnNames_.reserve(numberColumns_); |
---|
| 3151 | for (iColumn=0;iColumn<numberColumns_;iColumn++) { |
---|
[355] | 3152 | columnNames_.push_back(rhs->columnNames_[whichColumn[iColumn]]); |
---|
[399] | 3153 | maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames_[iColumn].c_str())); |
---|
[225] | 3154 | } |
---|
| 3155 | lengthNames_=(int) maxLength; |
---|
| 3156 | } else { |
---|
| 3157 | lengthNames_ = 0; |
---|
| 3158 | rowNames_ = std::vector<std::string> (); |
---|
| 3159 | columnNames_ = std::vector<std::string> (); |
---|
| 3160 | } |
---|
[653] | 3161 | #endif |
---|
[225] | 3162 | if (rhs->integerType_&&!dropIntegers) { |
---|
| 3163 | integerType_ = whichChar(rhs->integerType_,numberColumns,whichColumn); |
---|
| 3164 | } else { |
---|
| 3165 | integerType_ = NULL; |
---|
| 3166 | } |
---|
| 3167 | if (rhs->rowActivity_) { |
---|
| 3168 | rowActivity_=whichDouble(rhs->rowActivity_,numberRows,whichRow); |
---|
| 3169 | dual_=whichDouble(rhs->dual_,numberRows,whichRow); |
---|
| 3170 | columnActivity_=whichDouble(rhs->columnActivity_,numberColumns, |
---|
| 3171 | whichColumn); |
---|
| 3172 | reducedCost_=whichDouble(rhs->reducedCost_,numberColumns, |
---|
| 3173 | whichColumn); |
---|
| 3174 | } else { |
---|
| 3175 | rowActivity_=NULL; |
---|
| 3176 | columnActivity_=NULL; |
---|
| 3177 | dual_=NULL; |
---|
| 3178 | reducedCost_=NULL; |
---|
| 3179 | } |
---|
| 3180 | rowLower_=whichDouble(rhs->rowLower_,numberRows,whichRow); |
---|
| 3181 | rowUpper_=whichDouble(rhs->rowUpper_,numberRows,whichRow); |
---|
| 3182 | columnLower_=whichDouble(rhs->columnLower_,numberColumns,whichColumn); |
---|
| 3183 | columnUpper_=whichDouble(rhs->columnUpper_,numberColumns,whichColumn); |
---|
| 3184 | if (rhs->objective_) |
---|
| 3185 | objective_ = rhs->objective_->subsetClone(numberColumns,whichColumn); |
---|
| 3186 | else |
---|
| 3187 | objective_ = NULL; |
---|
| 3188 | rowObjective_=whichDouble(rhs->rowObjective_,numberRows,whichRow); |
---|
| 3189 | // status has to be done in two stages |
---|
| 3190 | status_ = new unsigned char[numberColumns_+numberRows_]; |
---|
| 3191 | unsigned char * rowStatus = whichUnsignedChar(rhs->status_+rhs->numberColumns_, |
---|
| 3192 | numberRows_,whichRow); |
---|
| 3193 | unsigned char * columnStatus = whichUnsignedChar(rhs->status_, |
---|
| 3194 | numberColumns_,whichColumn); |
---|
[706] | 3195 | CoinMemcpyN(rowStatus,numberRows_,status_+numberColumns_); |
---|
[225] | 3196 | delete [] rowStatus; |
---|
[706] | 3197 | CoinMemcpyN(columnStatus,numberColumns_,status_); |
---|
[225] | 3198 | delete [] columnStatus; |
---|
| 3199 | ray_ = NULL; |
---|
| 3200 | if (problemStatus_==1&&!secondaryStatus_) |
---|
| 3201 | ray_ = whichDouble (rhs->ray_,numberRows,whichRow); |
---|
| 3202 | else if (problemStatus_==2) |
---|
| 3203 | ray_ = whichDouble (rhs->ray_,numberColumns,whichColumn); |
---|
[372] | 3204 | rowScale_ = NULL; |
---|
| 3205 | columnScale_ = NULL; |
---|
[1197] | 3206 | inverseRowScale_ = NULL; |
---|
| 3207 | inverseColumnScale_ = NULL; |
---|
[372] | 3208 | scalingFlag_ = rhs->scalingFlag_; |
---|
[618] | 3209 | rowCopy_=NULL; |
---|
[1150] | 3210 | scaledMatrix_=NULL; |
---|
[225] | 3211 | matrix_=NULL; |
---|
| 3212 | if (rhs->matrix_) { |
---|
| 3213 | matrix_ = rhs->matrix_->subsetClone(numberRows,whichRow, |
---|
| 3214 | numberColumns,whichColumn); |
---|
| 3215 | } |
---|
[1141] | 3216 | randomNumberGenerator_.setSeed(1234567); |
---|
[225] | 3217 | } |
---|
[653] | 3218 | #ifndef CLP_NO_STD |
---|
[225] | 3219 | // Copies in names |
---|
| 3220 | void |
---|
| 3221 | ClpModel::copyNames(std::vector<std::string> & rowNames, |
---|
| 3222 | std::vector<std::string> & columnNames) |
---|
| 3223 | { |
---|
| 3224 | unsigned int maxLength=0; |
---|
| 3225 | int iRow; |
---|
| 3226 | rowNames_ = std::vector<std::string> (); |
---|
| 3227 | columnNames_ = std::vector<std::string> (); |
---|
| 3228 | rowNames_.reserve(numberRows_); |
---|
| 3229 | for (iRow=0;iRow<numberRows_;iRow++) { |
---|
[240] | 3230 | rowNames_.push_back(rowNames[iRow]); |
---|
[399] | 3231 | maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames_[iRow].c_str())); |
---|
[225] | 3232 | } |
---|
| 3233 | int iColumn; |
---|
| 3234 | columnNames_.reserve(numberColumns_); |
---|
| 3235 | for (iColumn=0;iColumn<numberColumns_;iColumn++) { |
---|
[240] | 3236 | columnNames_.push_back(columnNames[iColumn]); |
---|
[399] | 3237 | maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames_[iColumn].c_str())); |
---|
[225] | 3238 | } |
---|
| 3239 | lengthNames_=(int) maxLength; |
---|
| 3240 | } |
---|
[637] | 3241 | // Return name or Rnnnnnnn |
---|
| 3242 | std::string |
---|
| 3243 | ClpModel::getRowName(int iRow) const |
---|
| 3244 | { |
---|
| 3245 | #ifndef NDEBUG |
---|
| 3246 | if (iRow<0||iRow>=numberRows_) { |
---|
| 3247 | indexError(iRow,"getRowName"); |
---|
| 3248 | } |
---|
| 3249 | #endif |
---|
| 3250 | int size = rowNames_.size(); |
---|
| 3251 | if (size>iRow) { |
---|
| 3252 | return rowNames_[iRow]; |
---|
| 3253 | } else { |
---|
| 3254 | char name[9]; |
---|
| 3255 | sprintf(name,"R%7.7d",iRow); |
---|
| 3256 | std::string rowName(name); |
---|
| 3257 | return rowName; |
---|
| 3258 | } |
---|
| 3259 | } |
---|
| 3260 | // Set row name |
---|
| 3261 | void |
---|
| 3262 | ClpModel::setRowName(int iRow, std::string &name) |
---|
| 3263 | { |
---|
| 3264 | #ifndef NDEBUG |
---|
| 3265 | if (iRow<0||iRow>=numberRows_) { |
---|
| 3266 | indexError(iRow,"setRowName"); |
---|
| 3267 | } |
---|
| 3268 | #endif |
---|
| 3269 | unsigned int maxLength=lengthNames_; |
---|
| 3270 | int size = rowNames_.size(); |
---|
| 3271 | if (size<=iRow) |
---|
| 3272 | rowNames_.resize(iRow+1); |
---|
| 3273 | rowNames_[iRow]= name; |
---|
| 3274 | maxLength = CoinMax(maxLength,(unsigned int) strlen(name.c_str())); |
---|
| 3275 | // May be too big - but we would have to check both rows and columns to be exact |
---|
| 3276 | lengthNames_=(int) maxLength; |
---|
| 3277 | } |
---|
| 3278 | // Return name or Cnnnnnnn |
---|
| 3279 | std::string |
---|
| 3280 | ClpModel::getColumnName(int iColumn) const |
---|
| 3281 | { |
---|
| 3282 | #ifndef NDEBUG |
---|
| 3283 | if (iColumn<0||iColumn>=numberColumns_) { |
---|
| 3284 | indexError(iColumn,"getColumnName"); |
---|
| 3285 | } |
---|
| 3286 | #endif |
---|
| 3287 | int size = columnNames_.size(); |
---|
| 3288 | if (size>iColumn) { |
---|
| 3289 | return columnNames_[iColumn]; |
---|
| 3290 | } else { |
---|
| 3291 | char name[9]; |
---|
| 3292 | sprintf(name,"C%7.7d",iColumn); |
---|
| 3293 | std::string columnName(name); |
---|
| 3294 | return columnName; |
---|
| 3295 | } |
---|
| 3296 | } |
---|
| 3297 | // Set column name |
---|
| 3298 | void |
---|
| 3299 | ClpModel::setColumnName(int iColumn, std::string &name) |
---|
| 3300 | { |
---|
| 3301 | #ifndef NDEBUG |
---|
| 3302 | if (iColumn<0||iColumn>=numberColumns_) { |
---|
| 3303 | indexError(iColumn,"setColumnName"); |
---|
| 3304 | } |
---|
| 3305 | #endif |
---|
| 3306 | unsigned int maxLength=lengthNames_; |
---|
| 3307 | int size = columnNames_.size(); |
---|
| 3308 | if (size<=iColumn) |
---|
| 3309 | columnNames_.resize(iColumn+1); |
---|
| 3310 | columnNames_[iColumn]= name; |
---|
| 3311 | maxLength = CoinMax(maxLength,(unsigned int) strlen(name.c_str())); |
---|
| 3312 | // May be too big - but we would have to check both columns and columns to be exact |
---|
| 3313 | lengthNames_=(int) maxLength; |
---|
| 3314 | } |
---|
[470] | 3315 | // Copies in Row names - modifies names first .. last-1 |
---|
| 3316 | void |
---|
| 3317 | ClpModel::copyRowNames(const std::vector<std::string> & rowNames, int first, int last) |
---|
| 3318 | { |
---|
| 3319 | unsigned int maxLength=lengthNames_; |
---|
| 3320 | int size = rowNames_.size(); |
---|
| 3321 | if (size!=numberRows_) |
---|
| 3322 | rowNames_.resize(numberRows_); |
---|
| 3323 | int iRow; |
---|
| 3324 | for (iRow=first; iRow<last;iRow++) { |
---|
| 3325 | rowNames_[iRow]= rowNames[iRow-first]; |
---|
[647] | 3326 | maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames_[iRow-first].c_str())); |
---|
[470] | 3327 | } |
---|
| 3328 | // May be too big - but we would have to check both rows and columns to be exact |
---|
| 3329 | lengthNames_=(int) maxLength; |
---|
| 3330 | } |
---|
| 3331 | // Copies in Column names - modifies names first .. last-1 |
---|
| 3332 | void |
---|
| 3333 | ClpModel::copyColumnNames(const std::vector<std::string> & columnNames, int first, int last) |
---|
| 3334 | { |
---|
| 3335 | unsigned int maxLength=lengthNames_; |
---|
| 3336 | int size = columnNames_.size(); |
---|
| 3337 | if (size!=numberColumns_) |
---|
| 3338 | columnNames_.resize(numberColumns_); |
---|
| 3339 | int iColumn; |
---|
| 3340 | for (iColumn=first; iColumn<last;iColumn++) { |
---|
| 3341 | columnNames_[iColumn]= columnNames[iColumn-first]; |
---|
[647] | 3342 | maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames_[iColumn-first].c_str())); |
---|
[470] | 3343 | } |
---|
| 3344 | // May be too big - but we would have to check both rows and columns to be exact |
---|
| 3345 | lengthNames_=(int) maxLength; |
---|
| 3346 | } |
---|
[546] | 3347 | // Copies in Row names - modifies names first .. last-1 |
---|
| 3348 | void |
---|
| 3349 | ClpModel::copyRowNames(const char * const * rowNames, int first, int last) |
---|
| 3350 | { |
---|
| 3351 | unsigned int maxLength=lengthNames_; |
---|
| 3352 | int size = rowNames_.size(); |
---|
| 3353 | if (size!=numberRows_) |
---|
| 3354 | rowNames_.resize(numberRows_); |
---|
| 3355 | int iRow; |
---|
| 3356 | for (iRow=first; iRow<last;iRow++) { |
---|
[1034] | 3357 | if (rowNames[iRow-first]&&strlen(rowNames[iRow-first])) { |
---|
| 3358 | rowNames_[iRow]= rowNames[iRow-first]; |
---|
| 3359 | maxLength = CoinMax(maxLength,(unsigned int) strlen(rowNames[iRow-first])); |
---|
| 3360 | } else { |
---|
| 3361 | maxLength = CoinMax(maxLength,(unsigned int) 8); |
---|
| 3362 | char name[9]; |
---|
| 3363 | sprintf(name,"R%7.7d",iRow); |
---|
| 3364 | rowNames_[iRow]=name; |
---|
| 3365 | } |
---|
[546] | 3366 | } |
---|
| 3367 | // May be too big - but we would have to check both rows and columns to be exact |
---|
| 3368 | lengthNames_=(int) maxLength; |
---|
| 3369 | } |
---|
| 3370 | // Copies in Column names - modifies names first .. last-1 |
---|
| 3371 | void |
---|
| 3372 | ClpModel::copyColumnNames(const char * const * columnNames, int first, int last) |
---|
| 3373 | { |
---|
| 3374 | unsigned int maxLength=lengthNames_; |
---|
| 3375 | int size = columnNames_.size(); |
---|
| 3376 | if (size!=numberColumns_) |
---|
| 3377 | columnNames_.resize(numberColumns_); |
---|
| 3378 | int iColumn; |
---|
| 3379 | for (iColumn=first; iColumn<last;iColumn++) { |
---|
[1034] | 3380 | if (columnNames[iColumn-first]&&strlen(columnNames[iColumn-first])) { |
---|
| 3381 | columnNames_[iColumn]= columnNames[iColumn-first]; |
---|
| 3382 | maxLength = CoinMax(maxLength,(unsigned int) strlen(columnNames[iColumn-first])); |
---|
| 3383 | } else { |
---|
| 3384 | maxLength = CoinMax(maxLength,(unsigned int) 8); |
---|
| 3385 | char name[9]; |
---|
| 3386 | sprintf(name,"C%7.7d",iColumn); |
---|
| 3387 | columnNames_[iColumn]=name; |
---|
| 3388 | } |
---|
[546] | 3389 | } |
---|
| 3390 | // May be too big - but we would have to check both rows and columns to be exact |
---|
| 3391 | lengthNames_=(int) maxLength; |
---|
| 3392 | } |
---|
[653] | 3393 | #endif |
---|
[470] | 3394 | // Primal objective limit |
---|
| 3395 | void |
---|
| 3396 | ClpModel::setPrimalObjectiveLimit(double value) |
---|
| 3397 | { |
---|
| 3398 | dblParam_[ClpPrimalObjectiveLimit]=value; |
---|
| 3399 | } |
---|
[240] | 3400 | // Dual objective limit |
---|
| 3401 | void |
---|
| 3402 | ClpModel::setDualObjectiveLimit(double value) |
---|
| 3403 | { |
---|
| 3404 | dblParam_[ClpDualObjectiveLimit]=value; |
---|
| 3405 | } |
---|
| 3406 | // Objective offset |
---|
| 3407 | void |
---|
| 3408 | ClpModel::setObjectiveOffset(double value) |
---|
| 3409 | { |
---|
| 3410 | dblParam_[ClpObjOffset]=value; |
---|
| 3411 | } |
---|
[325] | 3412 | // Solve a problem with no elements - return status |
---|
| 3413 | int ClpModel::emptyProblem(int * infeasNumber, double * infeasSum,bool printMessage) |
---|
| 3414 | { |
---|
[523] | 3415 | secondaryStatus_=6; // so user can see something odd |
---|
[325] | 3416 | if (printMessage) |
---|
| 3417 | handler_->message(CLP_EMPTY_PROBLEM,messages_) |
---|
| 3418 | <<numberRows_ |
---|
| 3419 | <<numberColumns_ |
---|
| 3420 | <<0 |
---|
| 3421 | <<CoinMessageEol; |
---|
| 3422 | int returnCode=0; |
---|
| 3423 | if (numberRows_||numberColumns_) { |
---|
| 3424 | if (!status_) { |
---|
| 3425 | status_ = new unsigned char[numberRows_+numberColumns_]; |
---|
[706] | 3426 | CoinZeroN(status_,numberRows_+numberColumns_); |
---|
[325] | 3427 | } |
---|
| 3428 | } |
---|
| 3429 | // status is set directly (as can be used by Interior methods) |
---|
| 3430 | // check feasible |
---|
| 3431 | int numberPrimalInfeasibilities=0; |
---|
| 3432 | double sumPrimalInfeasibilities=0.0; |
---|
| 3433 | int numberDualInfeasibilities=0; |
---|
| 3434 | double sumDualInfeasibilities=0.0; |
---|
| 3435 | if (numberRows_) { |
---|
| 3436 | for (int i=0;i<numberRows_;i++) { |
---|
| 3437 | dual_[i]=0.0; |
---|
| 3438 | if (rowLower_[i]<=rowUpper_[i]) { |
---|
| 3439 | if (rowLower_[i]>-1.0e30||rowUpper_[i]<1.0e30) { |
---|
| 3440 | if (fabs(rowLower_[i])<fabs(rowUpper_[i])) |
---|
| 3441 | rowActivity_[i]=rowLower_[i]; |
---|
| 3442 | else |
---|
| 3443 | rowActivity_[i]=rowUpper_[i]; |
---|
| 3444 | } else { |
---|
| 3445 | rowActivity_[i]=0.0; |
---|
| 3446 | } |
---|
| 3447 | } else { |
---|
| 3448 | rowActivity_[i]=0.0; |
---|
| 3449 | numberPrimalInfeasibilities++; |
---|
| 3450 | sumPrimalInfeasibilities += rowLower_[i]-rowUpper_[i]; |
---|
| 3451 | returnCode=1; |
---|
| 3452 | } |
---|
| 3453 | status_[i+numberColumns_]=1; |
---|
| 3454 | } |
---|
| 3455 | } |
---|
| 3456 | objectiveValue_=0.0; |
---|
| 3457 | if (numberColumns_) { |
---|
| 3458 | const double * cost = objective(); |
---|
| 3459 | for (int i=0;i<numberColumns_;i++) { |
---|
| 3460 | reducedCost_[i]=cost[i]; |
---|
| 3461 | double objValue = cost[i]*optimizationDirection_; |
---|
| 3462 | if (columnLower_[i]<=columnUpper_[i]) { |
---|
| 3463 | if (columnLower_[i]>-1.0e30||columnUpper_[i]<1.0e30) { |
---|
| 3464 | if (!objValue) { |
---|
| 3465 | if (fabs(columnLower_[i])<fabs(columnUpper_[i])) { |
---|
| 3466 | columnActivity_[i]=columnLower_[i]; |
---|
| 3467 | status_[i]=3; |
---|
| 3468 | } else { |
---|
| 3469 | columnActivity_[i]=columnUpper_[i]; |
---|
| 3470 | status_[i]=2; |
---|
| 3471 | } |
---|
| 3472 | } else if (objValue>0.0) { |
---|
| 3473 | if (columnLower_[i]>-1.0e30) { |
---|
| 3474 | columnActivity_[i]=columnLower_[i]; |
---|
| 3475 | status_[i]=3; |
---|
| 3476 | } else { |
---|
| 3477 | columnActivity_[i]=columnUpper_[i]; |
---|
| 3478 | status_[i]=2; |
---|
| 3479 | numberDualInfeasibilities++;; |
---|
| 3480 | sumDualInfeasibilities += fabs(objValue); |
---|
| 3481 | returnCode |= 2; |
---|
| 3482 | } |
---|
| 3483 | objectiveValue_ += columnActivity_[i]*objValue; |
---|
| 3484 | } else { |
---|
| 3485 | if (columnUpper_[i]<1.0e30) { |
---|
| 3486 | columnActivity_[i]=columnUpper_[i]; |
---|
| 3487 | status_[i]=2; |
---|
| 3488 | } else { |
---|
| 3489 | columnActivity_[i]=columnLower_[i]; |
---|
| 3490 | status_[i]=3; |
---|
| 3491 | numberDualInfeasibilities++;; |
---|
| 3492 | sumDualInfeasibilities += fabs(objValue); |
---|
| 3493 | returnCode |= 2; |
---|
| 3494 | } |
---|
| 3495 | objectiveValue_ += columnActivity_[i]*objValue; |
---|
| 3496 | } |
---|
| 3497 | } else { |
---|
| 3498 | columnActivity_[i]=0.0; |
---|
| 3499 | if (objValue) { |
---|
| 3500 | numberDualInfeasibilities++;; |
---|
| 3501 | sumDualInfeasibilities += fabs(objValue); |
---|
| 3502 | returnCode |= 2; |
---|
| 3503 | } |
---|
| 3504 | status_[i]=0; |
---|
| 3505 | } |
---|
| 3506 | } else { |
---|
| 3507 | if (fabs(columnLower_[i])<fabs(columnUpper_[i])) { |
---|
| 3508 | columnActivity_[i]=columnLower_[i]; |
---|
| 3509 | status_[i]=3; |
---|
| 3510 | } else { |
---|
| 3511 | columnActivity_[i]=columnUpper_[i]; |
---|
| 3512 | status_[i]=2; |
---|
| 3513 | } |
---|
| 3514 | numberPrimalInfeasibilities++; |
---|
| 3515 | sumPrimalInfeasibilities += columnLower_[i]-columnUpper_[i]; |
---|
| 3516 | returnCode |= 1; |
---|
| 3517 | } |
---|
| 3518 | } |
---|
| 3519 | } |
---|
[848] | 3520 | objectiveValue_ /= (objectiveScale_*rhsScale_); |
---|
[325] | 3521 | if (infeasNumber) { |
---|
| 3522 | infeasNumber[0]=numberDualInfeasibilities; |
---|
| 3523 | infeasSum[0]=sumDualInfeasibilities; |
---|
| 3524 | infeasNumber[1]=numberPrimalInfeasibilities; |
---|
| 3525 | infeasSum[1]=sumPrimalInfeasibilities; |
---|
| 3526 | } |
---|
| 3527 | if (returnCode==3) |
---|
| 3528 | returnCode=4; |
---|
| 3529 | return returnCode; |
---|
| 3530 | } |
---|
[651] | 3531 | #ifndef SLIM_NOIO |
---|
[335] | 3532 | /* Write the problem in MPS format to the specified file. |
---|
| 3533 | |
---|
| 3534 | Row and column names may be null. |
---|
| 3535 | formatType is |
---|
| 3536 | <ul> |
---|
| 3537 | <li> 0 - normal |
---|
| 3538 | <li> 1 - extra accuracy |
---|
| 3539 | <li> 2 - IEEE hex (later) |
---|
| 3540 | </ul> |
---|
| 3541 | |
---|
| 3542 | Returns non-zero on I/O error |
---|
| 3543 | */ |
---|
| 3544 | int |
---|
| 3545 | ClpModel::writeMps(const char *filen |
---|