239 | | void ClpModel::setPrimalTolerance( double value) |
240 | | { |
241 | | if (value > 0.0 && value < 1.0e10) |
242 | | dblParam_[ClpPrimalTolerance] = value; |
243 | | } |
244 | | void ClpModel::setDualTolerance( double value) |
245 | | { |
246 | | if (value > 0.0 && value < 1.0e10) |
247 | | dblParam_[ClpDualTolerance] = value; |
248 | | } |
249 | | void ClpModel::setOptimizationDirection( double value) |
250 | | { |
251 | | optimizationDirection_ = value; |
252 | | } |
253 | | void |
254 | | ClpModel::gutsOfLoadModel (int numberRows, int numberColumns, |
255 | | const double* collb, const double* colub, |
256 | | const double* obj, |
257 | | const double* rowlb, const double* rowub, |
258 | | const double * rowObjective) |
259 | | { |
260 | | // save event handler in case already set |
261 | | ClpEventHandler * handler = eventHandler_->clone(); |
262 | | // Save specialOptions |
263 | | int saveOptions = specialOptions_; |
264 | | gutsOfDelete(0); |
265 | | specialOptions_ = saveOptions; |
266 | | eventHandler_ = handler; |
267 | | numberRows_ = numberRows; |
268 | | numberColumns_ = numberColumns; |
269 | | rowActivity_ = new double[numberRows_]; |
270 | | columnActivity_ = new double[numberColumns_]; |
271 | | dual_ = new double[numberRows_]; |
272 | | reducedCost_ = new double[numberColumns_]; |
273 | | |
274 | | CoinZeroN(dual_, numberRows_); |
275 | | CoinZeroN(reducedCost_, numberColumns_); |
276 | | int iRow, iColumn; |
277 | | |
278 | | rowLower_ = ClpCopyOfArray(rowlb, numberRows_, -COIN_DBL_MAX); |
279 | | rowUpper_ = ClpCopyOfArray(rowub, numberRows_, COIN_DBL_MAX); |
280 | | double * objective = ClpCopyOfArray(obj, numberColumns_, 0.0); |
281 | | objective_ = new ClpLinearObjective(objective, numberColumns_); |
282 | | delete [] objective; |
283 | | rowObjective_ = ClpCopyOfArray(rowObjective, numberRows_); |
284 | | columnLower_ = ClpCopyOfArray(collb, numberColumns_, 0.0); |
285 | | columnUpper_ = ClpCopyOfArray(colub, numberColumns_, COIN_DBL_MAX); |
286 | | // set default solution and clean bounds |
287 | | for (iRow = 0; iRow < numberRows_; iRow++) { |
288 | | if (rowLower_[iRow] > 0.0) { |
289 | | rowActivity_[iRow] = rowLower_[iRow]; |
290 | | } else if (rowUpper_[iRow] < 0.0) { |
291 | | rowActivity_[iRow] = rowUpper_[iRow]; |
292 | | } else { |
293 | | rowActivity_[iRow] = 0.0; |
294 | | } |
295 | | if (rowLower_[iRow] < -1.0e27) |
296 | | rowLower_[iRow] = -COIN_DBL_MAX; |
297 | | if (rowUpper_[iRow] > 1.0e27) |
298 | | rowUpper_[iRow] = COIN_DBL_MAX; |
299 | | } |
300 | | for (iColumn = 0; iColumn < numberColumns_; iColumn++) { |
301 | | if (columnLower_[iColumn] > 0.0) { |
302 | | columnActivity_[iColumn] = columnLower_[iColumn]; |
303 | | } else if (columnUpper_[iColumn] < 0.0) { |
304 | | columnActivity_[iColumn] = columnUpper_[iColumn]; |
305 | | } else { |
306 | | columnActivity_[iColumn] = 0.0; |
307 | | } |
308 | | if (columnLower_[iColumn] < -1.0e27) |
309 | | columnLower_[iColumn] = -COIN_DBL_MAX; |
310 | | if (columnUpper_[iColumn] > 1.0e27) |
311 | | columnUpper_[iColumn] = COIN_DBL_MAX; |
312 | | } |
| 239 | void ClpModel::setPrimalTolerance(double value) |
| 240 | { |
| 241 | if (value > 0.0 && value < 1.0e10) |
| 242 | dblParam_[ClpPrimalTolerance] = value; |
| 243 | } |
| 244 | void ClpModel::setDualTolerance(double value) |
| 245 | { |
| 246 | if (value > 0.0 && value < 1.0e10) |
| 247 | dblParam_[ClpDualTolerance] = value; |
| 248 | } |
| 249 | void ClpModel::setOptimizationDirection(double value) |
| 250 | { |
| 251 | optimizationDirection_ = value; |
| 252 | } |
| 253 | void ClpModel::gutsOfLoadModel(int numberRows, int numberColumns, |
| 254 | const double *collb, const double *colub, |
| 255 | const double *obj, |
| 256 | const double *rowlb, const double *rowub, |
| 257 | const double *rowObjective) |
| 258 | { |
| 259 | // save event handler in case already set |
| 260 | ClpEventHandler *handler = eventHandler_->clone(); |
| 261 | // Save specialOptions |
| 262 | int saveOptions = specialOptions_; |
| 263 | gutsOfDelete(0); |
| 264 | specialOptions_ = saveOptions; |
| 265 | eventHandler_ = handler; |
| 266 | numberRows_ = numberRows; |
| 267 | numberColumns_ = numberColumns; |
| 268 | rowActivity_ = new double[numberRows_]; |
| 269 | columnActivity_ = new double[numberColumns_]; |
| 270 | dual_ = new double[numberRows_]; |
| 271 | reducedCost_ = new double[numberColumns_]; |
| 272 | |
| 273 | CoinZeroN(dual_, numberRows_); |
| 274 | CoinZeroN(reducedCost_, numberColumns_); |
| 275 | int iRow, iColumn; |
| 276 | |
| 277 | rowLower_ = ClpCopyOfArray(rowlb, numberRows_, -COIN_DBL_MAX); |
| 278 | rowUpper_ = ClpCopyOfArray(rowub, numberRows_, COIN_DBL_MAX); |
| 279 | double *objective = ClpCopyOfArray(obj, numberColumns_, 0.0); |
| 280 | objective_ = new ClpLinearObjective(objective, numberColumns_); |
| 281 | delete[] objective; |
| 282 | rowObjective_ = ClpCopyOfArray(rowObjective, numberRows_); |
| 283 | columnLower_ = ClpCopyOfArray(collb, numberColumns_, 0.0); |
| 284 | columnUpper_ = ClpCopyOfArray(colub, numberColumns_, COIN_DBL_MAX); |
| 285 | // set default solution and clean bounds |
| 286 | for (iRow = 0; iRow < numberRows_; iRow++) { |
| 287 | if (rowLower_[iRow] > 0.0) { |
| 288 | rowActivity_[iRow] = rowLower_[iRow]; |
| 289 | } else if (rowUpper_[iRow] < 0.0) { |
| 290 | rowActivity_[iRow] = rowUpper_[iRow]; |
| 291 | } else { |
| 292 | rowActivity_[iRow] = 0.0; |
| 293 | } |
| 294 | if (rowLower_[iRow] < -1.0e27) |
| 295 | rowLower_[iRow] = -COIN_DBL_MAX; |
| 296 | if (rowUpper_[iRow] > 1.0e27) |
| 297 | rowUpper_[iRow] = COIN_DBL_MAX; |
| 298 | } |
| 299 | for (iColumn = 0; iColumn < numberColumns_; iColumn++) { |
| 300 | if (columnLower_[iColumn] > 0.0) { |
| 301 | columnActivity_[iColumn] = columnLower_[iColumn]; |
| 302 | } else if (columnUpper_[iColumn] < 0.0) { |
| 303 | columnActivity_[iColumn] = columnUpper_[iColumn]; |
| 304 | } else { |
| 305 | columnActivity_[iColumn] = 0.0; |
| 306 | } |
| 307 | if (columnLower_[iColumn] < -1.0e27) |
| 308 | columnLower_[iColumn] = -COIN_DBL_MAX; |
| 309 | if (columnUpper_[iColumn] > 1.0e27) |
| 310 | columnUpper_[iColumn] = COIN_DBL_MAX; |
| 311 | } |
315 | | void ClpModel::setRowObjective(const double * rowObjective) |
316 | | { |
317 | | delete [] rowObjective_; |
318 | | rowObjective_ = ClpCopyOfArray(rowObjective, numberRows_); |
319 | | whatsChanged_ = 0; |
320 | | } |
321 | | void |
322 | | ClpModel::loadProblem ( const ClpMatrixBase& matrix, |
323 | | const double* collb, const double* colub, |
324 | | const double* obj, |
325 | | const double* rowlb, const double* rowub, |
326 | | const double * rowObjective) |
327 | | { |
328 | | gutsOfLoadModel(matrix.getNumRows(), matrix.getNumCols(), |
329 | | collb, colub, obj, rowlb, rowub, rowObjective); |
330 | | if (matrix.isColOrdered()) { |
331 | | matrix_ = matrix.clone(); |
332 | | } else { |
333 | | // later may want to keep as unknown class |
334 | | CoinPackedMatrix matrix2; |
335 | | matrix2.setExtraGap(0.0); |
336 | | matrix2.setExtraMajor(0.0); |
337 | | matrix2.reverseOrderedCopyOf(*matrix.getPackedMatrix()); |
338 | | matrix.releasePackedMatrix(); |
339 | | matrix_ = new ClpPackedMatrix(matrix2); |
340 | | } |
341 | | matrix_->setDimensions(numberRows_, numberColumns_); |
342 | | } |
343 | | void |
344 | | ClpModel::loadProblem ( const CoinPackedMatrix& matrix, |
345 | | const double* collb, const double* colub, |
346 | | const double* obj, |
347 | | const double* rowlb, const double* rowub, |
348 | | const double * rowObjective) |
349 | | { |
350 | | ClpPackedMatrix* clpMatrix = |
351 | | dynamic_cast< ClpPackedMatrix*>(matrix_); |
352 | | bool special = (clpMatrix) ? clpMatrix->wantsSpecialColumnCopy() : false; |
353 | | gutsOfLoadModel(matrix.getNumRows(), matrix.getNumCols(), |
354 | | collb, colub, obj, rowlb, rowub, rowObjective); |
355 | | if (matrix.isColOrdered()) { |
356 | | matrix_ = new ClpPackedMatrix(matrix); |
357 | | if (special) { |
358 | | clpMatrix = static_cast< ClpPackedMatrix*>(matrix_); |
359 | | clpMatrix->makeSpecialColumnCopy(); |
360 | | } |
361 | | } else { |
362 | | CoinPackedMatrix matrix2; |
363 | | matrix2.setExtraGap(0.0); |
364 | | matrix2.setExtraMajor(0.0); |
365 | | matrix2.reverseOrderedCopyOf(matrix); |
366 | | matrix_ = new ClpPackedMatrix(matrix2); |
367 | | } |
368 | | matrix_->setDimensions(numberRows_, numberColumns_); |
369 | | } |
370 | | void |
371 | | ClpModel::loadProblem ( |
372 | | const int numcols, const int numrows, |
373 | | const CoinBigIndex* start, const int* index, |
374 | | const double* value, |
375 | | const double* collb, const double* colub, |
376 | | const double* obj, |
377 | | const double* rowlb, const double* rowub, |
378 | | const double * rowObjective) |
379 | | { |
380 | | gutsOfLoadModel(numrows, numcols, |
381 | | collb, colub, obj, rowlb, rowub, rowObjective); |
382 | | CoinBigIndex numberElements = start ? start[numcols] : 0; |
383 | | CoinPackedMatrix matrix(true, numrows, numrows ? numcols : 0, numberElements, |
384 | | value, index, start, NULL); |
385 | | matrix_ = new ClpPackedMatrix(matrix); |
386 | | matrix_->setDimensions(numberRows_, numberColumns_); |
387 | | } |
388 | | void |
389 | | ClpModel::loadProblem ( |
390 | | const int numcols, const int numrows, |
391 | | const CoinBigIndex* start, const int* index, |
392 | | const double* value, const int* length, |
393 | | const double* collb, const double* colub, |
394 | | const double* obj, |
395 | | const double* rowlb, const double* rowub, |
396 | | const double * rowObjective) |
397 | | { |
398 | | gutsOfLoadModel(numrows, numcols, |
399 | | collb, colub, obj, rowlb, rowub, rowObjective); |
400 | | // Compute number of elements |
401 | | int numberElements = 0; |
402 | | int i; |
403 | | for (i = 0; i < numcols; i++) |
404 | | numberElements += length[i]; |
405 | | CoinPackedMatrix matrix(true, numrows, numcols, numberElements, |
406 | | value, index, start, length); |
407 | | matrix_ = new ClpPackedMatrix(matrix); |
| 314 | void ClpModel::setRowObjective(const double *rowObjective) |
| 315 | { |
| 316 | delete[] rowObjective_; |
| 317 | rowObjective_ = ClpCopyOfArray(rowObjective, numberRows_); |
| 318 | whatsChanged_ = 0; |
| 319 | } |
| 320 | void ClpModel::loadProblem(const ClpMatrixBase &matrix, |
| 321 | const double *collb, const double *colub, |
| 322 | const double *obj, |
| 323 | const double *rowlb, const double *rowub, |
| 324 | const double *rowObjective) |
| 325 | { |
| 326 | gutsOfLoadModel(matrix.getNumRows(), matrix.getNumCols(), |
| 327 | collb, colub, obj, rowlb, rowub, rowObjective); |
| 328 | if (matrix.isColOrdered()) { |
| 329 | matrix_ = matrix.clone(); |
| 330 | } else { |
| 331 | // later may want to keep as unknown class |
| 332 | CoinPackedMatrix matrix2; |
| 333 | matrix2.setExtraGap(0.0); |
| 334 | matrix2.setExtraMajor(0.0); |
| 335 | matrix2.reverseOrderedCopyOf(*matrix.getPackedMatrix()); |
| 336 | matrix.releasePackedMatrix(); |
| 337 | matrix_ = new ClpPackedMatrix(matrix2); |
| 338 | } |
| 339 | matrix_->setDimensions(numberRows_, numberColumns_); |
| 340 | } |
| 341 | void ClpModel::loadProblem(const CoinPackedMatrix &matrix, |
| 342 | const double *collb, const double *colub, |
| 343 | const double *obj, |
| 344 | const double *rowlb, const double *rowub, |
| 345 | const double *rowObjective) |
| 346 | { |
| 347 | ClpPackedMatrix *clpMatrix = dynamic_cast< ClpPackedMatrix * >(matrix_); |
| 348 | bool special = (clpMatrix) ? clpMatrix->wantsSpecialColumnCopy() : false; |
| 349 | gutsOfLoadModel(matrix.getNumRows(), matrix.getNumCols(), |
| 350 | collb, colub, obj, rowlb, rowub, rowObjective); |
| 351 | if (matrix.isColOrdered()) { |
| 352 | matrix_ = new ClpPackedMatrix(matrix); |
| 353 | if (special) { |
| 354 | clpMatrix = static_cast< ClpPackedMatrix * >(matrix_); |
| 355 | clpMatrix->makeSpecialColumnCopy(); |
| 356 | } |
| 357 | } else { |
| 358 | CoinPackedMatrix matrix2; |
| 359 | matrix2.setExtraGap(0.0); |
| 360 | matrix2.setExtraMajor(0.0); |
| 361 | matrix2.reverseOrderedCopyOf(matrix); |
| 362 | matrix_ = new ClpPackedMatrix(matrix2); |
| 363 | } |
| 364 | matrix_->setDimensions(numberRows_, numberColumns_); |
| 365 | } |
| 366 | void ClpModel::loadProblem( |
| 367 | const int numcols, const int numrows, |
| 368 | const CoinBigIndex *start, const int *index, |
| 369 | const double *value, |
| 370 | const double *collb, const double *colub, |
| 371 | const double *obj, |
| 372 | const double *rowlb, const double *rowub, |
| 373 | const double *rowObjective) |
| 374 | { |
| 375 | gutsOfLoadModel(numrows, numcols, |
| 376 | collb, colub, obj, rowlb, rowub, rowObjective); |
| 377 | CoinBigIndex numberElements = start ? start[numcols] : 0; |
| 378 | CoinPackedMatrix matrix(true, numrows, numrows ? numcols : 0, numberElements, |
| 379 | value, index, start, NULL); |
| 380 | matrix_ = new ClpPackedMatrix(matrix); |
| 381 | matrix_->setDimensions(numberRows_, numberColumns_); |
| 382 | } |
| 383 | void ClpModel::loadProblem( |
| 384 | const int numcols, const int numrows, |
| 385 | const CoinBigIndex *start, const int *index, |
| 386 | const double *value, const int *length, |
| 387 | const double *collb, const double *colub, |
| 388 | const double *obj, |
| 389 | const double *rowlb, const double *rowub, |
| 390 | const double *rowObjective) |
| 391 | { |
| 392 | gutsOfLoadModel(numrows, numcols, |
| 393 | collb, colub, obj, rowlb, rowub, rowObjective); |
| 394 | // Compute number of elements |
| 395 | int numberElements = 0; |
| 396 | int i; |
| 397 | for (i = 0; i < numcols; i++) |
| 398 | numberElements += length[i]; |
| 399 | CoinPackedMatrix matrix(true, numrows, numcols, numberElements, |
| 400 | value, index, start, length); |
| 401 | matrix_ = new ClpPackedMatrix(matrix); |
411 | | int |
412 | | ClpModel::loadProblem ( CoinModel & modelObject, bool tryPlusMinusOne) |
413 | | { |
414 | | if (modelObject.numberColumns() == 0 && modelObject.numberRows() == 0) |
415 | | return 0; |
416 | | int numberErrors = 0; |
417 | | // Set arrays for normal use |
418 | | double * rowLower = modelObject.rowLowerArray(); |
419 | | double * rowUpper = modelObject.rowUpperArray(); |
420 | | double * columnLower = modelObject.columnLowerArray(); |
421 | | double * columnUpper = modelObject.columnUpperArray(); |
422 | | double * objective = modelObject.objectiveArray(); |
423 | | int * integerType = modelObject.integerTypeArray(); |
424 | | double * associated = modelObject.associatedArray(); |
425 | | // If strings then do copies |
426 | | if (modelObject.stringsExist()) { |
427 | | numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper, |
428 | | objective, integerType, associated); |
429 | | } |
430 | | int numberRows = modelObject.numberRows(); |
431 | | int numberColumns = modelObject.numberColumns(); |
432 | | gutsOfLoadModel(numberRows, numberColumns, |
433 | | columnLower, columnUpper, objective, rowLower, rowUpper, NULL); |
434 | | setObjectiveOffset(modelObject.objectiveOffset()); |
435 | | CoinBigIndex * startPositive = NULL; |
436 | | CoinBigIndex * startNegative = NULL; |
437 | | delete matrix_; |
438 | | if (tryPlusMinusOne) { |
439 | | startPositive = new CoinBigIndex[numberColumns+1]; |
440 | | startNegative = new CoinBigIndex[numberColumns]; |
441 | | modelObject.countPlusMinusOne(startPositive, startNegative, associated); |
442 | | if (startPositive[0] < 0) { |
443 | | // no good |
444 | | tryPlusMinusOne = false; |
445 | | delete [] startPositive; |
446 | | delete [] startNegative; |
447 | | } |
448 | | } |
| 405 | int ClpModel::loadProblem(CoinModel &modelObject, bool tryPlusMinusOne) |
| 406 | { |
| 407 | if (modelObject.numberColumns() == 0 && modelObject.numberRows() == 0) |
| 408 | return 0; |
| 409 | int numberErrors = 0; |
| 410 | // Set arrays for normal use |
| 411 | double *rowLower = modelObject.rowLowerArray(); |
| 412 | double *rowUpper = modelObject.rowUpperArray(); |
| 413 | double *columnLower = modelObject.columnLowerArray(); |
| 414 | double *columnUpper = modelObject.columnUpperArray(); |
| 415 | double *objective = modelObject.objectiveArray(); |
| 416 | int *integerType = modelObject.integerTypeArray(); |
| 417 | double *associated = modelObject.associatedArray(); |
| 418 | // If strings then do copies |
| 419 | if (modelObject.stringsExist()) { |
| 420 | numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper, |
| 421 | objective, integerType, associated); |
| 422 | } |
| 423 | int numberRows = modelObject.numberRows(); |
| 424 | int numberColumns = modelObject.numberColumns(); |
| 425 | gutsOfLoadModel(numberRows, numberColumns, |
| 426 | columnLower, columnUpper, objective, rowLower, rowUpper, NULL); |
| 427 | setObjectiveOffset(modelObject.objectiveOffset()); |
| 428 | CoinBigIndex *startPositive = NULL; |
| 429 | CoinBigIndex *startNegative = NULL; |
| 430 | delete matrix_; |
| 431 | if (tryPlusMinusOne) { |
| 432 | startPositive = new CoinBigIndex[numberColumns + 1]; |
| 433 | startNegative = new CoinBigIndex[numberColumns]; |
| 434 | modelObject.countPlusMinusOne(startPositive, startNegative, associated); |
| 435 | if (startPositive[0] < 0) { |
| 436 | // no good |
| 437 | tryPlusMinusOne = false; |
| 438 | delete[] startPositive; |
| 439 | delete[] startNegative; |
| 440 | } |
| 441 | } |
743 | | void |
744 | | ClpModel::gutsOfCopy(const ClpModel & rhs, int trueCopy) |
745 | | { |
746 | | defaultHandler_ = rhs.defaultHandler_; |
747 | | randomNumberGenerator_ = rhs.randomNumberGenerator_; |
748 | | if (trueCopy >= 0) { |
749 | | if (defaultHandler_) |
750 | | handler_ = new CoinMessageHandler(*rhs.handler_); |
751 | | else |
752 | | handler_ = rhs.handler_; |
753 | | eventHandler_ = rhs.eventHandler_->clone(); |
754 | | messages_ = rhs.messages_; |
755 | | coinMessages_ = rhs.coinMessages_; |
756 | | } else { |
757 | | if (!eventHandler_ && rhs.eventHandler_) |
758 | | eventHandler_ = rhs.eventHandler_->clone(); |
759 | | } |
760 | | intParam_[ClpMaxNumIteration] = rhs.intParam_[ClpMaxNumIteration]; |
761 | | intParam_[ClpMaxNumIterationHotStart] = |
762 | | rhs.intParam_[ClpMaxNumIterationHotStart]; |
763 | | intParam_[ClpNameDiscipline] = rhs.intParam_[ClpNameDiscipline] ; |
764 | | |
765 | | dblParam_[ClpDualObjectiveLimit] = rhs.dblParam_[ClpDualObjectiveLimit]; |
766 | | dblParam_[ClpPrimalObjectiveLimit] = rhs.dblParam_[ClpPrimalObjectiveLimit]; |
767 | | dblParam_[ClpDualTolerance] = rhs.dblParam_[ClpDualTolerance]; |
768 | | dblParam_[ClpPrimalTolerance] = rhs.dblParam_[ClpPrimalTolerance]; |
769 | | dblParam_[ClpObjOffset] = rhs.dblParam_[ClpObjOffset]; |
770 | | dblParam_[ClpMaxSeconds] = rhs.dblParam_[ClpMaxSeconds]; |
771 | | dblParam_[ClpMaxWallSeconds] = rhs.dblParam_[ClpMaxWallSeconds]; |
772 | | dblParam_[ClpPresolveTolerance] = rhs.dblParam_[ClpPresolveTolerance]; |
| 726 | void ClpModel::gutsOfCopy(const ClpModel &rhs, int trueCopy) |
| 727 | { |
| 728 | defaultHandler_ = rhs.defaultHandler_; |
| 729 | randomNumberGenerator_ = rhs.randomNumberGenerator_; |
| 730 | if (trueCopy >= 0) { |
| 731 | if (defaultHandler_) |
| 732 | handler_ = new CoinMessageHandler(*rhs.handler_); |
| 733 | else |
| 734 | handler_ = rhs.handler_; |
| 735 | eventHandler_ = rhs.eventHandler_->clone(); |
| 736 | messages_ = rhs.messages_; |
| 737 | coinMessages_ = rhs.coinMessages_; |
| 738 | } else { |
| 739 | if (!eventHandler_ && rhs.eventHandler_) |
| 740 | eventHandler_ = rhs.eventHandler_->clone(); |
| 741 | } |
| 742 | intParam_[ClpMaxNumIteration] = rhs.intParam_[ClpMaxNumIteration]; |
| 743 | intParam_[ClpMaxNumIterationHotStart] = rhs.intParam_[ClpMaxNumIterationHotStart]; |
| 744 | intParam_[ClpNameDiscipline] = rhs.intParam_[ClpNameDiscipline]; |
| 745 | |
| 746 | dblParam_[ClpDualObjectiveLimit] = rhs.dblParam_[ClpDualObjectiveLimit]; |
| 747 | dblParam_[ClpPrimalObjectiveLimit] = rhs.dblParam_[ClpPrimalObjectiveLimit]; |
| 748 | dblParam_[ClpDualTolerance] = rhs.dblParam_[ClpDualTolerance]; |
| 749 | dblParam_[ClpPrimalTolerance] = rhs.dblParam_[ClpPrimalTolerance]; |
| 750 | dblParam_[ClpObjOffset] = rhs.dblParam_[ClpObjOffset]; |
| 751 | dblParam_[ClpMaxSeconds] = rhs.dblParam_[ClpMaxSeconds]; |
| 752 | dblParam_[ClpMaxWallSeconds] = rhs.dblParam_[ClpMaxWallSeconds]; |
| 753 | dblParam_[ClpPresolveTolerance] = rhs.dblParam_[ClpPresolveTolerance]; |
796 | | lengthNames_ = rhs.lengthNames_; |
797 | | if (lengthNames_) { |
798 | | rowNames_ = rhs.rowNames_; |
799 | | columnNames_ = rhs.columnNames_; |
800 | | } |
801 | | #endif |
802 | | numberThreads_ = rhs.numberThreads_; |
803 | | if (maximumRows_ < 0) { |
804 | | specialOptions_ &= ~65536; |
805 | | savedRowScale_ = NULL; |
806 | | savedColumnScale_ = NULL; |
807 | | integerType_ = CoinCopyOfArray(rhs.integerType_, numberColumns_); |
808 | | rowActivity_ = ClpCopyOfArray(rhs.rowActivity_, numberRows_); |
809 | | columnActivity_ = ClpCopyOfArray(rhs.columnActivity_, numberColumns_); |
810 | | dual_ = ClpCopyOfArray(rhs.dual_, numberRows_); |
811 | | reducedCost_ = ClpCopyOfArray(rhs.reducedCost_, numberColumns_); |
812 | | rowLower_ = ClpCopyOfArray ( rhs.rowLower_, numberRows_ ); |
813 | | rowUpper_ = ClpCopyOfArray ( rhs.rowUpper_, numberRows_ ); |
814 | | columnLower_ = ClpCopyOfArray ( rhs.columnLower_, numberColumns_ ); |
815 | | columnUpper_ = ClpCopyOfArray ( rhs.columnUpper_, numberColumns_ ); |
816 | | rowScale_ = ClpCopyOfArray(rhs.rowScale_, numberRows_ * 2); |
817 | | columnScale_ = ClpCopyOfArray(rhs.columnScale_, numberColumns_ * 2); |
818 | | if (rhs.objective_) |
819 | | objective_ = rhs.objective_->clone(); |
820 | | else |
821 | | objective_ = NULL; |
822 | | rowObjective_ = ClpCopyOfArray ( rhs.rowObjective_, numberRows_ ); |
823 | | status_ = ClpCopyOfArray( rhs.status_, numberColumns_ + numberRows_); |
824 | | ray_ = NULL; |
825 | | if (problemStatus_ == 1) |
826 | | ray_ = ClpCopyOfArray (rhs.ray_, numberRows_); |
827 | | else if (problemStatus_ == 2) |
828 | | ray_ = ClpCopyOfArray (rhs.ray_, numberColumns_); |
829 | | if (rhs.rowCopy_) { |
830 | | rowCopy_ = rhs.rowCopy_->clone(); |
831 | | } else { |
832 | | rowCopy_ = NULL; |
833 | | } |
834 | | if (rhs.scaledMatrix_) { |
835 | | scaledMatrix_ = new ClpPackedMatrix(*rhs.scaledMatrix_); |
836 | | } else { |
837 | | scaledMatrix_ = NULL; |
838 | | } |
839 | | matrix_ = NULL; |
840 | | if (rhs.matrix_) { |
841 | | matrix_ = rhs.matrix_->clone(); |
842 | | } |
843 | | } else { |
844 | | // This already has arrays - just copy |
845 | | savedRowScale_ = NULL; |
846 | | savedColumnScale_ = NULL; |
847 | | startPermanentArrays(); |
848 | | if (rhs.integerType_) { |
849 | | assert (integerType_); |
850 | | ClpDisjointCopyN(rhs.integerType_, numberColumns_, integerType_); |
851 | | } else { |
852 | | integerType_ = NULL; |
853 | | } |
854 | | if (rhs.rowActivity_) { |
855 | | ClpDisjointCopyN ( rhs.rowActivity_, numberRows_ , |
856 | | rowActivity_); |
857 | | ClpDisjointCopyN ( rhs.columnActivity_, numberColumns_ , |
858 | | columnActivity_); |
859 | | ClpDisjointCopyN ( rhs.dual_, numberRows_ , |
860 | | dual_); |
861 | | ClpDisjointCopyN ( rhs.reducedCost_, numberColumns_ , |
862 | | reducedCost_); |
863 | | } else { |
864 | | rowActivity_ = NULL; |
865 | | columnActivity_ = NULL; |
866 | | dual_ = NULL; |
867 | | reducedCost_ = NULL; |
868 | | } |
869 | | ClpDisjointCopyN ( rhs.rowLower_, numberRows_, rowLower_ ); |
870 | | ClpDisjointCopyN ( rhs.rowUpper_, numberRows_, rowUpper_ ); |
871 | | ClpDisjointCopyN ( rhs.columnLower_, numberColumns_, columnLower_ ); |
872 | | assert ((specialOptions_ & 131072) == 0); |
873 | | abort(); |
874 | | ClpDisjointCopyN ( rhs.columnUpper_, numberColumns_, columnUpper_ ); |
875 | | if (rhs.objective_) { |
876 | | abort(); //check if same |
877 | | objective_ = rhs.objective_->clone(); |
878 | | } else { |
879 | | objective_ = NULL; |
880 | | } |
881 | | assert (!rhs.rowObjective_); |
882 | | ClpDisjointCopyN( rhs.status_, numberColumns_ + numberRows_, status_); |
883 | | ray_ = NULL; |
884 | | if (problemStatus_ == 1) |
885 | | ray_ = ClpCopyOfArray (rhs.ray_, numberRows_); |
886 | | else if (problemStatus_ == 2) |
887 | | ray_ = ClpCopyOfArray (rhs.ray_, numberColumns_); |
888 | | assert (!ray_); |
889 | | delete rowCopy_; |
890 | | if (rhs.rowCopy_) { |
891 | | rowCopy_ = rhs.rowCopy_->clone(); |
892 | | } else { |
893 | | rowCopy_ = NULL; |
894 | | } |
895 | | delete scaledMatrix_; |
896 | | if (rhs.scaledMatrix_) { |
897 | | scaledMatrix_ = new ClpPackedMatrix(*rhs.scaledMatrix_); |
898 | | } else { |
899 | | scaledMatrix_ = NULL; |
900 | | } |
901 | | delete matrix_; |
902 | | matrix_ = NULL; |
903 | | if (rhs.matrix_) { |
904 | | matrix_ = rhs.matrix_->clone(); |
905 | | } |
906 | | if (rhs.savedRowScale_) { |
907 | | assert (savedRowScale_); |
908 | | assert (!rowScale_); |
909 | | ClpDisjointCopyN(rhs.savedRowScale_, 4 * maximumInternalRows_, savedRowScale_); |
910 | | ClpDisjointCopyN(rhs.savedColumnScale_, 4 * maximumInternalColumns_, savedColumnScale_); |
911 | | } else { |
912 | | assert (!savedRowScale_); |
913 | | if (rowScale_) { |
914 | | ClpDisjointCopyN(rhs.rowScale_, numberRows_, rowScale_); |
915 | | ClpDisjointCopyN(rhs.columnScale_, numberColumns_, columnScale_); |
916 | | } else { |
917 | | rowScale_ = NULL; |
918 | | columnScale_ = NULL; |
919 | | } |
920 | | } |
921 | | abort(); // look at resizeDouble and resize |
922 | | } |
923 | | } else { |
924 | | savedRowScale_ = rhs.savedRowScale_; |
925 | | assert (!savedRowScale_); |
926 | | savedColumnScale_ = rhs.savedColumnScale_; |
927 | | rowActivity_ = rhs.rowActivity_; |
928 | | columnActivity_ = rhs.columnActivity_; |
929 | | dual_ = rhs.dual_; |
930 | | reducedCost_ = rhs.reducedCost_; |
931 | | rowLower_ = rhs.rowLower_; |
932 | | rowUpper_ = rhs.rowUpper_; |
933 | | objective_ = rhs.objective_; |
934 | | rowObjective_ = rhs.rowObjective_; |
935 | | columnLower_ = rhs.columnLower_; |
936 | | columnUpper_ = rhs.columnUpper_; |
937 | | matrix_ = rhs.matrix_; |
938 | | rowCopy_ = NULL; |
939 | | scaledMatrix_ = NULL; |
940 | | ray_ = rhs.ray_; |
941 | | //rowScale_ = rhs.rowScale_; |
942 | | //columnScale_ = rhs.columnScale_; |
943 | | lengthNames_ = 0; |
944 | | numberThreads_ = rhs.numberThreads_; |
| 777 | lengthNames_ = rhs.lengthNames_; |
| 778 | if (lengthNames_) { |
| 779 | rowNames_ = rhs.rowNames_; |
| 780 | columnNames_ = rhs.columnNames_; |
| 781 | } |
| 782 | #endif |
| 783 | numberThreads_ = rhs.numberThreads_; |
| 784 | if (maximumRows_ < 0) { |
| 785 | specialOptions_ &= ~65536; |
| 786 | savedRowScale_ = NULL; |
| 787 | savedColumnScale_ = NULL; |
| 788 | integerType_ = CoinCopyOfArray(rhs.integerType_, numberColumns_); |
| 789 | rowActivity_ = ClpCopyOfArray(rhs.rowActivity_, numberRows_); |
| 790 | columnActivity_ = ClpCopyOfArray(rhs.columnActivity_, numberColumns_); |
| 791 | dual_ = ClpCopyOfArray(rhs.dual_, numberRows_); |
| 792 | reducedCost_ = ClpCopyOfArray(rhs.reducedCost_, numberColumns_); |
| 793 | rowLower_ = ClpCopyOfArray(rhs.rowLower_, numberRows_); |
| 794 | rowUpper_ = ClpCopyOfArray(rhs.rowUpper_, numberRows_); |
| 795 | columnLower_ = ClpCopyOfArray(rhs.columnLower_, numberColumns_); |
| 796 | columnUpper_ = ClpCopyOfArray(rhs.columnUpper_, numberColumns_); |
| 797 | rowScale_ = ClpCopyOfArray(rhs.rowScale_, numberRows_ * 2); |
| 798 | columnScale_ = ClpCopyOfArray(rhs.columnScale_, numberColumns_ * 2); |
| 799 | if (rhs.objective_) |
| 800 | objective_ = rhs.objective_->clone(); |
| 801 | else |
| 802 | objective_ = NULL; |
| 803 | rowObjective_ = ClpCopyOfArray(rhs.rowObjective_, numberRows_); |
| 804 | status_ = ClpCopyOfArray(rhs.status_, numberColumns_ + numberRows_); |
| 805 | ray_ = NULL; |
| 806 | if (problemStatus_ == 1) |
| 807 | ray_ = ClpCopyOfArray(rhs.ray_, numberRows_); |
| 808 | else if (problemStatus_ == 2) |
| 809 | ray_ = ClpCopyOfArray(rhs.ray_, numberColumns_); |
| 810 | if (rhs.rowCopy_) { |
| 811 | rowCopy_ = rhs.rowCopy_->clone(); |
| 812 | } else { |
| 813 | rowCopy_ = NULL; |
| 814 | } |
| 815 | if (rhs.scaledMatrix_) { |
| 816 | scaledMatrix_ = new ClpPackedMatrix(*rhs.scaledMatrix_); |
| 817 | } else { |
| 818 | scaledMatrix_ = NULL; |
| 819 | } |
| 820 | matrix_ = NULL; |
| 821 | if (rhs.matrix_) { |
| 822 | matrix_ = rhs.matrix_->clone(); |
| 823 | } |
| 824 | } else { |
| 825 | // This already has arrays - just copy |
| 826 | savedRowScale_ = NULL; |
| 827 | savedColumnScale_ = NULL; |
| 828 | startPermanentArrays(); |
| 829 | if (rhs.integerType_) { |
| 830 | assert(integerType_); |
| 831 | ClpDisjointCopyN(rhs.integerType_, numberColumns_, integerType_); |
| 832 | } else { |
| 833 | integerType_ = NULL; |
| 834 | } |
| 835 | if (rhs.rowActivity_) { |
| 836 | ClpDisjointCopyN(rhs.rowActivity_, numberRows_, |
| 837 | rowActivity_); |
| 838 | ClpDisjointCopyN(rhs.columnActivity_, numberColumns_, |
| 839 | columnActivity_); |
| 840 | ClpDisjointCopyN(rhs.dual_, numberRows_, |
| 841 | dual_); |
| 842 | ClpDisjointCopyN(rhs.reducedCost_, numberColumns_, |
| 843 | reducedCost_); |
| 844 | } else { |
| 845 | rowActivity_ = NULL; |
| 846 | columnActivity_ = NULL; |
| 847 | dual_ = NULL; |
| 848 | reducedCost_ = NULL; |
| 849 | } |
| 850 | ClpDisjointCopyN(rhs.rowLower_, numberRows_, rowLower_); |
| 851 | ClpDisjointCopyN(rhs.rowUpper_, numberRows_, rowUpper_); |
| 852 | ClpDisjointCopyN(rhs.columnLower_, numberColumns_, columnLower_); |
| 853 | assert((specialOptions_ & 131072) == 0); |
| 854 | abort(); |
| 855 | ClpDisjointCopyN(rhs.columnUpper_, numberColumns_, columnUpper_); |
| 856 | if (rhs.objective_) { |
| 857 | abort(); //check if same |
| 858 | objective_ = rhs.objective_->clone(); |
| 859 | } else { |
| 860 | objective_ = NULL; |
| 861 | } |
| 862 | assert(!rhs.rowObjective_); |
| 863 | ClpDisjointCopyN(rhs.status_, numberColumns_ + numberRows_, status_); |
| 864 | ray_ = NULL; |
| 865 | if (problemStatus_ == 1) |
| 866 | ray_ = ClpCopyOfArray(rhs.ray_, numberRows_); |
| 867 | else if (problemStatus_ == 2) |
| 868 | ray_ = ClpCopyOfArray(rhs.ray_, numberColumns_); |
| 869 | assert(!ray_); |
| 870 | delete rowCopy_; |
| 871 | if (rhs.rowCopy_) { |
| 872 | rowCopy_ = rhs.rowCopy_->clone(); |
| 873 | } else { |
| 874 | rowCopy_ = NULL; |
| 875 | } |
| 876 | delete scaledMatrix_; |
| 877 | if (rhs.scaledMatrix_) { |
| 878 | scaledMatrix_ = new ClpPackedMatrix(*rhs.scaledMatrix_); |
| 879 | } else { |
| 880 | scaledMatrix_ = NULL; |
| 881 | } |
| 882 | delete matrix_; |
| 883 | matrix_ = NULL; |
| 884 | if (rhs.matrix_) { |
| 885 | matrix_ = rhs.matrix_->clone(); |
| 886 | } |
| 887 | if (rhs.savedRowScale_) { |
| 888 | assert(savedRowScale_); |
| 889 | assert(!rowScale_); |
| 890 | ClpDisjointCopyN(rhs.savedRowScale_, 4 * maximumInternalRows_, savedRowScale_); |
| 891 | ClpDisjointCopyN(rhs.savedColumnScale_, 4 * maximumInternalColumns_, savedColumnScale_); |
| 892 | } else { |
| 893 | assert(!savedRowScale_); |
| 894 | if (rowScale_) { |
| 895 | ClpDisjointCopyN(rhs.rowScale_, numberRows_, rowScale_); |
| 896 | ClpDisjointCopyN(rhs.columnScale_, numberColumns_, columnScale_); |
| 897 | } else { |
| 898 | rowScale_ = NULL; |
| 899 | columnScale_ = NULL; |
| 900 | } |
| 901 | } |
| 902 | abort(); // look at resizeDouble and resize |
| 903 | } |
| 904 | } else { |
| 905 | savedRowScale_ = rhs.savedRowScale_; |
| 906 | assert(!savedRowScale_); |
| 907 | savedColumnScale_ = rhs.savedColumnScale_; |
| 908 | rowActivity_ = rhs.rowActivity_; |
| 909 | columnActivity_ = rhs.columnActivity_; |
| 910 | dual_ = rhs.dual_; |
| 911 | reducedCost_ = rhs.reducedCost_; |
| 912 | rowLower_ = rhs.rowLower_; |
| 913 | rowUpper_ = rhs.rowUpper_; |
| 914 | objective_ = rhs.objective_; |
| 915 | rowObjective_ = rhs.rowObjective_; |
| 916 | columnLower_ = rhs.columnLower_; |
| 917 | columnUpper_ = rhs.columnUpper_; |
| 918 | matrix_ = rhs.matrix_; |
| 919 | rowCopy_ = NULL; |
| 920 | scaledMatrix_ = NULL; |
| 921 | ray_ = rhs.ray_; |
| 922 | //rowScale_ = rhs.rowScale_; |
| 923 | //columnScale_ = rhs.columnScale_; |
| 924 | lengthNames_ = 0; |
| 925 | numberThreads_ = rhs.numberThreads_; |
1169 | | double * deleteDouble(double * array , int size, |
1170 | | int number, const int * which, int & newSize) |
1171 | | { |
1172 | | if (array) { |
1173 | | int i ; |
1174 | | char * deleted = new char[size]; |
1175 | | int numberDeleted = 0; |
1176 | | CoinZeroN(deleted, size); |
1177 | | for (i = 0; i < number; i++) { |
1178 | | int j = which[i]; |
1179 | | if (j >= 0 && j < size && !deleted[j]) { |
1180 | | numberDeleted++; |
1181 | | deleted[j] = 1; |
1182 | | } |
1183 | | } |
1184 | | newSize = size - numberDeleted; |
1185 | | double * newArray = new double[newSize]; |
1186 | | int put = 0; |
1187 | | for (i = 0; i < size; i++) { |
1188 | | if (!deleted[i]) { |
1189 | | newArray[put++] = array[i]; |
1190 | | } |
1191 | | } |
1192 | | delete [] array; |
1193 | | array = newArray; |
1194 | | delete [] deleted; |
1195 | | } |
1196 | | return array; |
1197 | | } |
1198 | | char * deleteChar(char * array , int size, |
1199 | | int number, const int * which, int & newSize, |
1200 | | bool ifDelete) |
1201 | | { |
1202 | | if (array) { |
1203 | | int i ; |
1204 | | char * deleted = new char[size]; |
1205 | | int numberDeleted = 0; |
1206 | | CoinZeroN(deleted, size); |
1207 | | for (i = 0; i < number; i++) { |
1208 | | int j = which[i]; |
1209 | | if (j >= 0 && j < size && !deleted[j]) { |
1210 | | numberDeleted++; |
1211 | | deleted[j] = 1; |
1212 | | } |
1213 | | } |
1214 | | newSize = size - numberDeleted; |
1215 | | char * newArray = new char[newSize]; |
1216 | | int put = 0; |
1217 | | for (i = 0; i < size; i++) { |
1218 | | if (!deleted[i]) { |
1219 | | newArray[put++] = array[i]; |
1220 | | } |
1221 | | } |
1222 | | if (ifDelete) |
1223 | | delete [] array; |
1224 | | array = newArray; |
1225 | | delete [] deleted; |
1226 | | } |
1227 | | return array; |
| 1144 | double *deleteDouble(double *array, int size, |
| 1145 | int number, const int *which, int &newSize) |
| 1146 | { |
| 1147 | if (array) { |
| 1148 | int i; |
| 1149 | char *deleted = new char[size]; |
| 1150 | int numberDeleted = 0; |
| 1151 | CoinZeroN(deleted, size); |
| 1152 | for (i = 0; i < number; i++) { |
| 1153 | int j = which[i]; |
| 1154 | if (j >= 0 && j < size && !deleted[j]) { |
| 1155 | numberDeleted++; |
| 1156 | deleted[j] = 1; |
| 1157 | } |
| 1158 | } |
| 1159 | newSize = size - numberDeleted; |
| 1160 | double *newArray = new double[newSize]; |
| 1161 | int put = 0; |
| 1162 | for (i = 0; i < size; i++) { |
| 1163 | if (!deleted[i]) { |
| 1164 | newArray[put++] = array[i]; |
| 1165 | } |
| 1166 | } |
| 1167 | delete[] array; |
| 1168 | array = newArray; |
| 1169 | delete[] deleted; |
| 1170 | } |
| 1171 | return array; |
| 1172 | } |
| 1173 | char *deleteChar(char *array, int size, |
| 1174 | int number, const int *which, int &newSize, |
| 1175 | bool ifDelete) |
| 1176 | { |
| 1177 | if (array) { |
| 1178 | int i; |
| 1179 | char *deleted = new char[size]; |
| 1180 | int numberDeleted = 0; |
| 1181 | CoinZeroN(deleted, size); |
| 1182 | for (i = 0; i < number; i++) { |
| 1183 | int j = which[i]; |
| 1184 | if (j >= 0 && j < size && !deleted[j]) { |
| 1185 | numberDeleted++; |
| 1186 | deleted[j] = 1; |
| 1187 | } |
| 1188 | } |
| 1189 | newSize = size - numberDeleted; |
| 1190 | char *newArray = new char[newSize]; |
| 1191 | int put = 0; |
| 1192 | for (i = 0; i < size; i++) { |
| 1193 | if (!deleted[i]) { |
| 1194 | newArray[put++] = array[i]; |
| 1195 | } |
| 1196 | } |
| 1197 | if (ifDelete) |
| 1198 | delete[] array; |
| 1199 | array = newArray; |
| 1200 | delete[] deleted; |
| 1201 | } |
| 1202 | return array; |
1256 | | void |
1257 | | ClpModel::resize (int newNumberRows, int newNumberColumns) |
1258 | | { |
1259 | | if (newNumberRows == numberRows_ && |
1260 | | newNumberColumns == numberColumns_) |
1261 | | return; // nothing to do |
1262 | | whatsChanged_ = 0; |
1263 | | int numberRows2 = newNumberRows; |
1264 | | int numberColumns2 = newNumberColumns; |
1265 | | if (numberRows2 < maximumRows_) |
1266 | | numberRows2 = maximumRows_; |
1267 | | if (numberColumns2 < maximumColumns_) |
1268 | | numberColumns2 = maximumColumns_; |
1269 | | if (numberRows2 > maximumRows_) { |
1270 | | rowActivity_ = resizeDouble(rowActivity_, numberRows_, |
1271 | | newNumberRows, 0.0, true); |
1272 | | dual_ = resizeDouble(dual_, numberRows_, |
1273 | | newNumberRows, 0.0, true); |
1274 | | rowObjective_ = resizeDouble(rowObjective_, numberRows_, |
1275 | | newNumberRows, 0.0, false); |
1276 | | rowLower_ = resizeDouble(rowLower_, numberRows_, |
1277 | | newNumberRows, -COIN_DBL_MAX, true); |
1278 | | rowUpper_ = resizeDouble(rowUpper_, numberRows_, |
1279 | | newNumberRows, COIN_DBL_MAX, true); |
1280 | | } |
1281 | | if (numberColumns2 > maximumColumns_) { |
1282 | | columnActivity_ = resizeDouble(columnActivity_, numberColumns_, |
1283 | | newNumberColumns, 0.0, true); |
1284 | | reducedCost_ = resizeDouble(reducedCost_, numberColumns_, |
1285 | | newNumberColumns, 0.0, true); |
1286 | | } |
1287 | | if (savedRowScale_ && numberRows2 > maximumInternalRows_) { |
1288 | | double * temp; |
1289 | | temp = new double [4*newNumberRows]; |
1290 | | CoinFillN(temp, 4 * newNumberRows, 1.0); |
1291 | | CoinMemcpyN(savedRowScale_, numberRows_, temp); |
1292 | | CoinMemcpyN(savedRowScale_ + maximumInternalRows_, numberRows_, temp + newNumberRows); |
1293 | | CoinMemcpyN(savedRowScale_ + 2 * maximumInternalRows_, numberRows_, temp + 2 * newNumberRows); |
1294 | | CoinMemcpyN(savedRowScale_ + 3 * maximumInternalRows_, numberRows_, temp + 3 * newNumberRows); |
1295 | | delete [] savedRowScale_; |
1296 | | savedRowScale_ = temp; |
1297 | | } |
1298 | | if (savedColumnScale_ && numberColumns2 > maximumInternalColumns_) { |
1299 | | double * temp; |
1300 | | temp = new double [4*newNumberColumns]; |
1301 | | CoinFillN(temp, 4 * newNumberColumns, 1.0); |
1302 | | CoinMemcpyN(savedColumnScale_, numberColumns_, temp); |
1303 | | CoinMemcpyN(savedColumnScale_ + maximumInternalColumns_, numberColumns_, temp + newNumberColumns); |
1304 | | CoinMemcpyN(savedColumnScale_ + 2 * maximumInternalColumns_, numberColumns_, temp + 2 * newNumberColumns); |
1305 | | CoinMemcpyN(savedColumnScale_ + 3 * maximumInternalColumns_, numberColumns_, temp + 3 * newNumberColumns); |
1306 | | delete [] savedColumnScale_; |
1307 | | savedColumnScale_ = temp; |
1308 | | } |
1309 | | if (objective_ && numberColumns2 > maximumColumns_) |
1310 | | objective_->resize(newNumberColumns); |
1311 | | else if (!objective_) |
1312 | | objective_ = new ClpLinearObjective(NULL, newNumberColumns); |
1313 | | if (numberColumns2 > maximumColumns_) { |
1314 | | columnLower_ = resizeDouble(columnLower_, numberColumns_, |
1315 | | newNumberColumns, 0.0, true); |
1316 | | columnUpper_ = resizeDouble(columnUpper_, numberColumns_, |
1317 | | newNumberColumns, COIN_DBL_MAX, true); |
1318 | | } |
1319 | | if (newNumberRows < numberRows_) { |
1320 | | int * which = new int[numberRows_-newNumberRows]; |
1321 | | int i; |
1322 | | for (i = newNumberRows; i < numberRows_; i++) |
1323 | | which[i-newNumberRows] = i; |
1324 | | matrix_->deleteRows(numberRows_ - newNumberRows, which); |
1325 | | delete [] which; |
1326 | | } |
1327 | | if (numberRows_ != newNumberRows || numberColumns_ != newNumberColumns) { |
1328 | | // set state back to unknown |
1329 | | problemStatus_ = -1; |
1330 | | secondaryStatus_ = 0; |
1331 | | delete [] ray_; |
1332 | | ray_ = NULL; |
1333 | | } |
1334 | | setRowScale(NULL); |
1335 | | setColumnScale(NULL); |
1336 | | if (status_) { |
1337 | | if (newNumberColumns + newNumberRows) { |
1338 | | if (newNumberColumns + newNumberRows > maximumRows_ + maximumColumns_) { |
1339 | | unsigned char * tempC = new unsigned char [newNumberColumns+newNumberRows]; |
1340 | | unsigned char * tempR = tempC + newNumberColumns; |
1341 | | memset(tempC, 3, newNumberColumns * sizeof(unsigned char)); |
1342 | | memset(tempR, 1, newNumberRows * sizeof(unsigned char)); |
1343 | | CoinMemcpyN(status_, CoinMin(newNumberColumns, numberColumns_), tempC); |
1344 | | CoinMemcpyN(status_ + numberColumns_, CoinMin(newNumberRows, numberRows_), tempR); |
1345 | | delete [] status_; |
1346 | | status_ = tempC; |
1347 | | } else if (newNumberColumns < numberColumns_) { |
1348 | | memmove(status_ + newNumberColumns, status_ + numberColumns_, |
1349 | | newNumberRows); |
1350 | | } else if (newNumberColumns > numberColumns_) { |
1351 | | memset(status_ + numberColumns_, 3, newNumberColumns - numberColumns_); |
1352 | | memmove(status_ + newNumberColumns, status_ + numberColumns_, |
1353 | | newNumberRows); |
1354 | | } |
1355 | | } else { |
1356 | | // empty model - some systems don't like new [0] |
1357 | | delete [] status_; |
1358 | | status_ = NULL; |
1359 | | } |
1360 | | } |
| 1230 | void ClpModel::resize(int newNumberRows, int newNumberColumns) |
| 1231 | { |
| 1232 | if (newNumberRows == numberRows_ && newNumberColumns == numberColumns_) |
| 1233 | return; // nothing to do |
| 1234 | whatsChanged_ = 0; |
| 1235 | int numberRows2 = newNumberRows; |
| 1236 | int numberColumns2 = newNumberColumns; |
| 1237 | if (numberRows2 < maximumRows_) |
| 1238 | numberRows2 = maximumRows_; |
| 1239 | if (numberColumns2 < maximumColumns_) |
| 1240 | numberColumns2 = maximumColumns_; |
| 1241 | if (numberRows2 > maximumRows_) { |
| 1242 | rowActivity_ = resizeDouble(rowActivity_, numberRows_, |
| 1243 | newNumberRows, 0.0, true); |
| 1244 | dual_ = resizeDouble(dual_, numberRows_, |
| 1245 | newNumberRows, 0.0, true); |
| 1246 | rowObjective_ = resizeDouble(rowObjective_, numberRows_, |
| 1247 | newNumberRows, 0.0, false); |
| 1248 | rowLower_ = resizeDouble(rowLower_, numberRows_, |
| 1249 | newNumberRows, -COIN_DBL_MAX, true); |
| 1250 | rowUpper_ = resizeDouble(rowUpper_, numberRows_, |
| 1251 | newNumberRows, COIN_DBL_MAX, true); |
| 1252 | } |
| 1253 | if (numberColumns2 > maximumColumns_) { |
| 1254 | columnActivity_ = resizeDouble(columnActivity_, numberColumns_, |
| 1255 | newNumberColumns, 0.0, true); |
| 1256 | reducedCost_ = resizeDouble(reducedCost_, numberColumns_, |
| 1257 | newNumberColumns, 0.0, true); |
| 1258 | } |
| 1259 | if (savedRowScale_ && numberRows2 > maximumInternalRows_) { |
| 1260 | double *temp; |
| 1261 | temp = new double[4 * newNumberRows]; |
| 1262 | CoinFillN(temp, 4 * newNumberRows, 1.0); |
| 1263 | CoinMemcpyN(savedRowScale_, numberRows_, temp); |
| 1264 | CoinMemcpyN(savedRowScale_ + maximumInternalRows_, numberRows_, temp + newNumberRows); |
| 1265 | CoinMemcpyN(savedRowScale_ + 2 * maximumInternalRows_, numberRows_, temp + 2 * newNumberRows); |
| 1266 | CoinMemcpyN(savedRowScale_ + 3 * maximumInternalRows_, numberRows_, temp + 3 * newNumberRows); |
| 1267 | delete[] savedRowScale_; |
| 1268 | savedRowScale_ = temp; |
| 1269 | } |
| 1270 | if (savedColumnScale_ && numberColumns2 > maximumInternalColumns_) { |
| 1271 | double *temp; |
| 1272 | temp = new double[4 * newNumberColumns]; |
| 1273 | CoinFillN(temp, 4 * newNumberColumns, 1.0); |
| 1274 | CoinMemcpyN(savedColumnScale_, numberColumns_, temp); |
| 1275 | CoinMemcpyN(savedColumnScale_ + maximumInternalColumns_, numberColumns_, temp + newNumberColumns); |
| 1276 | CoinMemcpyN(savedColumnScale_ + 2 * maximumInternalColumns_, numberColumns_, temp + 2 * newNumberColumns); |
| 1277 | CoinMemcpyN(savedColumnScale_ + 3 * maximumInternalColumns_, numberColumns_, temp + 3 * newNumberColumns); |
| 1278 | delete[] savedColumnScale_; |
| 1279 | savedColumnScale_ = temp; |
| 1280 | } |
| 1281 | if (objective_ && numberColumns2 > maximumColumns_) |
| 1282 | objective_->resize(newNumberColumns); |
| 1283 | else if (!objective_) |
| 1284 | objective_ = new ClpLinearObjective(NULL, newNumberColumns); |
| 1285 | if (numberColumns2 > maximumColumns_) { |
| 1286 | columnLower_ = resizeDouble(columnLower_, numberColumns_, |
| 1287 | newNumberColumns, 0.0, true); |
| 1288 | columnUpper_ = resizeDouble(columnUpper_, numberColumns_, |
| 1289 | newNumberColumns, COIN_DBL_MAX, true); |
| 1290 | } |
| 1291 | if (newNumberRows < numberRows_) { |
| 1292 | int *which = new int[numberRows_ - newNumberRows]; |
| 1293 | int i; |
| 1294 | for (i = newNumberRows; i < numberRows_; i++) |
| 1295 | which[i - newNumberRows] = i; |
| 1296 | matrix_->deleteRows(numberRows_ - newNumberRows, which); |
| 1297 | delete[] which; |
| 1298 | } |
| 1299 | if (numberRows_ != newNumberRows || numberColumns_ != newNumberColumns) { |
| 1300 | // set state back to unknown |
| 1301 | problemStatus_ = -1; |
| 1302 | secondaryStatus_ = 0; |
| 1303 | delete[] ray_; |
| 1304 | ray_ = NULL; |
| 1305 | } |
| 1306 | setRowScale(NULL); |
| 1307 | setColumnScale(NULL); |
| 1308 | if (status_) { |
| 1309 | if (newNumberColumns + newNumberRows) { |
| 1310 | if (newNumberColumns + newNumberRows > maximumRows_ + maximumColumns_) { |
| 1311 | unsigned char *tempC = new unsigned char[newNumberColumns + newNumberRows]; |
| 1312 | unsigned char *tempR = tempC + newNumberColumns; |
| 1313 | memset(tempC, 3, newNumberColumns * sizeof(unsigned char)); |
| 1314 | memset(tempR, 1, newNumberRows * sizeof(unsigned char)); |
| 1315 | CoinMemcpyN(status_, CoinMin(newNumberColumns, numberColumns_), tempC); |
| 1316 | CoinMemcpyN(status_ + numberColumns_, CoinMin(newNumberRows, numberRows_), tempR); |
| 1317 | delete[] status_; |
| 1318 | status_ = tempC; |
| 1319 | } else if (newNumberColumns < numberColumns_) { |
| 1320 | memmove(status_ + newNumberColumns, status_ + numberColumns_, |
| 1321 | newNumberRows); |
| 1322 | } else if (newNumberColumns > numberColumns_) { |
| 1323 | memset(status_ + numberColumns_, 3, newNumberColumns - numberColumns_); |
| 1324 | memmove(status_ + newNumberColumns, status_ + numberColumns_, |
| 1325 | newNumberRows); |
| 1326 | } |
| 1327 | } else { |
| 1328 | // empty model - some systems don't like new [0] |
| 1329 | delete[] status_; |
| 1330 | status_ = NULL; |
| 1331 | } |
| 1332 | } |
1362 | | if (lengthNames_) { |
1363 | | // redo row and column names (make sure clean) |
1364 | | int numberRowNames = |
1365 | | CoinMin(static_cast<int>(rowNames_.size()),numberRows_); |
1366 | | if (numberRowNames < newNumberRows) { |
1367 | | rowNames_.resize(newNumberRows); |
1368 | | lengthNames_ = CoinMax(lengthNames_, 8); |
1369 | | char name[10]; |
1370 | | for (unsigned int iRow = numberRowNames; iRow < newNumberRows; iRow++) { |
1371 | | sprintf(name, "R%7.7d", iRow); |
1372 | | rowNames_[iRow] = name; |
1373 | | } |
1374 | | } |
1375 | | int numberColumnNames = |
1376 | | CoinMin(static_cast<int>(columnNames_.size()),numberColumns_); |
1377 | | if (numberColumnNames < newNumberColumns) { |
1378 | | columnNames_.resize(newNumberColumns); |
1379 | | lengthNames_ = CoinMax(lengthNames_, 8); |
1380 | | char name[10]; |
1381 | | for (unsigned int iColumn = numberColumnNames; |
1382 | | iColumn < newNumberColumns; iColumn++) { |
1383 | | sprintf(name, "C%7.7d", iColumn); |
1384 | | columnNames_[iColumn] = name; |
1385 | | } |
1386 | | } |
1387 | | } |
1388 | | #endif |
1389 | | numberRows_ = newNumberRows; |
1390 | | if (newNumberColumns < numberColumns_ && matrix_->getNumCols()) { |
1391 | | int * which = new int[numberColumns_-newNumberColumns]; |
1392 | | int i; |
1393 | | for (i = newNumberColumns; i < numberColumns_; i++) |
1394 | | which[i-newNumberColumns] = i; |
1395 | | matrix_->deleteCols(numberColumns_ - newNumberColumns, which); |
1396 | | delete [] which; |
1397 | | } |
1398 | | if (integerType_ && numberColumns2 > maximumColumns_) { |
1399 | | char * temp = new char [newNumberColumns]; |
1400 | | CoinZeroN(temp, newNumberColumns); |
1401 | | CoinMemcpyN(integerType_, |
1402 | | CoinMin(newNumberColumns, numberColumns_), temp); |
1403 | | delete [] integerType_; |
1404 | | integerType_ = temp; |
1405 | | } |
1406 | | numberColumns_ = newNumberColumns; |
1407 | | if ((specialOptions_ & 65536) != 0) { |
1408 | | // leave until next create rim to up numbers |
1409 | | } |
1410 | | if (maximumRows_ >= 0) { |
1411 | | if (numberRows_ > maximumRows_) |
1412 | | COIN_DETAIL_PRINT(printf("resize %d rows, %d old maximum rows\n", |
1413 | | numberRows_, maximumRows_)); |
1414 | | maximumRows_ = CoinMax(maximumRows_, numberRows_); |
1415 | | maximumColumns_ = CoinMax(maximumColumns_, numberColumns_); |
1416 | | } |
| 1334 | if (lengthNames_) { |
| 1335 | // redo row and column names (make sure clean) |
| 1336 | int numberRowNames = CoinMin(static_cast< int >(rowNames_.size()), numberRows_); |
| 1337 | if (numberRowNames < newNumberRows) { |
| 1338 | rowNames_.resize(newNumberRows); |
| 1339 | lengthNames_ = CoinMax(lengthNames_, 8); |
| 1340 | char name[10]; |
| 1341 | for (unsigned int iRow = numberRowNames; iRow < newNumberRows; iRow++) { |
| 1342 | sprintf(name, "R%7.7d", iRow); |
| 1343 | rowNames_[iRow] = name; |
| 1344 | } |
| 1345 | } |
| 1346 | int numberColumnNames = CoinMin(static_cast< int >(columnNames_.size()), numberColumns_); |
| 1347 | if (numberColumnNames < newNumberColumns) { |
| 1348 | columnNames_.resize(newNumberColumns); |
| 1349 | lengthNames_ = CoinMax(lengthNames_, 8); |
| 1350 | char name[10]; |
| 1351 | for (unsigned int iColumn = numberColumnNames; |
| 1352 | iColumn < newNumberColumns; iColumn++) { |
| 1353 | sprintf(name, "C%7.7d", iColumn); |
| 1354 | columnNames_[iColumn] = name; |
| 1355 | } |
| 1356 | } |
| 1357 | } |
| 1358 | #endif |
| 1359 | numberRows_ = newNumberRows; |
| 1360 | if (newNumberColumns < numberColumns_ && matrix_->getNumCols()) { |
| 1361 | int *which = new int[numberColumns_ - newNumberColumns]; |
| 1362 | int i; |
| 1363 | for (i = newNumberColumns; i < numberColumns_; i++) |
| 1364 | which[i - newNumberColumns] = i; |
| 1365 | matrix_->deleteCols(numberColumns_ - newNumberColumns, which); |
| 1366 | delete[] which; |
| 1367 | } |
| 1368 | if (integerType_ && numberColumns2 > maximumColumns_) { |
| 1369 | char *temp = new char[newNumberColumns]; |
| 1370 | CoinZeroN(temp, newNumberColumns); |
| 1371 | CoinMemcpyN(integerType_, |
| 1372 | CoinMin(newNumberColumns, numberColumns_), temp); |
| 1373 | delete[] integerType_; |
| 1374 | integerType_ = temp; |
| 1375 | } |
| 1376 | numberColumns_ = newNumberColumns; |
| 1377 | if ((specialOptions_ & 65536) != 0) { |
| 1378 | // leave until next create rim to up numbers |
| 1379 | } |
| 1380 | if (maximumRows_ >= 0) { |
| 1381 | if (numberRows_ > maximumRows_) |
| 1382 | COIN_DETAIL_PRINT(printf("resize %d rows, %d old maximum rows\n", |
| 1383 | numberRows_, maximumRows_)); |
| 1384 | maximumRows_ = CoinMax(maximumRows_, numberRows_); |
| 1385 | maximumColumns_ = CoinMax(maximumColumns_, numberColumns_); |
| 1386 | } |
1428 | | if (status_) { |
1429 | | // try and get right number of basic |
1430 | | int nChange=0; |
1431 | | unsigned char * rowStatus = status_+numberColumns_; |
1432 | | for (int i=0;i<number;i++) { |
1433 | | int iRow = which[i]; |
1434 | | if ((rowStatus[iRow]&7) !=1) |
1435 | | nChange++; |
1436 | | } |
1437 | | // take out slacks at bound |
1438 | | for (int iRow=0;iRow<numberRows_;iRow++) { |
1439 | | if (!nChange) |
1440 | | break; |
1441 | | if ((rowStatus[iRow]&7) ==1) { |
1442 | | if (fabs(rowActivity_[iRow]-rowLower_[iRow])<1.0e-8) { |
1443 | | rowStatus[iRow]=3; |
1444 | | nChange--; |
1445 | | } else if (fabs(rowActivity_[iRow]-rowUpper_[iRow])<1.0e-8) { |
1446 | | rowStatus[iRow]=2; |
1447 | | nChange--; |
1448 | | } |
1449 | | } |
1450 | | } |
1451 | | } |
1452 | | #endif |
1453 | | if (maximumRows_ < 0) { |
1454 | | rowActivity_ = deleteDouble(rowActivity_, numberRows_, |
1455 | | number, which, newSize); |
1456 | | dual_ = deleteDouble(dual_, numberRows_, |
1457 | | number, which, newSize); |
1458 | | rowObjective_ = deleteDouble(rowObjective_, numberRows_, |
1459 | | number, which, newSize); |
1460 | | rowLower_ = deleteDouble(rowLower_, numberRows_, |
1461 | | number, which, newSize); |
1462 | | rowUpper_ = deleteDouble(rowUpper_, numberRows_, |
1463 | | number, which, newSize); |
1464 | | if (matrix_->getNumRows()) |
1465 | | matrix_->deleteRows(number, which); |
1466 | | //matrix_->removeGaps(); |
1467 | | // status |
1468 | | if (status_) { |
1469 | | if (numberColumns_ + newSize) { |
1470 | | unsigned char * tempR = reinterpret_cast<unsigned char *> |
1471 | | (deleteChar(reinterpret_cast<char *>(status_) + numberColumns_, |
1472 | | numberRows_, |
1473 | | number, which, newSize, false)); |
1474 | | unsigned char * tempC = new unsigned char [numberColumns_+newSize]; |
1475 | | CoinMemcpyN(status_, numberColumns_, tempC); |
1476 | | CoinMemcpyN(tempR, newSize, tempC + numberColumns_); |
1477 | | delete [] tempR; |
1478 | | delete [] status_; |
1479 | | status_ = tempC; |
1480 | | } else { |
1481 | | // empty model - some systems don't like new [0] |
1482 | | delete [] status_; |
1483 | | status_ = NULL; |
1484 | | } |
1485 | | } |
1486 | | } else { |
1487 | | char * deleted = new char [numberRows_]; |
1488 | | int i; |
1489 | | int numberDeleted = 0; |
1490 | | CoinZeroN(deleted, numberRows_); |
1491 | | for (i = 0; i < number; i++) { |
1492 | | int j = which[i]; |
1493 | | if (j >= 0 && j < numberRows_ && !deleted[j]) { |
1494 | | numberDeleted++; |
1495 | | deleted[j] = 1; |
1496 | | } |
1497 | | } |
1498 | | assert (!rowObjective_); |
1499 | | unsigned char * status2 = status_ + numberColumns_; |
1500 | | for (i = 0; i < numberRows_; i++) { |
1501 | | if (!deleted[i]) { |
1502 | | rowActivity_[newSize] = rowActivity_[i]; |
1503 | | dual_[newSize] = dual_[i]; |
1504 | | rowLower_[newSize] = rowLower_[i]; |
1505 | | rowUpper_[newSize] = rowUpper_[i]; |
1506 | | status2[newSize] = status2[i]; |
1507 | | newSize++; |
1508 | | } |
1509 | | } |
1510 | | if (matrix_->getNumRows()) |
1511 | | matrix_->deleteRows(number, which); |
1512 | | //matrix_->removeGaps(); |
1513 | | delete [] deleted; |
1514 | | } |
| 1397 | if (status_) { |
| 1398 | // try and get right number of basic |
| 1399 | int nChange = 0; |
| 1400 | unsigned char *rowStatus = status_ + numberColumns_; |
| 1401 | for (int i = 0; i < number; i++) { |
| 1402 | int iRow = which[i]; |
| 1403 | if ((rowStatus[iRow] & 7) != 1) |
| 1404 | nChange++; |
| 1405 | } |
| 1406 | // take out slacks at bound |
| 1407 | for (int iRow = 0; iRow < numberRows_; iRow++) { |
| 1408 | if (!nChange) |
| 1409 | break; |
| 1410 | if ((rowStatus[iRow] & 7) == 1) { |
| 1411 | if (fabs(rowActivity_[iRow] - rowLower_[iRow]) < 1.0e-8) { |
| 1412 | rowStatus[iRow] = 3; |
| 1413 | nChange--; |
| 1414 | } else if (fabs(rowActivity_[iRow] - rowUpper_[iRow]) < 1.0e-8) { |
| 1415 | rowStatus[iRow] = 2; |
| 1416 | nChange--; |
| 1417 | } |
| 1418 | } |
| 1419 | } |
| 1420 | } |
| 1421 | #endif |
| 1422 | if (maximumRows_ < 0) { |
| 1423 | rowActivity_ = deleteDouble(rowActivity_, numberRows_, |
| 1424 | number, which, newSize); |
| 1425 | dual_ = deleteDouble(dual_, numberRows_, |
| 1426 | number, which, newSize); |
| 1427 | rowObjective_ = deleteDouble(rowObjective_, numberRows_, |
| 1428 | number, which, newSize); |
| 1429 | rowLower_ = deleteDouble(rowLower_, numberRows_, |
| 1430 | number, which, newSize); |
| 1431 | rowUpper_ = deleteDouble(rowUpper_, numberRows_, |
| 1432 | number, which, newSize); |
| 1433 | if (matrix_->getNumRows()) |
| 1434 | matrix_->deleteRows(number, which); |
| 1435 | //matrix_->removeGaps(); |
| 1436 | // status |
| 1437 | if (status_) { |
| 1438 | if (numberColumns_ + newSize) { |
| 1439 | unsigned char *tempR = reinterpret_cast< unsigned char * >(deleteChar(reinterpret_cast< char * >(status_) + numberColumns_, |
| 1440 | numberRows_, |
| 1441 | number, which, newSize, false)); |
| 1442 | unsigned char *tempC = new unsigned char[numberColumns_ + newSize]; |
| 1443 | CoinMemcpyN(status_, numberColumns_, tempC); |
| 1444 | CoinMemcpyN(tempR, newSize, tempC + numberColumns_); |
| 1445 | delete[] tempR; |
| 1446 | delete[] status_; |
| 1447 | status_ = tempC; |
| 1448 | } else { |
| 1449 | // empty model - some systems don't like new [0] |
| 1450 | delete[] status_; |
| 1451 | status_ = NULL; |
| 1452 | } |
| 1453 | } |
| 1454 | } else { |
| 1455 | char *deleted = new char[numberRows_]; |
| 1456 | int i; |
| 1457 | int numberDeleted = 0; |
| 1458 | CoinZeroN(deleted, numberRows_); |
| 1459 | for (i = 0; i < number; i++) { |
| 1460 | int j = which[i]; |
| 1461 | if (j >= 0 && j < numberRows_ && !deleted[j]) { |
| 1462 | numberDeleted++; |
| 1463 | deleted[j] = 1; |
| 1464 | } |
| 1465 | } |
| 1466 | assert(!rowObjective_); |
| 1467 | unsigned char *status2 = status_ + numberColumns_; |
| 1468 | for (i = 0; i < numberRows_; i++) { |
| 1469 | if (!deleted[i]) { |
| 1470 | rowActivity_[newSize] = rowActivity_[i]; |
| 1471 | dual_[newSize] = dual_[i]; |
| 1472 | rowLower_[newSize] = rowLower_[i]; |
| 1473 | rowUpper_[newSize] = rowUpper_[i]; |
| 1474 | status2[newSize] = status2[i]; |
| 1475 | newSize++; |
| 1476 | } |
| 1477 | } |
| 1478 | if (matrix_->getNumRows()) |
| 1479 | matrix_->deleteRows(number, which); |
| 1480 | //matrix_->removeGaps(); |
| 1481 | delete[] deleted; |
| 1482 | } |
1548 | | void |
1549 | | ClpModel::deleteColumns(int number, const int * which) |
1550 | | { |
1551 | | if (!number) |
1552 | | return; // nothing to do |
1553 | | assert (maximumColumns_ < 0); |
1554 | | whatsChanged_ &= ~(1 + 2 + 4 + 8 + 64 + 128 + 256); // all except rows changed |
1555 | | int newSize = 0; |
1556 | | columnActivity_ = deleteDouble(columnActivity_, numberColumns_, |
1557 | | number, which, newSize); |
1558 | | reducedCost_ = deleteDouble(reducedCost_, numberColumns_, |
1559 | | number, which, newSize); |
1560 | | objective_->deleteSome(number, which); |
1561 | | columnLower_ = deleteDouble(columnLower_, numberColumns_, |
1562 | | number, which, newSize); |
1563 | | columnUpper_ = deleteDouble(columnUpper_, numberColumns_, |
1564 | | number, which, newSize); |
1565 | | // possible matrix is not full |
1566 | | if (matrix_->getNumCols() < numberColumns_) { |
1567 | | int * which2 = new int [number]; |
1568 | | int n = 0; |
1569 | | int nMatrix = matrix_->getNumCols(); |
1570 | | for (int i = 0; i < number; i++) { |
1571 | | if (which[i] < nMatrix) |
1572 | | which2[n++] = which[i]; |
1573 | | } |
1574 | | matrix_->deleteCols(n, which2); |
1575 | | delete [] which2; |
1576 | | } else { |
1577 | | matrix_->deleteCols(number, which); |
1578 | | } |
1579 | | //matrix_->removeGaps(); |
1580 | | // status |
1581 | | if (status_) { |
1582 | | if (numberRows_ + newSize) { |
1583 | | unsigned char * tempC = reinterpret_cast<unsigned char *> |
1584 | | (deleteChar(reinterpret_cast<char *>(status_), |
1585 | | numberColumns_, |
1586 | | number, which, newSize, false)); |
1587 | | unsigned char * temp = new unsigned char [numberRows_+newSize]; |
1588 | | CoinMemcpyN(tempC, newSize, temp); |
1589 | | CoinMemcpyN(status_ + numberColumns_, numberRows_, temp + newSize); |
1590 | | delete [] tempC; |
1591 | | delete [] status_; |
1592 | | status_ = temp; |
1593 | | } else { |
1594 | | // empty model - some systems don't like new [0] |
1595 | | delete [] status_; |
1596 | | status_ = NULL; |
1597 | | } |
1598 | | } |
1599 | | integerType_ = deleteChar(integerType_, numberColumns_, |
1600 | | number, which, newSize, true); |
| 1516 | void ClpModel::deleteColumns(int number, const int *which) |
| 1517 | { |
| 1518 | if (!number) |
| 1519 | return; // nothing to do |
| 1520 | assert(maximumColumns_ < 0); |
| 1521 | whatsChanged_ &= ~(1 + 2 + 4 + 8 + 64 + 128 + 256); // all except rows changed |
| 1522 | int newSize = 0; |
| 1523 | columnActivity_ = deleteDouble(columnActivity_, numberColumns_, |
| 1524 | number, which, newSize); |
| 1525 | reducedCost_ = deleteDouble(reducedCost_, numberColumns_, |
| 1526 | number, which, newSize); |
| 1527 | objective_->deleteSome(number, which); |
| 1528 | columnLower_ = deleteDouble(columnLower_, numberColumns_, |
| 1529 | number, which, newSize); |
| 1530 | columnUpper_ = deleteDouble(columnUpper_, numberColumns_, |
| 1531 | number, which, newSize); |
| 1532 | // possible matrix is not full |
| 1533 | if (matrix_->getNumCols() < numberColumns_) { |
| 1534 | int *which2 = new int[number]; |
| 1535 | int n = 0; |
| 1536 | int nMatrix = matrix_->getNumCols(); |
| 1537 | for (int i = 0; i < number; i++) { |
| 1538 | if (which[i] < nMatrix) |
| 1539 | which2[n++] = which[i]; |
| 1540 | } |
| 1541 | matrix_->deleteCols(n, which2); |
| 1542 | delete[] which2; |
| 1543 | } else { |
| 1544 | matrix_->deleteCols(number, which); |
| 1545 | } |
| 1546 | //matrix_->removeGaps(); |
| 1547 | // status |
| 1548 | if (status_) { |
| 1549 | if (numberRows_ + newSize) { |
| 1550 | unsigned char *tempC = reinterpret_cast< unsigned char * >(deleteChar(reinterpret_cast< char * >(status_), |
| 1551 | numberColumns_, |
| 1552 | number, which, newSize, false)); |
| 1553 | unsigned char *temp = new unsigned char[numberRows_ + newSize]; |
| 1554 | CoinMemcpyN(tempC, newSize, temp); |
| 1555 | CoinMemcpyN(status_ + numberColumns_, numberRows_, temp + newSize); |
| 1556 | delete[] tempC; |
| 1557 | delete[] status_; |
| 1558 | status_ = temp; |
| 1559 | } else { |
| 1560 | // empty model - some systems don't like new [0] |
| 1561 | delete[] status_; |
| 1562 | status_ = NULL; |
| 1563 | } |
| 1564 | } |
| 1565 | integerType_ = deleteChar(integerType_, numberColumns_, |
| 1566 | number, which, newSize, true); |
1853 | | void |
1854 | | ClpModel::addRows(int number, const double * rowLower, |
1855 | | const double * rowUpper, |
1856 | | const CoinBigIndex * rowStarts, |
1857 | | const int * rowLengths, const int * columns, |
1858 | | const double * elements) |
1859 | | { |
1860 | | if (number) { |
1861 | | CoinBigIndex numberElements = 0; |
1862 | | int iRow; |
1863 | | for (iRow = 0; iRow < number; iRow++) |
1864 | | numberElements += rowLengths[iRow]; |
1865 | | CoinBigIndex * newStarts = new CoinBigIndex[number+1]; |
1866 | | int * newIndex = new int[numberElements]; |
1867 | | double * newElements = new double[numberElements]; |
1868 | | numberElements = 0; |
1869 | | newStarts[0] = 0; |
1870 | | for (iRow = 0; iRow < number; iRow++) { |
1871 | | CoinBigIndex iStart = rowStarts[iRow]; |
1872 | | int length = rowLengths[iRow]; |
1873 | | CoinMemcpyN(columns + iStart, length, newIndex + numberElements); |
1874 | | CoinMemcpyN(elements + iStart, length, newElements + numberElements); |
1875 | | numberElements += length; |
1876 | | newStarts[iRow+1] = numberElements; |
1877 | | } |
1878 | | addRows(number, rowLower, rowUpper, |
1879 | | newStarts, newIndex, newElements); |
1880 | | delete [] newStarts; |
1881 | | delete [] newIndex; |
1882 | | delete [] newElements; |
1883 | | } |
| 1816 | void ClpModel::addRows(int number, const double *rowLower, |
| 1817 | const double *rowUpper, |
| 1818 | const CoinBigIndex *rowStarts, |
| 1819 | const int *rowLengths, const int *columns, |
| 1820 | const double *elements) |
| 1821 | { |
| 1822 | if (number) { |
| 1823 | CoinBigIndex numberElements = 0; |
| 1824 | int iRow; |
| 1825 | for (iRow = 0; iRow < number; iRow++) |
| 1826 | numberElements += rowLengths[iRow]; |
| 1827 | CoinBigIndex *newStarts = new CoinBigIndex[number + 1]; |
| 1828 | int *newIndex = new int[numberElements]; |
| 1829 | double *newElements = new double[numberElements]; |
| 1830 | numberElements = 0; |
| 1831 | newStarts[0] = 0; |
| 1832 | for (iRow = 0; iRow < number; iRow++) { |
| 1833 | CoinBigIndex iStart = rowStarts[iRow]; |
| 1834 | int length = rowLengths[iRow]; |
| 1835 | CoinMemcpyN(columns + iStart, length, newIndex + numberElements); |
| 1836 | CoinMemcpyN(elements + iStart, length, newElements + numberElements); |
| 1837 | numberElements += length; |
| 1838 | newStarts[iRow + 1] = numberElements; |
| 1839 | } |
| 1840 | addRows(number, rowLower, rowUpper, |
| 1841 | newStarts, newIndex, newElements); |
| 1842 | delete[] newStarts; |
| 1843 | delete[] newIndex; |
| 1844 | delete[] newElements; |
| 1845 | } |
1979 | | if (!tryPlusMinusOne) { |
1980 | | CoinBigIndex numberElements = buildObject.numberElements(); |
1981 | | CoinBigIndex * starts = new CoinBigIndex [number+1]; |
1982 | | int * column = new int[numberElements]; |
1983 | | double * element = new double[numberElements]; |
1984 | | starts[0] = 0; |
1985 | | numberElements = 0; |
1986 | | for (iRow = 0; iRow < number; iRow++) { |
1987 | | const int * columns; |
1988 | | const double * elements; |
1989 | | int numberElementsThis = buildObject.row(iRow, lower[iRow], upper[iRow], |
1990 | | columns, elements); |
1991 | | CoinMemcpyN(columns, numberElementsThis, column + numberElements); |
1992 | | CoinMemcpyN(elements, numberElementsThis, element + numberElements); |
1993 | | numberElements += numberElementsThis; |
1994 | | starts[iRow+1] = numberElements; |
1995 | | } |
1996 | | addRows(number, lower, upper, NULL); |
1997 | | // make sure matrix has enough columns |
1998 | | matrix_->setDimensions(-1, numberColumns_); |
1999 | | numberErrors = matrix_->appendMatrix(number, 0, starts, column, element, |
2000 | | checkDuplicates ? numberColumns_ : -1); |
2001 | | delete [] starts; |
2002 | | delete [] column; |
2003 | | delete [] element; |
2004 | | } else { |
2005 | | char * which = NULL; // for duplicates |
2006 | | if (checkDuplicates) { |
2007 | | which = new char[numberColumns_]; |
2008 | | CoinZeroN(which, numberColumns_); |
2009 | | } |
2010 | | // build +-1 matrix |
2011 | | // arrays already filled in |
2012 | | addRows(number, lower, upper, NULL); |
2013 | | CoinBigIndex * startPositive = new CoinBigIndex [numberColumns_+1]; |
2014 | | CoinBigIndex * startNegative = new CoinBigIndex [numberColumns_]; |
2015 | | int * indices = new int [size]; |
2016 | | CoinZeroN(startPositive, numberColumns_); |
2017 | | CoinZeroN(startNegative, numberColumns_); |
2018 | | int maxColumn = -1; |
2019 | | // need two passes |
2020 | | for (iRow = 0; iRow < number; iRow++) { |
2021 | | const int * columns; |
2022 | | const double * elements; |
2023 | | int numberElements = buildObject.row(iRow, lower[iRow], |
2024 | | upper[iRow], |
2025 | | columns, elements); |
2026 | | for (int i = 0; i < numberElements; i++) { |
2027 | | int iColumn = columns[i]; |
2028 | | if (checkDuplicates) { |
2029 | | if (iColumn >= numberColumns_) { |
2030 | | if(which[iColumn]) |
2031 | | numberErrors++; |
2032 | | else |
2033 | | which[iColumn] = 1; |
2034 | | } else { |
2035 | | numberErrors++; |
2036 | | // and may as well switch off |
2037 | | checkDuplicates = false; |
2038 | | } |
2039 | | } |
2040 | | maxColumn = CoinMax(maxColumn, iColumn); |
2041 | | if (elements[i] == 1.0) { |
2042 | | startPositive[iColumn]++; |
2043 | | } else if (elements[i] == -1.0) { |
2044 | | startNegative[iColumn]++; |
2045 | | } |
2046 | | } |
2047 | | if (checkDuplicates) { |
2048 | | for (int i = 0; i < numberElements; i++) { |
2049 | | int iColumn = columns[i]; |
2050 | | which[iColumn] = 0; |
2051 | | } |
2052 | | } |
2053 | | } |
2054 | | // check size |
2055 | | int numberColumns = maxColumn + 1; |
2056 | | CoinAssertHint (numberColumns <= numberColumns_, |
2057 | | "rows having column indices >= numberColumns_"); |
2058 | | size = 0; |
2059 | | int iColumn; |
2060 | | for (iColumn = 0; iColumn < numberColumns_; iColumn++) { |
2061 | | CoinBigIndex n = startPositive[iColumn]; |
2062 | | startPositive[iColumn] = size; |
2063 | | size += n; |
2064 | | n = startNegative[iColumn]; |
2065 | | startNegative[iColumn] = size; |
2066 | | size += n; |
2067 | | } |
2068 | | startPositive[numberColumns_] = size; |
2069 | | for (iRow = 0; iRow < number; iRow++) { |
2070 | | const int * columns; |
2071 | | const double * elements; |
2072 | | int numberElements = buildObject.row(iRow, lower[iRow], |
2073 | | upper[iRow], |
2074 | | columns, elements); |
2075 | | for (int i = 0; i < numberElements; i++) { |
2076 | | int iColumn = columns[i]; |
2077 | | maxColumn = CoinMax(maxColumn, iColumn); |
2078 | | if (elements[i] == 1.0) { |
2079 | | CoinBigIndex position = startPositive[iColumn]; |
2080 | | indices[position] = iRow; |
2081 | | startPositive[iColumn]++; |
2082 | | } else if (elements[i] == -1.0) { |
2083 | | CoinBigIndex position = startNegative[iColumn]; |
2084 | | indices[position] = iRow; |
2085 | | startNegative[iColumn]++; |
2086 | | } |
2087 | | } |
2088 | | } |
2089 | | // and now redo starts |
2090 | | for (iColumn = numberColumns_ - 1; iColumn >= 0; iColumn--) { |
2091 | | startPositive[iColumn+1] = startNegative[iColumn]; |
2092 | | startNegative[iColumn] = startPositive[iColumn]; |
2093 | | } |
2094 | | startPositive[0] = 0; |
2095 | | for (iColumn = 0; iColumn < numberColumns_; iColumn++) { |
2096 | | CoinBigIndex start = startPositive[iColumn]; |
2097 | | CoinBigIndex end = startNegative[iColumn]; |
2098 | | std::sort(indices + start, indices + end); |
2099 | | start = startNegative[iColumn]; |
2100 | | end = startPositive[iColumn+1]; |
2101 | | std::sort(indices + start, indices + end); |
2102 | | } |
2103 | | // Get good object |
2104 | | delete matrix_; |
2105 | | ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix(); |
2106 | | matrix->passInCopy(numberRows_, numberColumns, |
2107 | | true, indices, startPositive, startNegative); |
2108 | | matrix_ = matrix; |
2109 | | delete [] which; |
| 1931 | } |
| 1932 | if (!tryPlusMinusOne) |
| 1933 | break; |
| 1934 | } |
| 1935 | } else { |
| 1936 | // Will add to whatever sort of matrix exists |
| 1937 | tryPlusMinusOne = false; |
| 1938 | } |
| 1939 | if (!tryPlusMinusOne) { |
| 1940 | CoinBigIndex numberElements = buildObject.numberElements(); |
| 1941 | CoinBigIndex *starts = new CoinBigIndex[number + 1]; |
| 1942 | int *column = new int[numberElements]; |
| 1943 | double *element = new double[numberElements]; |
| 1944 | starts[0] = 0; |
| 1945 | numberElements = 0; |
| 1946 | for (iRow = 0; iRow < number; iRow++) { |
| 1947 | const int *columns; |
| 1948 | const double *elements; |
| 1949 | int numberElementsThis = buildObject.row(iRow, lower[iRow], upper[iRow], |
| 1950 | columns, elements); |
| 1951 | CoinMemcpyN(columns, numberElementsThis, column + numberElements); |
| 1952 | CoinMemcpyN(elements, numberElementsThis, element + numberElements); |
| 1953 | numberElements += numberElementsThis; |
| 1954 | starts[iRow + 1] = numberElements; |
| 1955 | } |
| 1956 | addRows(number, lower, upper, NULL); |
| 1957 | // make sure matrix has enough columns |
| 1958 | matrix_->setDimensions(-1, numberColumns_); |
| 1959 | numberErrors = matrix_->appendMatrix(number, 0, starts, column, element, |
| 1960 | checkDuplicates ? numberColumns_ : -1); |
| 1961 | delete[] starts; |
| 1962 | delete[] column; |
| 1963 | delete[] element; |
| 1964 | } else { |
| 1965 | char *which = NULL; // for duplicates |
| 1966 | if (checkDuplicates) { |
| 1967 | which = new char[numberColumns_]; |
| 1968 | CoinZeroN(which, numberColumns_); |
| 1969 | } |
| 1970 | // build +-1 matrix |
| 1971 | // arrays already filled in |
| 1972 | addRows(number, lower, upper, NULL); |
| 1973 | CoinBigIndex *startPositive = new CoinBigIndex[numberColumns_ + 1]; |
| 1974 | CoinBigIndex *startNegative = new CoinBigIndex[numberColumns_]; |
| 1975 | int *indices = new int[size]; |
| 1976 | CoinZeroN(startPositive, numberColumns_); |
| 1977 | CoinZeroN(startNegative, numberColumns_); |
| 1978 | int maxColumn = -1; |
| 1979 | // need two passes |
| 1980 | for (iRow = 0; iRow < number; iRow++) { |
| 1981 | const int *columns; |
| 1982 | const double *elements; |
| 1983 | int numberElements = buildObject.row(iRow, lower[iRow], |
| 1984 | upper[iRow], |
| 1985 | columns, elements); |
| 1986 | for (int i = 0; i < numberElements; i++) { |
| 1987 | int iColumn = columns[i]; |
| 1988 | if (checkDuplicates) { |
| 1989 | if (iColumn >= numberColumns_) { |
| 1990 | if (which[iColumn]) |
| 1991 | numberErrors++; |
| 1992 | else |
| 1993 | which[iColumn] = 1; |
| 1994 | } else { |
| 1995 | numberErrors++; |
| 1996 | // and may as well switch off |
| 1997 | checkDuplicates = false; |
| 1998 | } |
2111 | | delete [] lower; |
2112 | | delete [] upper; |
2113 | | // make sure matrix correct size |
2114 | | matrix_->setDimensions(numberRows_, numberColumns_); |
2115 | | } |
2116 | | return numberErrors; |
| 2000 | maxColumn = CoinMax(maxColumn, iColumn); |
| 2001 | if (elements[i] == 1.0) { |
| 2002 | startPositive[iColumn]++; |
| 2003 | } else if (elements[i] == -1.0) { |
| 2004 | startNegative[iColumn]++; |
| 2005 | } |
| 2006 | } |
| 2007 | if (checkDuplicates) { |
| 2008 | for (int i = 0; i < numberElements; i++) { |
| 2009 | int iColumn = columns[i]; |
| 2010 | which[iColumn] = 0; |
| 2011 | } |
| 2012 | } |
| 2013 | } |
| 2014 | // check size |
| 2015 | int numberColumns = maxColumn + 1; |
| 2016 | CoinAssertHint(numberColumns <= numberColumns_, |
| 2017 | "rows having column indices >= numberColumns_"); |
| 2018 | size = 0; |
| 2019 | int iColumn; |
| 2020 | for (iColumn = 0; iColumn < numberColumns_; iColumn++) { |
| 2021 | CoinBigIndex n = startPositive[iColumn]; |
| 2022 | startPositive[iColumn] = size; |
| 2023 | size += n; |
| 2024 | n = startNegative[iColumn]; |
| 2025 | startNegative[iColumn] = size; |
| 2026 | size += n; |
| 2027 | } |
| 2028 | startPositive[numberColumns_] = size; |
| 2029 | for (iRow = 0; iRow < number; iRow++) { |
| 2030 | const int *columns; |
| 2031 | const double *elements; |
| 2032 | int numberElements = buildObject.row(iRow, lower[iRow], |
| 2033 | upper[iRow], |
| 2034 | columns, elements); |
| 2035 | for (int i = 0; i < numberElements; i++) { |
| 2036 | int iColumn = columns[i]; |
| 2037 | maxColumn = CoinMax(maxColumn, iColumn); |
| 2038 | if (elements[i] == 1.0) { |
| 2039 | CoinBigIndex position = startPositive[iColumn]; |
| 2040 | indices[position] = iRow; |
| 2041 | startPositive[iColumn]++; |
| 2042 | } else if (elements[i] == -1.0) { |
| 2043 | CoinBigIndex position = startNegative[iColumn]; |
| 2044 | indices[position] = iRow; |
| 2045 | startNegative[iColumn]++; |
| 2046 | } |
| 2047 | } |
| 2048 | } |
| 2049 | // and now redo starts |
| 2050 | for (iColumn = numberColumns_ - 1; iColumn >= 0; iColumn--) { |
| 2051 | startPositive[iColumn + 1] = startNegative[iColumn]; |
| 2052 | startNegative[iColumn] = startPositive[iColumn]; |
| 2053 | } |
| 2054 | startPositive[0] = 0; |
| 2055 | for (iColumn = 0; iColumn < numberColumns_; iColumn++) { |
| 2056 | CoinBigIndex start = startPositive[iColumn]; |
| 2057 | CoinBigIndex end = startNegative[iColumn]; |
| 2058 | std::sort(indices + start, indices + end); |
| 2059 | start = startNegative[iColumn]; |
| 2060 | end = startPositive[iColumn + 1]; |
| 2061 | std::sort(indices + start, indices + end); |
| 2062 | } |
| 2063 | // Get good object |
| 2064 | delete matrix_; |
| 2065 | ClpPlusMinusOneMatrix *matrix = new ClpPlusMinusOneMatrix(); |
| 2066 | matrix->passInCopy(numberRows_, numberColumns, |
| 2067 | true, indices, startPositive, startNegative); |
| 2068 | matrix_ = matrix; |
| 2069 | delete[] which; |
| 2070 | } |
| 2071 | delete[] lower; |
| 2072 | delete[] upper; |
| 2073 | // make sure matrix correct size |
| 2074 | matrix_->setDimensions(numberRows_, numberColumns_); |
| 2075 | } |
| 2076 | return numberErrors; |
2121 | | int |
2122 | | ClpModel::addRows( CoinModel & modelObject, bool tryPlusMinusOne, bool checkDuplicates) |
2123 | | { |
2124 | | if (modelObject.numberElements() == 0) |
2125 | | return 0; |
2126 | | bool goodState = true; |
2127 | | int numberErrors = 0; |
2128 | | if (modelObject.columnLowerArray()) { |
2129 | | // some column information exists |
2130 | | int numberColumns2 = modelObject.numberColumns(); |
2131 | | const double * columnLower = modelObject.columnLowerArray(); |
2132 | | const double * columnUpper = modelObject.columnUpperArray(); |
2133 | | const double * objective = modelObject.objectiveArray(); |
2134 | | const int * integerType = modelObject.integerTypeArray(); |
2135 | | for (int i = 0; i < numberColumns2; i++) { |
2136 | | if (columnLower[i] != 0.0) |
2137 | | goodState = false; |
2138 | | if (columnUpper[i] != COIN_DBL_MAX) |
2139 | | goodState = false; |
2140 | | if (objective[i] != 0.0) |
2141 | | goodState = false; |
2142 | | if (integerType[i] != 0) |
2143 | | goodState = false; |
2144 | | } |
2145 | | } |
2146 | | if (goodState) { |
2147 | | // can do addRows |
2148 | | // Set arrays for normal use |
2149 | | double * rowLower = modelObject.rowLowerArray(); |
2150 | | double * rowUpper = modelObject.rowUpperArray(); |
2151 | | double * columnLower = modelObject.columnLowerArray(); |
2152 | | double * columnUpper = modelObject.columnUpperArray(); |
2153 | | double * objective = modelObject.objectiveArray(); |
2154 | | int * integerType = modelObject.integerTypeArray(); |
2155 | | double * associated = modelObject.associatedArray(); |
2156 | | // If strings then do copies |
2157 | | if (modelObject.stringsExist()) { |
2158 | | numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper, |
2159 | | objective, integerType, associated); |
2160 | | } |
2161 | | int numberRows = numberRows_; // save number of rows |
2162 | | int numberRows2 = modelObject.numberRows(); |
2163 | | if (numberRows2 && !numberErrors) { |
2164 | | CoinBigIndex * startPositive = NULL; |
2165 | | CoinBigIndex * startNegative = NULL; |
2166 | | int numberColumns = modelObject.numberColumns(); |
2167 | | if ((!matrix_ || !matrix_->getNumElements()) && !numberRows && tryPlusMinusOne) { |
2168 | | startPositive = new CoinBigIndex[numberColumns+1]; |
2169 | | startNegative = new CoinBigIndex[numberColumns]; |
2170 | | modelObject.countPlusMinusOne(startPositive, startNegative, associated); |
2171 | | if (startPositive[0] < 0) { |
2172 | | // no good |
2173 | | tryPlusMinusOne = false; |
2174 | | delete [] startPositive; |
2175 | | delete [] startNegative; |
2176 | | } |
2177 | | } else { |
2178 | | // Will add to whatever sort of matrix exists |
2179 | | tryPlusMinusOne = false; |
2180 | | } |
2181 | | assert (rowLower); |
2182 | | addRows(numberRows2, rowLower, rowUpper, NULL, NULL, NULL); |
| 2081 | int ClpModel::addRows(CoinModel &modelObject, bool tryPlusMinusOne, bool checkDuplicates) |
| 2082 | { |
| 2083 | if (modelObject.numberElements() == 0) |
| 2084 | return 0; |
| 2085 | bool goodState = true; |
| 2086 | int numberErrors = 0; |
| 2087 | if (modelObject.columnLowerArray()) { |
| 2088 | // some column information exists |
| 2089 | int numberColumns2 = modelObject.numberColumns(); |
| 2090 | const double *columnLower = modelObject.columnLowerArray(); |
| 2091 | const double *columnUpper = modelObject.columnUpperArray(); |
| 2092 | const double *objective = modelObject.objectiveArray(); |
| 2093 | const int *integerType = modelObject.integerTypeArray(); |
| 2094 | for (int i = 0; i < numberColumns2; i++) { |
| 2095 | if (columnLower[i] != 0.0) |
| 2096 | goodState = false; |
| 2097 | if (columnUpper[i] != COIN_DBL_MAX) |
| 2098 | goodState = false; |
| 2099 | if (objective[i] != 0.0) |
| 2100 | goodState = false; |
| 2101 | if (integerType[i] != 0) |
| 2102 | goodState = false; |
| 2103 | } |
| 2104 | } |
| 2105 | if (goodState) { |
| 2106 | // can do addRows |
| 2107 | // Set arrays for normal use |
| 2108 | double *rowLower = modelObject.rowLowerArray(); |
| 2109 | double *rowUpper = modelObject.rowUpperArray(); |
| 2110 | double *columnLower = modelObject.columnLowerArray(); |
| 2111 | double *columnUpper = modelObject.columnUpperArray(); |
| 2112 | double *objective = modelObject.objectiveArray(); |
| 2113 | int *integerType = modelObject.integerTypeArray(); |
| 2114 | double *associated = modelObject.associatedArray(); |
| 2115 | // If strings then do copies |
| 2116 | if (modelObject.stringsExist()) { |
| 2117 | numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper, |
| 2118 | objective, integerType, associated); |
| 2119 | } |
| 2120 | int numberRows = numberRows_; // save number of rows |
| 2121 | int numberRows2 = modelObject.numberRows(); |
| 2122 | if (numberRows2 && !numberErrors) { |
| 2123 | CoinBigIndex *startPositive = NULL; |
| 2124 | CoinBigIndex *startNegative = NULL; |
| 2125 | int numberColumns = modelObject.numberColumns(); |
| 2126 | if ((!matrix_ || !matrix_->getNumElements()) && !numberRows && tryPlusMinusOne) { |
| 2127 | startPositive = new CoinBigIndex[numberColumns + 1]; |
| 2128 | startNegative = new CoinBigIndex[numberColumns]; |
| 2129 | modelObject.countPlusMinusOne(startPositive, startNegative, associated); |
| 2130 | if (startPositive[0] < 0) { |
| 2131 | // no good |
| 2132 | tryPlusMinusOne = false; |
| 2133 | delete[] startPositive; |
| 2134 | delete[] startNegative; |
| 2135 | } |
| 2136 | } else { |
| 2137 | // Will add to whatever sort of matrix exists |
| 2138 | tryPlusMinusOne = false; |
| 2139 | } |
| 2140 | assert(rowLower); |
| 2141 | addRows(numberRows2, rowLower, rowUpper, NULL, NULL, NULL); |
2265 | | void |
2266 | | ClpModel::addColumns(int number, const double * columnLower, |
2267 | | const double * columnUpper, |
2268 | | const double * objIn, |
2269 | | const CoinBigIndex * columnStarts, const int * rows, |
2270 | | const double * elements) |
2271 | | { |
2272 | | // Create a list of CoinPackedVectors |
2273 | | if (number) { |
2274 | | whatsChanged_ &= ~(1 + 2 + 4 + 64 + 128 + 256); // all except rows changed |
2275 | | int numberColumnsNow = numberColumns_; |
2276 | | resize(numberRows_, numberColumnsNow + number); |
2277 | | double * lower = columnLower_ + numberColumnsNow; |
2278 | | double * upper = columnUpper_ + numberColumnsNow; |
2279 | | double * obj = objective() + numberColumnsNow; |
2280 | | int iColumn; |
2281 | | if (columnLower) { |
2282 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2283 | | double value = columnLower[iColumn]; |
2284 | | if (value < -1.0e20) |
2285 | | value = -COIN_DBL_MAX; |
2286 | | lower[iColumn] = value; |
2287 | | } |
2288 | | } else { |
2289 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2290 | | lower[iColumn] = 0.0; |
2291 | | } |
2292 | | } |
2293 | | if (columnUpper) { |
2294 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2295 | | double value = columnUpper[iColumn]; |
2296 | | if (value > 1.0e20) |
2297 | | value = COIN_DBL_MAX; |
2298 | | upper[iColumn] = value; |
2299 | | } |
2300 | | } else { |
2301 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2302 | | upper[iColumn] = COIN_DBL_MAX; |
2303 | | } |
2304 | | } |
2305 | | if (objIn) { |
2306 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2307 | | obj[iColumn] = objIn[iColumn]; |
2308 | | } |
2309 | | } else { |
2310 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2311 | | obj[iColumn] = 0.0; |
2312 | | } |
2313 | | } |
2314 | | // Deal with matrix |
2315 | | |
2316 | | delete rowCopy_; |
2317 | | rowCopy_ = NULL; |
2318 | | delete scaledMatrix_; |
2319 | | scaledMatrix_ = NULL; |
2320 | | if (!matrix_) |
2321 | | createEmptyMatrix(); |
2322 | | setRowScale(NULL); |
2323 | | setColumnScale(NULL); |
| 2223 | void ClpModel::addColumns(int number, const double *columnLower, |
| 2224 | const double *columnUpper, |
| 2225 | const double *objIn, |
| 2226 | const CoinBigIndex *columnStarts, const int *rows, |
| 2227 | const double *elements) |
| 2228 | { |
| 2229 | // Create a list of CoinPackedVectors |
| 2230 | if (number) { |
| 2231 | whatsChanged_ &= ~(1 + 2 + 4 + 64 + 128 + 256); // all except rows changed |
| 2232 | int numberColumnsNow = numberColumns_; |
| 2233 | resize(numberRows_, numberColumnsNow + number); |
| 2234 | double *lower = columnLower_ + numberColumnsNow; |
| 2235 | double *upper = columnUpper_ + numberColumnsNow; |
| 2236 | double *obj = objective() + numberColumnsNow; |
| 2237 | int iColumn; |
| 2238 | if (columnLower) { |
| 2239 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2240 | double value = columnLower[iColumn]; |
| 2241 | if (value < -1.0e20) |
| 2242 | value = -COIN_DBL_MAX; |
| 2243 | lower[iColumn] = value; |
| 2244 | } |
| 2245 | } else { |
| 2246 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2247 | lower[iColumn] = 0.0; |
| 2248 | } |
| 2249 | } |
| 2250 | if (columnUpper) { |
| 2251 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2252 | double value = columnUpper[iColumn]; |
| 2253 | if (value > 1.0e20) |
| 2254 | value = COIN_DBL_MAX; |
| 2255 | upper[iColumn] = value; |
| 2256 | } |
| 2257 | } else { |
| 2258 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2259 | upper[iColumn] = COIN_DBL_MAX; |
| 2260 | } |
| 2261 | } |
| 2262 | if (objIn) { |
| 2263 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2264 | obj[iColumn] = objIn[iColumn]; |
| 2265 | } |
| 2266 | } else { |
| 2267 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2268 | obj[iColumn] = 0.0; |
| 2269 | } |
| 2270 | } |
| 2271 | // Deal with matrix |
| 2272 | |
| 2273 | delete rowCopy_; |
| 2274 | rowCopy_ = NULL; |
| 2275 | delete scaledMatrix_; |
| 2276 | scaledMatrix_ = NULL; |
| 2277 | if (!matrix_) |
| 2278 | createEmptyMatrix(); |
| 2279 | setRowScale(NULL); |
| 2280 | setColumnScale(NULL); |
2334 | | void |
2335 | | ClpModel::addColumns(int number, const double * columnLower, |
2336 | | const double * columnUpper, |
2337 | | const double * objIn, |
2338 | | const CoinBigIndex * columnStarts, |
2339 | | const int * columnLengths, const int * rows, |
2340 | | const double * elements) |
2341 | | { |
2342 | | if (number) { |
2343 | | CoinBigIndex numberElements = 0; |
2344 | | int iColumn; |
2345 | | for (iColumn = 0; iColumn < number; iColumn++) |
2346 | | numberElements += columnLengths[iColumn]; |
2347 | | CoinBigIndex * newStarts = new CoinBigIndex[number+1]; |
2348 | | int * newIndex = new int[numberElements]; |
2349 | | double * newElements = new double[numberElements]; |
2350 | | numberElements = 0; |
2351 | | newStarts[0] = 0; |
2352 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2353 | | CoinBigIndex iStart = columnStarts[iColumn]; |
2354 | | int length = columnLengths[iColumn]; |
2355 | | CoinMemcpyN(rows + iStart, length, newIndex + numberElements); |
2356 | | CoinMemcpyN(elements + iStart, length, newElements + numberElements); |
2357 | | numberElements += length; |
2358 | | newStarts[iColumn+1] = numberElements; |
2359 | | } |
2360 | | addColumns(number, columnLower, columnUpper, objIn, |
2361 | | newStarts, newIndex, newElements); |
2362 | | delete [] newStarts; |
2363 | | delete [] newIndex; |
2364 | | delete [] newElements; |
2365 | | } |
| 2291 | void ClpModel::addColumns(int number, const double *columnLower, |
| 2292 | const double *columnUpper, |
| 2293 | const double *objIn, |
| 2294 | const CoinBigIndex *columnStarts, |
| 2295 | const int *columnLengths, const int *rows, |
| 2296 | const double *elements) |
| 2297 | { |
| 2298 | if (number) { |
| 2299 | CoinBigIndex numberElements = 0; |
| 2300 | int iColumn; |
| 2301 | for (iColumn = 0; iColumn < number; iColumn++) |
| 2302 | numberElements += columnLengths[iColumn]; |
| 2303 | CoinBigIndex *newStarts = new CoinBigIndex[number + 1]; |
| 2304 | int *newIndex = new int[numberElements]; |
| 2305 | double *newElements = new double[numberElements]; |
| 2306 | numberElements = 0; |
| 2307 | newStarts[0] = 0; |
| 2308 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2309 | CoinBigIndex iStart = columnStarts[iColumn]; |
| 2310 | int length = columnLengths[iColumn]; |
| 2311 | CoinMemcpyN(rows + iStart, length, newIndex + numberElements); |
| 2312 | CoinMemcpyN(elements + iStart, length, newElements + numberElements); |
| 2313 | numberElements += length; |
| 2314 | newStarts[iColumn + 1] = numberElements; |
| 2315 | } |
| 2316 | addColumns(number, columnLower, columnUpper, objIn, |
| 2317 | newStarts, newIndex, newElements); |
| 2318 | delete[] newStarts; |
| 2319 | delete[] newIndex; |
| 2320 | delete[] newElements; |
| 2321 | } |
2368 | | void |
2369 | | ClpModel::addColumns(int number, const double * columnLower, |
2370 | | const double * columnUpper, |
2371 | | const double * objIn, |
2372 | | const CoinPackedVectorBase * const * columns) |
2373 | | { |
2374 | | if (!number) |
2375 | | return; |
2376 | | whatsChanged_ &= ~(1 + 2 + 4 + 64 + 128 + 256); // all except rows changed |
2377 | | int numberColumnsNow = numberColumns_; |
2378 | | resize(numberRows_, numberColumnsNow + number); |
2379 | | double * lower = columnLower_ + numberColumnsNow; |
2380 | | double * upper = columnUpper_ + numberColumnsNow; |
2381 | | double * obj = objective() + numberColumnsNow; |
2382 | | int iColumn; |
2383 | | if (columnLower) { |
2384 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2385 | | double value = columnLower[iColumn]; |
2386 | | if (value < -1.0e20) |
2387 | | value = -COIN_DBL_MAX; |
2388 | | lower[iColumn] = value; |
2389 | | } |
2390 | | } else { |
2391 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2392 | | lower[iColumn] = 0.0; |
2393 | | } |
2394 | | } |
2395 | | if (columnUpper) { |
2396 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2397 | | double value = columnUpper[iColumn]; |
2398 | | if (value > 1.0e20) |
2399 | | value = COIN_DBL_MAX; |
2400 | | upper[iColumn] = value; |
2401 | | } |
2402 | | } else { |
2403 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2404 | | upper[iColumn] = COIN_DBL_MAX; |
2405 | | } |
2406 | | } |
2407 | | if (objIn) { |
2408 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2409 | | obj[iColumn] = objIn[iColumn]; |
2410 | | } |
2411 | | } else { |
2412 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2413 | | obj[iColumn] = 0.0; |
2414 | | } |
2415 | | } |
2416 | | // Deal with matrix |
2417 | | |
2418 | | delete rowCopy_; |
2419 | | rowCopy_ = NULL; |
2420 | | delete scaledMatrix_; |
2421 | | scaledMatrix_ = NULL; |
2422 | | if (!matrix_) |
2423 | | createEmptyMatrix(); |
2424 | | if (columns) |
2425 | | matrix_->appendCols(number, columns); |
2426 | | setRowScale(NULL); |
2427 | | setColumnScale(NULL); |
2428 | | if (lengthNames_) { |
2429 | | columnNames_.resize(numberColumns_); |
2430 | | } |
| 2324 | void ClpModel::addColumns(int number, const double *columnLower, |
| 2325 | const double *columnUpper, |
| 2326 | const double *objIn, |
| 2327 | const CoinPackedVectorBase *const *columns) |
| 2328 | { |
| 2329 | if (!number) |
| 2330 | return; |
| 2331 | whatsChanged_ &= ~(1 + 2 + 4 + 64 + 128 + 256); // all except rows changed |
| 2332 | int numberColumnsNow = numberColumns_; |
| 2333 | resize(numberRows_, numberColumnsNow + number); |
| 2334 | double *lower = columnLower_ + numberColumnsNow; |
| 2335 | double *upper = columnUpper_ + numberColumnsNow; |
| 2336 | double *obj = objective() + numberColumnsNow; |
| 2337 | int iColumn; |
| 2338 | if (columnLower) { |
| 2339 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2340 | double value = columnLower[iColumn]; |
| 2341 | if (value < -1.0e20) |
| 2342 | value = -COIN_DBL_MAX; |
| 2343 | lower[iColumn] = value; |
| 2344 | } |
| 2345 | } else { |
| 2346 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2347 | lower[iColumn] = 0.0; |
| 2348 | } |
| 2349 | } |
| 2350 | if (columnUpper) { |
| 2351 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2352 | double value = columnUpper[iColumn]; |
| 2353 | if (value > 1.0e20) |
| 2354 | value = COIN_DBL_MAX; |
| 2355 | upper[iColumn] = value; |
| 2356 | } |
| 2357 | } else { |
| 2358 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2359 | upper[iColumn] = COIN_DBL_MAX; |
| 2360 | } |
| 2361 | } |
| 2362 | if (objIn) { |
| 2363 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2364 | obj[iColumn] = objIn[iColumn]; |
| 2365 | } |
| 2366 | } else { |
| 2367 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2368 | obj[iColumn] = 0.0; |
| 2369 | } |
| 2370 | } |
| 2371 | // Deal with matrix |
| 2372 | |
| 2373 | delete rowCopy_; |
| 2374 | rowCopy_ = NULL; |
| 2375 | delete scaledMatrix_; |
| 2376 | scaledMatrix_ = NULL; |
| 2377 | if (!matrix_) |
| 2378 | createEmptyMatrix(); |
| 2379 | if (columns) |
| 2380 | matrix_->appendCols(number, columns); |
| 2381 | setRowScale(NULL); |
| 2382 | setColumnScale(NULL); |
| 2383 | if (lengthNames_) { |
| 2384 | columnNames_.resize(numberColumns_); |
| 2385 | } |
2475 | | if (!tryPlusMinusOne) { |
2476 | | CoinBigIndex numberElements = buildObject.numberElements(); |
2477 | | CoinBigIndex * starts = new CoinBigIndex [number+1]; |
2478 | | int * row = new int[numberElements]; |
2479 | | double * element = new double[numberElements]; |
2480 | | starts[0] = 0; |
2481 | | numberElements = 0; |
2482 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2483 | | const int * rows; |
2484 | | const double * elements; |
2485 | | int numberElementsThis = buildObject.column(iColumn, lower[iColumn], upper[iColumn], |
2486 | | objective[iColumn], rows, elements); |
2487 | | CoinMemcpyN(rows, numberElementsThis, row + numberElements); |
2488 | | CoinMemcpyN(elements, numberElementsThis, element + numberElements); |
2489 | | numberElements += numberElementsThis; |
2490 | | starts[iColumn+1] = numberElements; |
2491 | | } |
2492 | | addColumns(number, lower, upper, objective, NULL); |
2493 | | // make sure matrix has enough rows |
2494 | | matrix_->setDimensions(numberRows_, -1); |
2495 | | numberErrors = matrix_->appendMatrix(number, 1, starts, row, element, |
2496 | | checkDuplicates ? numberRows_ : -1); |
2497 | | delete [] starts; |
2498 | | delete [] row; |
2499 | | delete [] element; |
2500 | | } else { |
2501 | | // arrays already filled in |
2502 | | addColumns(number, lower, upper, objective, NULL); |
2503 | | char * which = NULL; // for duplicates |
2504 | | if (checkDuplicates) { |
2505 | | which = new char[numberRows_]; |
2506 | | CoinZeroN(which, numberRows_); |
2507 | | } |
2508 | | // build +-1 matrix |
2509 | | CoinBigIndex * startPositive = new CoinBigIndex [number+1]; |
2510 | | CoinBigIndex * startNegative = new CoinBigIndex [number]; |
2511 | | int * indices = new int [size]; |
2512 | | int * neg = new int[maximumLength]; |
2513 | | startPositive[0] = 0; |
2514 | | size = 0; |
2515 | | int maxRow = -1; |
2516 | | for (iColumn = 0; iColumn < number; iColumn++) { |
2517 | | const int * rows; |
2518 | | const double * elements; |
2519 | | int numberElements = buildObject.column(iColumn, lower[iColumn], |
2520 | | upper[iColumn], objective[iColumn], |
2521 | | rows, elements); |
2522 | | int nNeg = 0; |
2523 | | CoinBigIndex start = size; |
2524 | | for (int i = 0; i < numberElements; i++) { |
2525 | | int iRow = rows[i]; |
2526 | | if (checkDuplicates) { |
2527 | | if (iRow < numberRows_) { |
2528 | | if(which[iRow]) |
2529 | | numberErrors++; |
2530 | | else |
2531 | | which[iRow] = 1; |
2532 | | } else { |
2533 | | numberErrors++; |
2534 | | // and may as well switch off |
2535 | | checkDuplicates = false; |
2536 | | } |
2537 | | } |
2538 | | maxRow = CoinMax(maxRow, iRow); |
2539 | | if (elements[i] == 1.0) { |
2540 | | indices[size++] = iRow; |
2541 | | } else if (elements[i] == -1.0) { |
2542 | | neg[nNeg++] = iRow; |
2543 | | } |
2544 | | } |
2545 | | std::sort(indices + start, indices + size); |
2546 | | std::sort(neg, neg + nNeg); |
2547 | | startNegative[iColumn] = size; |
2548 | | CoinMemcpyN(neg, nNeg, indices + size); |
2549 | | size += nNeg; |
2550 | | startPositive[iColumn+1] = size; |
2551 | | } |
2552 | | delete [] neg; |
2553 | | // check size |
2554 | | assert (maxRow + 1 <= numberRows_); |
2555 | | // Get good object |
2556 | | delete matrix_; |
2557 | | ClpPlusMinusOneMatrix * matrix = new ClpPlusMinusOneMatrix(); |
2558 | | matrix->passInCopy(numberRows_, number, true, indices, startPositive, startNegative); |
2559 | | matrix_ = matrix; |
2560 | | delete [] which; |
| 2421 | } |
| 2422 | if (!tryPlusMinusOne) |
| 2423 | break; |
| 2424 | } |
| 2425 | } else { |
| 2426 | // Will add to whatever sort of matrix exists |
| 2427 | tryPlusMinusOne = false; |
| 2428 | } |
| 2429 | if (!tryPlusMinusOne) { |
| 2430 | CoinBigIndex numberElements = buildObject.numberElements(); |
| 2431 | CoinBigIndex *starts = new CoinBigIndex[number + 1]; |
| 2432 | int *row = new int[numberElements]; |
| 2433 | double *element = new double[numberElements]; |
| 2434 | starts[0] = 0; |
| 2435 | numberElements = 0; |
| 2436 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2437 | const int *rows; |
| 2438 | const double *elements; |
| 2439 | int numberElementsThis = buildObject.column(iColumn, lower[iColumn], upper[iColumn], |
| 2440 | objective[iColumn], rows, elements); |
| 2441 | CoinMemcpyN(rows, numberElementsThis, row + numberElements); |
| 2442 | CoinMemcpyN(elements, numberElementsThis, element + numberElements); |
| 2443 | numberElements += numberElementsThis; |
| 2444 | starts[iColumn + 1] = numberElements; |
| 2445 | } |
| 2446 | addColumns(number, lower, upper, objective, NULL); |
| 2447 | // make sure matrix has enough rows |
| 2448 | matrix_->setDimensions(numberRows_, -1); |
| 2449 | numberErrors = matrix_->appendMatrix(number, 1, starts, row, element, |
| 2450 | checkDuplicates ? numberRows_ : -1); |
| 2451 | delete[] starts; |
| 2452 | delete[] row; |
| 2453 | delete[] element; |
| 2454 | } else { |
| 2455 | // arrays already filled in |
| 2456 | addColumns(number, lower, upper, objective, NULL); |
| 2457 | char *which = NULL; // for duplicates |
| 2458 | if (checkDuplicates) { |
| 2459 | which = new char[numberRows_]; |
| 2460 | CoinZeroN(which, numberRows_); |
| 2461 | } |
| 2462 | // build +-1 matrix |
| 2463 | CoinBigIndex *startPositive = new CoinBigIndex[number + 1]; |
| 2464 | CoinBigIndex *startNegative = new CoinBigIndex[number]; |
| 2465 | int *indices = new int[size]; |
| 2466 | int *neg = new int[maximumLength]; |
| 2467 | startPositive[0] = 0; |
| 2468 | size = 0; |
| 2469 | int maxRow = -1; |
| 2470 | for (iColumn = 0; iColumn < number; iColumn++) { |
| 2471 | const int *rows; |
| 2472 | const double *elements; |
| 2473 | int numberElements = buildObject.column(iColumn, lower[iColumn], |
| 2474 | upper[iColumn], objective[iColumn], |
| 2475 | rows, elements); |
| 2476 | int nNeg = 0; |
| 2477 | CoinBigIndex start = size; |
| 2478 | for (int i = 0; i < numberElements; i++) { |
| 2479 | int iRow = rows[i]; |
| 2480 | if (checkDuplicates) { |
| 2481 | if (iRow < numberRows_) { |
| 2482 | if (which[iRow]) |
| 2483 | numberErrors++; |
| 2484 | else |
| 2485 | which[iRow] = 1; |
| 2486 | } else { |
| 2487 | numberErrors++; |
| 2488 | // and may as well switch off |
| 2489 | checkDuplicates = false; |
| 2490 | } |
2571 | | int |
2572 | | ClpModel::addColumns( CoinModel & modelObject, bool tryPlusMinusOne, bool checkDuplicates) |
2573 | | { |
2574 | | if (modelObject.numberElements() == 0) |
2575 | | return 0; |
2576 | | bool goodState = true; |
2577 | | if (modelObject.rowLowerArray()) { |
2578 | | // some row information exists |
2579 | | int numberRows2 = modelObject.numberRows(); |
2580 | | const double * rowLower = modelObject.rowLowerArray(); |
2581 | | const double * rowUpper = modelObject.rowUpperArray(); |
2582 | | for (int i = 0; i < numberRows2; i++) { |
2583 | | if (rowLower[i] != -COIN_DBL_MAX) |
2584 | | goodState = false; |
2585 | | if (rowUpper[i] != COIN_DBL_MAX) |
2586 | | goodState = false; |
2587 | | } |
2588 | | } |
2589 | | if (goodState) { |
2590 | | // can do addColumns |
2591 | | int numberErrors = 0; |
2592 | | // Set arrays for normal use |
2593 | | double * rowLower = modelObject.rowLowerArray(); |
2594 | | double * rowUpper = modelObject.rowUpperArray(); |
2595 | | double * columnLower = modelObject.columnLowerArray(); |
2596 | | double * columnUpper = modelObject.columnUpperArray(); |
2597 | | double * objective = modelObject.objectiveArray(); |
2598 | | int * integerType = modelObject.integerTypeArray(); |
2599 | | double * associated = modelObject.associatedArray(); |
2600 | | // If strings then do copies |
2601 | | if (modelObject.stringsExist()) { |
2602 | | numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper, |
2603 | | objective, integerType, associated); |
2604 | | } |
2605 | | int numberColumns = numberColumns_; // save number of columns |
2606 | | int numberColumns2 = modelObject.numberColumns(); |
2607 | | if (numberColumns2 && !numberErrors) { |
2608 | | CoinBigIndex * startPositive = NULL; |
2609 | | CoinBigIndex * startNegative = NULL; |
2610 | | if ((!matrix_ || !matrix_->getNumElements()) && !numberColumns && tryPlusMinusOne) { |
2611 | | startPositive = new CoinBigIndex[numberColumns2+1]; |
2612 | | startNegative = new CoinBigIndex[numberColumns2]; |
2613 | | modelObject.countPlusMinusOne(startPositive, startNegative, associated); |
2614 | | if (startPositive[0] < 0) { |
2615 | | // no good |
2616 | | tryPlusMinusOne = false; |
2617 | | delete [] startPositive; |
2618 | | delete [] startNegative; |
2619 | | } |
2620 | | } else { |
2621 | | // Will add to whatever sort of matrix exists |
2622 | | tryPlusMinusOne = false; |
2623 | | } |
2624 | | assert (columnLower); |
| 2525 | int ClpModel::addColumns(CoinModel &modelObject, bool tryPlusMinusOne, bool checkDuplicates) |
| 2526 | { |
| 2527 | if (modelObject.numberElements() == 0) |
| 2528 | return 0; |
| 2529 | bool goodState = true; |
| 2530 | if (modelObject.rowLowerArray()) { |
| 2531 | // some row information exists |
| 2532 | int numberRows2 = modelObject.numberRows(); |
| 2533 | const double *rowLower = modelObject.rowLowerArray(); |
| 2534 | const double *rowUpper = modelObject.rowUpperArray(); |
| 2535 | for (int i = 0; i < numberRows2; i++) { |
| 2536 | if (rowLower[i] != -COIN_DBL_MAX) |
| 2537 | goodState = false; |
| 2538 | if (rowUpper[i] != COIN_DBL_MAX) |
| 2539 | goodState = false; |
| 2540 | } |
| 2541 | } |
| 2542 | if (goodState) { |
| 2543 | // can do addColumns |
| 2544 | int numberErrors = 0; |
| 2545 | // Set arrays for normal use |
| 2546 | double *rowLower = modelObject.rowLowerArray(); |
| 2547 | double *rowUpper = modelObject.rowUpperArray(); |
| 2548 | double *columnLower = modelObject.columnLowerArray(); |
| 2549 | double *columnUpper = modelObject.columnUpperArray(); |
| 2550 | double *objective = modelObject.objectiveArray(); |
| 2551 | int *integerType = modelObject.integerTypeArray(); |
| 2552 | double *associated = modelObject.associatedArray(); |
| 2553 | // If strings then do copies |
| 2554 | if (modelObject.stringsExist()) { |
| 2555 | numberErrors = modelObject.createArrays(rowLower, rowUpper, columnLower, columnUpper, |
| 2556 | objective, integerType, associated); |
| 2557 | } |
| 2558 | int numberColumns = numberColumns_; // save number of columns |
| 2559 | int numberColumns2 = modelObject.numberColumns(); |
| 2560 | if (numberColumns2 && !numberErrors) { |
| 2561 | CoinBigIndex *startPositive = NULL; |
| 2562 | CoinBigIndex *startNegative = NULL; |
| 2563 | if ((!matrix_ || !matrix_->getNumElements()) && !numberColumns && tryPlusMinusOne) { |
| 2564 | startPositive = new CoinBigIndex[numberColumns2 + 1]; |
| 2565 | startNegative = new CoinBigIndex[numberColumns2]; |
| 2566 | modelObject.countPlusMinusOne(startPositive, startNegative, associated); |
| 2567 | if (startPositive[0] < 0) { |
| 2568 | // no good |
| 2569 | tryPlusMinusOne = false; |
| 2570 | delete[] startPositive; |
| 2571 | delete[] startNegative; |
| 2572 | } |
| 2573 | } else { |
| 2574 | // Will add to whatever sort of matrix exists |
| 2575 | tryPlusMinusOne = false; |
| 2576 | } |
| 2577 | assert(columnLower); |
2911 | | int |
2912 | | ClpModel::readMps(const char *fileName, |
2913 | | bool keepNames, |
2914 | | bool ignoreErrors) |
2915 | | { |
2916 | | if (!strcmp(fileName, "-") || !strcmp(fileName, "stdin")) { |
2917 | | // stdin |
2918 | | } else { |
2919 | | std::string name = fileName; |
2920 | | bool readable = fileCoinReadable(name); |
2921 | | if (!readable) { |
2922 | | handler_->message(CLP_UNABLE_OPEN, messages_) |
2923 | | << fileName << CoinMessageEol; |
2924 | | return -1; |
2925 | | } |
2926 | | } |
2927 | | CoinMpsIO m; |
2928 | | m.passInMessageHandler(handler_); |
2929 | | *m.messagesPointer() = coinMessages(); |
2930 | | bool savePrefix = m.messageHandler()->prefix(); |
2931 | | m.messageHandler()->setPrefix(handler_->prefix()); |
2932 | | m.setSmallElementValue(CoinMax(smallElement_, m.getSmallElementValue())); |
2933 | | double time1 = CoinCpuTime(), time2; |
2934 | | int status = 0; |
2935 | | try { |
2936 | | status = m.readMps(fileName, ""); |
2937 | | } catch (CoinError e) { |
2938 | | e.print(); |
2939 | | status = -1; |
2940 | | } |
2941 | | m.messageHandler()->setPrefix(savePrefix); |
2942 | | if (!status || (ignoreErrors && (status > 0 && status < 100000))) { |
2943 | | loadProblem(*m.getMatrixByCol(), |
2944 | | m.getColLower(), m.getColUpper(), |
2945 | | m.getObjCoefficients(), |
2946 | | m.getRowLower(), m.getRowUpper()); |
2947 | | if (m.integerColumns()) { |
2948 | | integerType_ = new char[numberColumns_]; |
2949 | | CoinMemcpyN(m.integerColumns(), numberColumns_, integerType_); |
2950 | | } else { |
2951 | | integerType_ = NULL; |
2952 | | } |
| 2851 | int ClpModel::readMps(const char *fileName, |
| 2852 | bool keepNames, |
| 2853 | bool ignoreErrors) |
| 2854 | { |
| 2855 | if (!strcmp(fileName, "-") || !strcmp(fileName, "stdin")) { |
| 2856 | // stdin |
| 2857 | } else { |
| 2858 | std::string name = fileName; |
| 2859 | bool readable = fileCoinReadable(name); |
| 2860 | if (!readable) { |
| 2861 | handler_->message(CLP_UNABLE_OPEN, messages_) |
| 2862 | << fileName << CoinMessageEol; |
| 2863 | return -1; |
| 2864 | } |
| 2865 | } |
| 2866 | CoinMpsIO m; |
| 2867 | m.passInMessageHandler(handler_); |
| 2868 | *m.messagesPointer() = coinMessages(); |
| 2869 | bool savePrefix = m.messageHandler()->prefix(); |
| 2870 | m.messageHandler()->setPrefix(handler_->prefix()); |
| 2871 | m.setSmallElementValue(CoinMax(smallElement_, m.getSmallElementValue())); |
| 2872 | double time1 = CoinCpuTime(), time2; |
| 2873 | int status = 0; |
| 2874 | try { |
| 2875 | status = m.readMps(fileName, ""); |
| 2876 | } catch (CoinError e) { |
| 2877 | e.print(); |
| 2878 | status = -1; |
| 2879 | } |
| 2880 | m.messageHandler()->setPrefix(savePrefix); |
| 2881 | if (!status || (ignoreErrors && (status > 0 && status < 100000))) { |
| 2882 | loadProblem(*m.getMatrixByCol(), |
| 2883 | m.getColLower(), m.getColUpper(), |
| 2884 | m.getObjCoefficients(), |
| 2885 | m.getRowLower(), m.getRowUpper()); |
| 2886 | if (m.integerColumns()) { |
| 2887 | integerType_ = new char[numberColumns_]; |
| 2888 | CoinMemcpyN(m.integerColumns(), numberColumns_, integerType_); |
| 2889 | } else { |
| 2890 | integerType_ = NULL; |
| 2891 | } |
2968 | | // set problem name |
2969 | | setStrParam(ClpProbName, m.getProblemName()); |
2970 | | // do names |
2971 | | if (keepNames) { |
2972 | | unsigned int maxLength = 0; |
2973 | | int iRow; |
2974 | | rowNames_ = std::vector<std::string> (); |
2975 | | columnNames_ = std::vector<std::string> (); |
2976 | | rowNames_.reserve(numberRows_); |
2977 | | for (iRow = 0; iRow < numberRows_; iRow++) { |
2978 | | const char * name = m.rowName(iRow); |
2979 | | maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(name))); |
2980 | | rowNames_.push_back(name); |
2981 | | } |
2982 | | |
2983 | | int iColumn; |
2984 | | columnNames_.reserve(numberColumns_); |
2985 | | for (iColumn = 0; iColumn < numberColumns_; iColumn++) { |
2986 | | const char * name = m.columnName(iColumn); |
2987 | | maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(name))); |
2988 | | columnNames_.push_back(name); |
2989 | | } |
2990 | | lengthNames_ = static_cast<int> (maxLength); |
2991 | | } else { |
2992 | | lengthNames_ = 0; |
2993 | | } |
2994 | | #endif |
2995 | | setDblParam(ClpObjOffset, m.objectiveOffset()); |
2996 | | time2 = CoinCpuTime(); |
2997 | | handler_->message(CLP_IMPORT_RESULT, messages_) |
2998 | | << fileName |
2999 | | << time2 - time1 << CoinMessageEol; |
3000 | | } else { |
3001 | | // errors |
3002 | | handler_->message(CLP_IMPORT_ERRORS, messages_) |
3003 | | << status << fileName << CoinMessageEol; |
3004 | | } |
3005 | | |
3006 | | return status; |
| 2907 | // set problem name |
| 2908 | setStrParam(ClpProbName, m.getProblemName()); |
| 2909 | // do names |
| 2910 | if (keepNames) { |
| 2911 | unsigned int maxLength = 0; |
| 2912 | int iRow; |
| 2913 | rowNames_ = std::vector< std::string >(); |
| 2914 | columnNames_ = std::vector< std::string >(); |
| 2915 | rowNames_.reserve(numberRows_); |
| 2916 | for (iRow = 0; iRow < numberRows_; iRow++) { |
| 2917 | const char *name = m.rowName(iRow); |
| 2918 | maxLength = CoinMax(maxLength, static_cast< unsigned int >(strlen(name))); |
| 2919 | rowNames_.push_back(name); |
| 2920 | } |
| 2921 | |
| 2922 | int iColumn; |
| 2923 | columnNames_.reserve(numberColumns_); |
| 2924 | for (iColumn = 0; iColumn < numberColumns_; iColumn++) { |
| 2925 | const char *name = m.columnName(iColumn); |
| 2926 | maxLength = CoinMax(maxLength, static_cast< unsigned int >(strlen(name))); |
| 2927 | columnNames_.push_back(name); |
| 2928 | } |
| 2929 | lengthNames_ = static_cast< int >(maxLength); |
| 2930 | } else { |
| 2931 | lengthNames_ = 0; |
| 2932 | } |
| 2933 | #endif |
| 2934 | setDblParam(ClpObjOffset, m.objectiveOffset()); |
| 2935 | time2 = CoinCpuTime(); |
| 2936 | handler_->message(CLP_IMPORT_RESULT, messages_) |
| 2937 | << fileName |
| 2938 | << time2 - time1 << CoinMessageEol; |
| 2939 | } else { |
| 2940 | // errors |
| 2941 | handler_->message(CLP_IMPORT_ERRORS, messages_) |
| 2942 | << status << fileName << CoinMessageEol; |
| 2943 | } |
| 2944 | |
| 2945 | return status; |
3009 | | int |
3010 | | ClpModel::readGMPL(const char *fileName, const char * dataName, |
3011 | | bool keepNames) |
3012 | | { |
3013 | | FILE *fp = fopen(fileName, "r"); |
3014 | | if (fp) { |
3015 | | // can open - lets go for it |
3016 | | fclose(fp); |
3017 | | if (dataName) { |
3018 | | fp = fopen(dataName, "r"); |
3019 | | if (fp) { |
3020 | | fclose(fp); |
3021 | | } else { |
3022 | | handler_->message(CLP_UNABLE_OPEN, messages_) |
3023 | | << dataName << CoinMessageEol; |
3024 | | return -1; |
3025 | | } |
3026 | | } |
3027 | | } else { |
3028 | | handler_->message(CLP_UNABLE_OPEN, messages_) |
3029 | | << fileName << CoinMessageEol; |
3030 | | return -1; |
3031 | | } |
3032 | | CoinMpsIO m; |
3033 | | m.passInMessageHandler(handler_); |
3034 | | *m.messagesPointer() = coinMessages(); |
3035 | | bool savePrefix = m.messageHandler()->prefix(); |
3036 | | m.messageHandler()->setPrefix(handler_->prefix()); |
3037 | | double time1 = CoinCpuTime(), time2; |
3038 | | int status = m.readGMPL(fileName, dataName, keepNames); |
3039 | | m.messageHandler()->setPrefix(savePrefix); |
3040 | | if (!status) { |
3041 | | loadProblem(*m.getMatrixByCol(), |
3042 | | m.getColLower(), m.getColUpper(), |
3043 | | m.getObjCoefficients(), |
3044 | | m.getRowLower(), m.getRowUpper()); |
3045 | | if (m.integerColumns()) { |
3046 | | integerType_ = new char[numberColumns_]; |
3047 | | CoinMemcpyN(m.integerColumns(), numberColumns_, integerType_); |
3048 | | } else { |
3049 | | integerType_ = NULL; |
3050 | | } |
| 2948 | int ClpModel::readGMPL(const char *fileName, const char *dataName, |
| 2949 | bool keepNames) |
| 2950 | { |
| 2951 | FILE *fp = fopen(fileName, "r"); |
| 2952 | if (fp) { |
| 2953 | // can open - lets go for it |
| 2954 | fclose(fp); |
| 2955 | if (dataName) { |
| 2956 | fp = fopen(dataName, "r"); |
| 2957 | if (fp) { |
| 2958 | fclose(fp); |
| 2959 | } else { |
| 2960 | handler_->message(CLP_UNABLE_OPEN, messages_) |
| 2961 | << dataName << CoinMessageEol; |
| 2962 | return -1; |
| 2963 | } |
| 2964 | } |
| 2965 | } else { |
| 2966 | handler_->message(CLP_UNABLE_OPEN, messages_) |
| 2967 | << fileName << CoinMessageEol; |
| 2968 | return -1; |
| 2969 | } |
| 2970 | CoinMpsIO m; |
| 2971 | m.passInMessageHandler(handler_); |
| 2972 | *m.messagesPointer() = coinMessages(); |
| 2973 | bool savePrefix = m.messageHandler()->prefix(); |
| 2974 | m.messageHandler()->setPrefix(handler_->prefix()); |
| 2975 | double time1 = CoinCpuTime(), time2; |
| 2976 | int status = m.readGMPL(fileName, dataName, keepNames); |
| 2977 | m.messageHandler()->setPrefix(savePrefix); |
| 2978 | if (!status) { |
| 2979 | loadProblem(*m.getMatrixByCol(), |
| 2980 | m.getColLower(), m.getColUpper(), |
| 2981 | m.getObjCoefficients(), |
| 2982 | m.getRowLower(), m.getRowUpper()); |
| 2983 | if (m.integerColumns()) { |
| 2984 | integerType_ = new char[numberColumns_]; |
| 2985 | CoinMemcpyN(m.integerColumns(), numberColumns_, integerType_); |
| 2986 | } else { |
| 2987 | integerType_ = NULL; |
| 2988 | } |
3052 | | // set problem name |
3053 | | setStrParam(ClpProbName, m.getProblemName()); |
3054 | | // do names |
3055 | | if (keepNames) { |
3056 | | unsigned int maxLength = 0; |
3057 | | int iRow; |
3058 | | rowNames_ = std::vector<std::string> (); |
3059 | | columnNames_ = std::vector<std::string> (); |
3060 | | rowNames_.reserve(numberRows_); |
3061 | | for (iRow = 0; iRow < numberRows_; iRow++) { |
3062 | | const char * name = m.rowName(iRow); |
3063 | | maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(name))); |
3064 | | rowNames_.push_back(name); |
3065 | | } |
3066 | | |
3067 | | int iColumn; |
3068 | | columnNames_.reserve(numberColumns_); |
3069 | | for (iColumn = 0; iColumn < numberColumns_; iColumn++) { |
3070 | | const char * name = m.columnName(iColumn); |
3071 | | maxLength = CoinMax(maxLength, static_cast<unsigned int> (strlen(name))); |
3072 | | columnNames_.push_back(name); |
3073 | | } |
3074 | | lengthNames_ = static_cast<int> (maxLength); |
3075 | | } else { |
3076 | | lengthNames_ = 0; |
3077 | | } |
3078 | | #endif |
3079 | | setDblParam(ClpObjOffset, m.objectiveOffset()); |
3080 | | time2 = CoinCpuTime(); |
3081 | | handler_->message(CLP_IMPORT_RESULT, messages_) |
3082 | | << fileName |
3083 | | << time2 - time1 << CoinMessageEol; |
3084 | | } else { |
3085 | | // errors |
3086 | | handler_->message(CLP_IMPORT_ERRORS, messages_) |
3087 | | << status << fileName << CoinMessageEol; |
3088 | | } |
3089 | | return status; |
| 2990 | // set problem name |
| 2991 | setStrParam(ClpProbName, m.getProblemName()); |
| 2992 | // do names |
| 2993 | if (keepNames) { |
| 2994 | unsigned int maxLength = 0; |
| 2995 | int iRow; |
| 2996 | rowNames_ = std::vector< std::string >(); |
| 2997 | columnNames_ = std::vector< std::string >(); |
| 2998 | rowNames_.reserve(numberRows_); |
| 2999 | for (iRow = 0; iRow < numberRows_; iRow++) { |
| 3000 | const char *name = m.rowName(iRow); |
| 3001 | maxLength = CoinMax(maxLength, static_cast< unsigned int >(strlen(name))); |
| 3002 | rowNames_.push_back(name); |
| 3003 | } |
| 3004 | |
| 3005 | int iColumn; |
| 3006 | columnNames_.reserve(numberColumns_); |
| 3007 | for (iColumn = 0; iColumn < numberColumns_; iColumn++) { |
| 3008 | const char *name = m.columnName(iColumn); |
| 3009 | maxLength = CoinMax(maxLength, static_cast< unsigned int >(strlen(name))); |
| 3010 | columnNames_.push_back(name); |
| 3011 | } |
| 3012 | lengthNames_ = static_cast< int >(maxLength); |
| 3013 | } else { |
| 3014 | lengthNames_ = 0; |
| 3015 | } |
| 3016 | #endif |
| 3017 | setDblParam(ClpObjOffset, m.objectiveOffset()); |
| 3018 | time2 = CoinCpuTime(); |
| 3019 | handler_->message(CLP_IMPORT_RESULT, messages_) |
| 3020 | << fileName |
| 3021 | << time2 - time1 << CoinMessageEol; |
| 3022 | } else { |
| 3023 | // errors |
| 3024 | handler_->message(CLP_IMPORT_ERRORS, messages_) |
| 3025 | << status << fileName << CoinMessageEol; |
| 3026 | } |
| 3027 | return status; |