1/* $Id: ClpModel.hpp 1753 2011-06-19 16:27:26Z stefan $ */
2// Copyright (C) 2002, International Business Machines
3// Corporation and others. All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#ifndef ClpModel_H
7#define ClpModel_H
8
9#include "ClpConfig.h"
10
11#include <iostream>
12#include <cassert>
13#include <cmath>
14#include <vector>
15#include <string>
16//#ifndef COIN_USE_CLP
17//#define COIN_USE_CLP
18//#endif
19#include "ClpPackedMatrix.hpp"
20#include "CoinMessageHandler.hpp"
21#include "CoinHelperFunctions.hpp"
22#include "CoinTypes.hpp"
23#include "CoinFinite.hpp"
24#include "ClpParameters.hpp"
25#include "ClpObjective.hpp"
26class ClpEventHandler;
27/** This is the base class for Linear and quadratic Models
28 This knows nothing about the algorithm, but it seems to
29 have a reasonable amount of information
30
31 I would welcome suggestions for what should be in this and
32 how it relates to OsiSolverInterface. Some methods look
33 very similar.
34
35*/
36class CoinBuild;
37class CoinModel;
38class ClpModel {
39
40public:
41
42 /**@name Constructors and destructor
43 Note - copy methods copy ALL data so can chew up memory
44 until other copy is freed
45 */
46 //@{
47 /// Default constructor
48 ClpModel (bool emptyMessages = false );
49
50 /** Copy constructor. May scale depending on mode
51 -1 leave mode as is
52 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 auto-but-as-initialSolve-in-bab
53 */
54 ClpModel(const ClpModel & rhs, int scalingMode = -1);
55 /// Assignment operator. This copies the data
56 ClpModel & operator=(const ClpModel & rhs);
57 /** Subproblem constructor. A subset of whole model is created from the
58 row and column lists given. The new order is given by list order and
59 duplicates are allowed. Name and integer information can be dropped
60 */
61 ClpModel (const ClpModel * wholeModel,
62 int numberRows, const int * whichRows,
63 int numberColumns, const int * whichColumns,
64 bool dropNames = true, bool dropIntegers = true);
65 /// Destructor
66 ~ClpModel ( );
67 //@}
68
69 /**@name Load model - loads some stuff and initializes others */
70 //@{
71 /** Loads a problem (the constraints on the
72 rows are given by lower and upper bounds). If a pointer is 0 then the
73 following values are the default:
74 <ul>
75 <li> <code>colub</code>: all columns have upper bound infinity
76 <li> <code>collb</code>: all columns have lower bound 0
77 <li> <code>rowub</code>: all rows have upper bound infinity
78 <li> <code>rowlb</code>: all rows have lower bound -infinity
79 <li> <code>obj</code>: all variables have 0 objective coefficient
80 </ul>
81 */
82 void loadProblem ( const ClpMatrixBase& matrix,
83 const double* collb, const double* colub,
84 const double* obj,
85 const double* rowlb, const double* rowub,
86 const double * rowObjective = nullptr);
87 void loadProblem ( const CoinPackedMatrix& matrix,
88 const double* collb, const double* colub,
89 const double* obj,
90 const double* rowlb, const double* rowub,
91 const double * rowObjective = nullptr);
92
93 /** Just like the other loadProblem() method except that the matrix is
94 given in a standard column major ordered format (without gaps). */
95 void loadProblem ( const int numcols, const int numrows,
96 const CoinBigIndex* start, const int* index,
97 const double* value,
98 const double* collb, const double* colub,
99 const double* obj,
100 const double* rowlb, const double* rowub,
101 const double * rowObjective = nullptr);
102 /** This loads a model from a coinModel object - returns number of errors.
103
104 modelObject not const as may be changed as part of process
105 If tryPlusMinusOne then will try adding as +-1 matrix
106 */
107 int loadProblem ( CoinModel & modelObject, bool tryPlusMinusOne = false);
108 /// This one is for after presolve to save memory
109 void loadProblem ( const int numcols, const int numrows,
110 const CoinBigIndex* start, const int* index,
111 const double* value, const int * length,
112 const double* collb, const double* colub,
113 const double* obj,
114 const double* rowlb, const double* rowub,
115 const double * rowObjective = nullptr);
116 /** Load up quadratic objective. This is stored as a CoinPackedMatrix */
117 void loadQuadraticObjective(const int numberColumns,
118 const CoinBigIndex * start,
119 const int * column, const double * element);
120 void loadQuadraticObjective ( const CoinPackedMatrix& matrix);
121 /// Get rid of quadratic objective
122 void deleteQuadraticObjective();
123 /// This just loads up a row objective
124 void setRowObjective(const double * rowObjective);
125 /// Read an mps file from the given filename
126 int readMps(const char *filename,
127 bool keepNames = false,
128 bool ignoreErrors = false);
129 /// Read GMPL files from the given filenames
130 int readGMPL(const char *filename, const char * dataName,
131 bool keepNames = false);
132 /// Copy in integer informations
133 void copyInIntegerInformation(const char * information);
134 /// Drop integer informations
135 void deleteIntegerInformation();
136 /** Set the index-th variable to be a continuous variable */
137 void setContinuous(int index);
138 /** Set the index-th variable to be an integer variable */
139 void setInteger(int index);
140 /** Return true if the index-th variable is an integer variable */
141 bool isInteger(int index) const;
142 /// Resizes rim part of model
143 void resize (int newNumberRows, int newNumberColumns);
144 /// Deletes rows
145 void deleteRows(int number, const int * which);
146 /// Add one row
147 void addRow(int numberInRow, const int * columns,
148 const double * elements, double rowLower = -COIN_DBL_MAX,
149 double rowUpper = COIN_DBL_MAX);
150 /// Add rows
151 void addRows(int number, const double * rowLower,
152 const double * rowUpper,
153 const CoinBigIndex * rowStarts, const int * columns,
154 const double * elements);
155 /// Add rows
156 void addRows(int number, const double * rowLower,
157 const double * rowUpper,
158 const CoinBigIndex * rowStarts, const int * rowLengths,
159 const int * columns,
160 const double * elements);
161#ifndef CLP_NO_VECTOR
162 void addRows(int number, const double * rowLower,
163 const double * rowUpper,
164 const CoinPackedVectorBase * const * rows);
165#endif
166 /** Add rows from a build object.
167 If tryPlusMinusOne then will try adding as +-1 matrix
168 if no matrix exists.
169 Returns number of errors e.g. duplicates
170 */
171 int addRows(const CoinBuild & buildObject, bool tryPlusMinusOne = false,
172 bool checkDuplicates = true);
173 /** Add rows from a model object. returns
174 -1 if object in bad state (i.e. has column information)
175 otherwise number of errors.
176
177 modelObject non const as can be regularized as part of build
178 If tryPlusMinusOne then will try adding as +-1 matrix
179 if no matrix exists.
180 */
181 int addRows(CoinModel & modelObject, bool tryPlusMinusOne = false,
182 bool checkDuplicates = true);
183
184 /// Deletes columns
185 void deleteColumns(int number, const int * which);
186 /// Add one column
187 void addColumn(int numberInColumn,
188 const int * rows,
189 const double * elements,
190 double columnLower = 0.0,
191 double columnUpper = COIN_DBL_MAX,
192 double objective = 0.0);
193 /// Add columns
194 void addColumns(int number, const double * columnLower,
195 const double * columnUpper,
196 const double * objective,
197 const CoinBigIndex * columnStarts, const int * rows,
198 const double * elements);
199 void addColumns(int number, const double * columnLower,
200 const double * columnUpper,
201 const double * objective,
202 const CoinBigIndex * columnStarts, const int * columnLengths,
203 const int * rows,
204 const double * elements);
205#ifndef CLP_NO_VECTOR
206 void addColumns(int number, const double * columnLower,
207 const double * columnUpper,
208 const double * objective,
209 const CoinPackedVectorBase * const * columns);
210#endif
211 /** Add columns from a build object
212 If tryPlusMinusOne then will try adding as +-1 matrix
213 if no matrix exists.
214 Returns number of errors e.g. duplicates
215 */
216 int addColumns(const CoinBuild & buildObject, bool tryPlusMinusOne = false,
217 bool checkDuplicates = true);
218 /** Add columns from a model object. returns
219 -1 if object in bad state (i.e. has row information)
220 otherwise number of errors
221 modelObject non const as can be regularized as part of build
222 If tryPlusMinusOne then will try adding as +-1 matrix
223 if no matrix exists.
224 */
225 int addColumns(CoinModel & modelObject, bool tryPlusMinusOne = false,
226 bool checkDuplicates = true);
227 /// Modify one element of a matrix
228 inline void modifyCoefficient(int row, int column, double newElement,
229 bool keepZero = false) {
230 matrix_->modifyCoefficient(row, column, newElement, keepZero);
231 }
232 /** Change row lower bounds */
233 void chgRowLower(const double * rowLower);
234 /** Change row upper bounds */
235 void chgRowUpper(const double * rowUpper);
236 /** Change column lower bounds */
237 void chgColumnLower(const double * columnLower);
238 /** Change column upper bounds */
239 void chgColumnUpper(const double * columnUpper);
240 /** Change objective coefficients */
241 void chgObjCoefficients(const double * objIn);
242 /** Borrow model. This is so we don't have to copy large amounts
243 of data around. It assumes a derived class wants to overwrite
244 an empty model with a real one - while it does an algorithm */
245 void borrowModel(ClpModel & otherModel);
246 /** Return model - nulls all arrays so can be deleted safely
247 also updates any scalars */
248 void returnModel(ClpModel & otherModel);
249
250 /// Create empty ClpPackedMatrix
251 void createEmptyMatrix();
252 /** Really clean up matrix (if ClpPackedMatrix).
253 a) eliminate all duplicate AND small elements in matrix
254 b) remove all gaps and set extraGap_ and extraMajor_ to 0.0
255 c) reallocate arrays and make max lengths equal to lengths
256 d) orders elements
257 returns number of elements eliminated or -1 if not ClpPackedMatrix
258 */
259 int cleanMatrix(double threshold = 1.0e-20);
260 /// Copy contents - resizing if necessary - otherwise re-use memory
261 void copy(const ClpMatrixBase * from, ClpMatrixBase * & to);
262#ifndef CLP_NO_STD
263 /// Drops names - makes lengthnames 0 and names empty
264 void dropNames();
265 /// Copies in names
266 void copyNames(std::vector<std::string> & rowNames,
267 std::vector<std::string> & columnNames);
268 /// Copies in Row names - modifies names first .. last-1
269 void copyRowNames(const std::vector<std::string> & rowNames, int first, int last);
270 /// Copies in Column names - modifies names first .. last-1
271 void copyColumnNames(const std::vector<std::string> & columnNames, int first, int last);
272 /// Copies in Row names - modifies names first .. last-1
273 void copyRowNames(const char * const * rowNames, int first, int last);
274 /// Copies in Column names - modifies names first .. last-1
275 void copyColumnNames(const char * const * columnNames, int first, int last);
276 /// Set name of row
277 void setRowName(int rowIndex, std::string & name) ;
278 /// Set name of col
279 void setColumnName(int colIndex, std::string & name) ;
280#endif
281 /** Find a network subset.
282 rotate array should be numberRows. On output
283 -1 not in network
284 0 in network as is
285 1 in network with signs swapped
286 Returns number of network rows
287 */
288 int findNetwork(char * rotate, double fractionNeeded = 0.75);
289 /** This creates a coinModel object
290 */
291 CoinModel * createCoinModel() const;
292
293 /** Write the problem in MPS format to the specified file.
294
295 Row and column names may be null.
296 formatType is
297 <ul>
298 <li> 0 - normal
299 <li> 1 - extra accuracy
300 <li> 2 - IEEE hex
301 </ul>
302
303 Returns non-zero on I/O error
304 */
305 int writeMps(const char *filename,
306 int formatType = 0, int numberAcross = 2,
307 double objSense = 0.0) const ;
308 //@}
309 /**@name gets and sets */
310 //@{
311 /// Number of rows
312 inline int numberRows() const {
313 return numberRows_;
314 }
315 inline int getNumRows() const {
316 return numberRows_;
317 }
318 /// Number of columns
319 inline int getNumCols() const {
320 return numberColumns_;
321 }
322 inline int numberColumns() const {
323 return numberColumns_;
324 }
325 /// Primal tolerance to use
326 inline double primalTolerance() const {
327 return dblParam_[ClpPrimalTolerance];
328 }
329 void setPrimalTolerance( double value) ;
330 /// Dual tolerance to use
331 inline double dualTolerance() const {
332 return dblParam_[ClpDualTolerance];
333 }
334 void setDualTolerance( double value) ;
335 /// Primal objective limit
336 inline double primalObjectiveLimit() const {
337 return dblParam_[ClpPrimalObjectiveLimit];
338 }
339 void setPrimalObjectiveLimit(double value);
340 /// Dual objective limit
341 inline double dualObjectiveLimit() const {
342 return dblParam_[ClpDualObjectiveLimit];
343 }
344 void setDualObjectiveLimit(double value);
345 /// Objective offset
346 inline double objectiveOffset() const {
347 return dblParam_[ClpObjOffset];
348 }
349 void setObjectiveOffset(double value);
350 /// Presolve tolerance to use
351 inline double presolveTolerance() const {
352 return dblParam_[ClpPresolveTolerance];
353 }
354#ifndef CLP_NO_STD
355 inline std::string problemName() const {
356 return strParam_[ClpProbName];
357 }
358#endif
359 /// Number of iterations
360 inline int numberIterations() const {
361 return numberIterations_;
362 }
363 inline int getIterationCount() const {
364 return numberIterations_;
365 }
366 inline void setNumberIterations(int numberIterationsNew) {
367 numberIterations_ = numberIterationsNew;
368 }
369 /** Solve type - 1 simplex, 2 simplex interface, 3 Interior.*/
370 inline int solveType() const {
371 return solveType_;
372 }
373 inline void setSolveType(int type) {
374 solveType_ = type;
375 }
376 /// Maximum number of iterations
377 inline int maximumIterations() const {
378 return intParam_[ClpMaxNumIteration];
379 }
380 void setMaximumIterations(int value);
381 /// Maximum time in seconds (from when set called)
382 inline double maximumSeconds() const {
383 return dblParam_[ClpMaxSeconds];
384 }
385 void setMaximumSeconds(double value);
386 /// Returns true if hit maximum iterations (or time)
387 bool hitMaximumIterations() const;
388 /** Status of problem:
389 -1 - unknown e.g. before solve or if postSolve says not optimal
390 0 - optimal
391 1 - primal infeasible
392 2 - dual infeasible
393 3 - stopped on iterations or time
394 4 - stopped due to errors
395 5 - stopped by event handler (virtual int ClpEventHandler::event())
396 */
397 inline int status() const {
398 return problemStatus_;
399 }
400 inline int problemStatus() const {
401 return problemStatus_;
402 }
403 /// Set problem status
404 inline void setProblemStatus(int problemStatusNew) {
405 problemStatus_ = problemStatusNew;
406 }
407 /** Secondary status of problem - may get extended
408 0 - none
409 1 - primal infeasible because dual limit reached OR (probably primal
410 infeasible but can't prove it - main status was 4)
411 2 - scaled problem optimal - unscaled problem has primal infeasibilities
412 3 - scaled problem optimal - unscaled problem has dual infeasibilities
413 4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities
414 5 - giving up in primal with flagged variables
415 6 - failed due to empty problem check
416 7 - postSolve says not optimal
417 8 - failed due to bad element check
418 9 - status was 3 and stopped on time
419 100 up - translation of enum from ClpEventHandler
420 */
421 inline int secondaryStatus() const {
422 return secondaryStatus_;
423 }
424 inline void setSecondaryStatus(int newstatus) {
425 secondaryStatus_ = newstatus;
426 }
427 /// Are there a numerical difficulties?
428 inline bool isAbandoned() const {
429 return problemStatus_ == 4;
430 }
431 /// Is optimality proven?
432 inline bool isProvenOptimal() const {
433 return problemStatus_ == 0;
434 }
435 /// Is primal infeasiblity proven?
436 inline bool isProvenPrimalInfeasible() const {
437 return problemStatus_ == 1;
438 }
439 /// Is dual infeasiblity proven?
440 inline bool isProvenDualInfeasible() const {
441 return problemStatus_ == 2;
442 }
443 /// Is the given primal objective limit reached?
444 bool isPrimalObjectiveLimitReached() const ;
445 /// Is the given dual objective limit reached?
446 bool isDualObjectiveLimitReached() const ;
447 /// Iteration limit reached?
448 inline bool isIterationLimitReached() const {
449 return problemStatus_ == 3;
450 }
451 /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore
452 inline double optimizationDirection() const {
453 return optimizationDirection_;
454 }
455 inline double getObjSense() const {
456 return optimizationDirection_;
457 }
458 void setOptimizationDirection(double value);
459 /// Primal row solution
460 inline double * primalRowSolution() const {
461 return rowActivity_;
462 }
463 inline const double * getRowActivity() const {
464 return rowActivity_;
465 }
466 /// Primal column solution
467 inline double * primalColumnSolution() const {
468 return columnActivity_;
469 }
470 inline const double * getColSolution() const {
471 return columnActivity_;
472 }
473 inline void setColSolution(const double * input) {
474 memcpy(columnActivity_, input, numberColumns_ * sizeof(double));
475 }
476 /// Dual row solution
477 inline double * dualRowSolution() const {
478 return dual_;
479 }
480 inline const double * getRowPrice() const {
481 return dual_;
482 }
483 /// Reduced costs
484 inline double * dualColumnSolution() const {
485 return reducedCost_;
486 }
487 inline const double * getReducedCost() const {
488 return reducedCost_;
489 }
490 /// Row lower
491 inline double* rowLower() const {
492 return rowLower_;
493 }
494 inline const double* getRowLower() const {
495 return rowLower_;
496 }
497 /// Row upper
498 inline double* rowUpper() const {
499 return rowUpper_;
500 }
501 inline const double* getRowUpper() const {
502 return rowUpper_;
503 }
504 //-------------------------------------------------------------------------
505 /**@name Changing bounds on variables and constraints */
506 //@{
507 /** Set an objective function coefficient */
508 void setObjectiveCoefficient( int elementIndex, double elementValue );
509 /** Set an objective function coefficient */
510 inline void setObjCoeff( int elementIndex, double elementValue ) {
511 setObjectiveCoefficient( elementIndex, elementValue);
512 }
513
514 /** Set a single column lower bound<br>
515 Use -DBL_MAX for -infinity. */
516 void setColumnLower( int elementIndex, double elementValue );
517
518 /** Set a single column upper bound<br>
519 Use DBL_MAX for infinity. */
520 void setColumnUpper( int elementIndex, double elementValue );
521
522 /** Set a single column lower and upper bound */
523 void setColumnBounds( int elementIndex,
524 double lower, double upper );
525
526 /** Set the bounds on a number of columns simultaneously<br>
527 The default implementation just invokes setColLower() and
528 setColUpper() over and over again.
529 @param indexFirst,indexLast pointers to the beginning and after the
530 end of the array of the indices of the variables whose
531 <em>either</em> bound changes
532 @param boundList the new lower/upper bound pairs for the variables
533 */
534 void setColumnSetBounds(const int* indexFirst,
535 const int* indexLast,
536 const double* boundList);
537
538 /** Set a single column lower bound<br>
539 Use -DBL_MAX for -infinity. */
540 inline void setColLower( int elementIndex, double elementValue ) {
541 setColumnLower(elementIndex, elementValue);
542 }
543 /** Set a single column upper bound<br>
544 Use DBL_MAX for infinity. */
545 inline void setColUpper( int elementIndex, double elementValue ) {
546 setColumnUpper(elementIndex, elementValue);
547 }
548
549 /** Set a single column lower and upper bound */
550 inline void setColBounds( int elementIndex,
551 double lower, double upper ) {
552 setColumnBounds(elementIndex, lower, upper);
553 }
554
555 /** Set the bounds on a number of columns simultaneously<br>
556 @param indexFirst,indexLast pointers to the beginning and after the
557 end of the array of the indices of the variables whose
558 <em>either</em> bound changes
559 @param boundList the new lower/upper bound pairs for the variables
560 */
561 inline void setColSetBounds(const int* indexFirst,
562 const int* indexLast,
563 const double* boundList) {
564 setColumnSetBounds(indexFirst, indexLast, boundList);
565 }
566
567 /** Set a single row lower bound<br>
568 Use -DBL_MAX for -infinity. */
569 void setRowLower( int elementIndex, double elementValue );
570
571 /** Set a single row upper bound<br>
572 Use DBL_MAX for infinity. */
573 void setRowUpper( int elementIndex, double elementValue ) ;
574
575 /** Set a single row lower and upper bound */
576 void setRowBounds( int elementIndex,
577 double lower, double upper ) ;
578
579 /** Set the bounds on a number of rows simultaneously<br>
580 @param indexFirst,indexLast pointers to the beginning and after the
581 end of the array of the indices of the constraints whose
582 <em>either</em> bound changes
583 @param boundList the new lower/upper bound pairs for the constraints
584 */
585 void setRowSetBounds(const int* indexFirst,
586 const int* indexLast,
587 const double* boundList);
588
589 //@}
590 /// Scaling
591 inline const double * rowScale() const {
592 return rowScale_;
593 }
594 inline const double * columnScale() const {
595 return columnScale_;
596 }
597 inline const double * inverseRowScale() const {
598 return inverseRowScale_;
599 }
600 inline const double * inverseColumnScale() const {
601 return inverseColumnScale_;
602 }
603 inline double * mutableRowScale() const {
604 return rowScale_;
605 }
606 inline double * mutableColumnScale() const {
607 return columnScale_;
608 }
609 inline double * mutableInverseRowScale() const {
610 return inverseRowScale_;
611 }
612 inline double * mutableInverseColumnScale() const {
613 return inverseColumnScale_;
614 }
615 void setRowScale(double * scale) ;
616 void setColumnScale(double * scale);
617 /// Scaling of objective
618 inline double objectiveScale() const {
619 return objectiveScale_;
620 }
621 inline void setObjectiveScale(double value) {
622 objectiveScale_ = value;
623 }
624 /// Scaling of rhs and bounds
625 inline double rhsScale() const {
626 return rhsScale_;
627 }
628 inline void setRhsScale(double value) {
629 rhsScale_ = value;
630 }
631 /// Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3 auto, 4 auto-but-as-initialSolve-in-bab
632 void scaling(int mode = 1);
633 /** If we constructed a "really" scaled model then this reverses the operation.
634 Quantities may not be exactly as they were before due to rounding errors */
635 void unscale();
636 /// Gets scalingFlag
637 inline int scalingFlag() const {
638 return scalingFlag_;
639 }
640 /// Objective
641 inline double * objective() const {
642 if (objective_) {
643 double offset;
644 return objective_->gradient(nullptr, nullptr, offset, false);
645 } else {
646 return nullptr;
647 }
648 }
649 inline double * objective(const double * solution, double & offset, bool refresh = true) const {
650 offset = 0.0;
651 if (objective_) {
652 return objective_->gradient(nullptr, solution, offset, refresh);
653 } else {
654 return nullptr;
655 }
656 }
657 inline const double * getObjCoefficients() const {
658 if (objective_) {
659 double offset;
660 return objective_->gradient(nullptr, nullptr, offset, false);
661 } else {
662 return nullptr;
663 }
664 }
665 /// Row Objective
666 inline double * rowObjective() const {
667 return rowObjective_;
668 }
669 inline const double * getRowObjCoefficients() const {
670 return rowObjective_;
671 }
672 /// Column Lower
673 inline double * columnLower() const {
674 return columnLower_;
675 }
676 inline const double * getColLower() const {
677 return columnLower_;
678 }
679 /// Column Upper
680 inline double * columnUpper() const {
681 return columnUpper_;
682 }
683 inline const double * getColUpper() const {
684 return columnUpper_;
685 }
686 /// Matrix (if not ClpPackedmatrix be careful about memory leak
687 inline CoinPackedMatrix * matrix() const {
688 if ( matrix_ == nullptr ) return nullptr;
689 else return matrix_->getPackedMatrix();
690 }
691 /// Number of elements in matrix
692 inline int getNumElements() const {
693 return matrix_->getNumElements();
694 }
695 /** Small element value - elements less than this set to zero,
696 default is 1.0e-20 */
697 inline double getSmallElementValue() const {
698 return smallElement_;
699 }
700 inline void setSmallElementValue(double value) {
701 smallElement_ = value;
702 }
703 /// Row Matrix
704 inline ClpMatrixBase * rowCopy() const {
705 return rowCopy_;
706 }
707 /// Set new row matrix
708 void setNewRowCopy(ClpMatrixBase * newCopy);
709 /// Clp Matrix
710 inline ClpMatrixBase * clpMatrix() const {
711 return matrix_;
712 }
713 /// Scaled ClpPackedMatrix
714 inline ClpPackedMatrix * clpScaledMatrix() const {
715 return scaledMatrix_;
716 }
717 /// Sets pointer to scaled ClpPackedMatrix
718 inline void setClpScaledMatrix(ClpPackedMatrix * scaledMatrix) {
719 delete scaledMatrix_;
720 scaledMatrix_ = scaledMatrix;
721 }
722 /** Replace Clp Matrix (current is not deleted unless told to
723 and new is used)
724 So up to user to delete current. This was used where
725 matrices were being rotated. ClpModel takes ownership.
726 */
727 void replaceMatrix(ClpMatrixBase * matrix, bool deleteCurrent = false);
728 /** Replace Clp Matrix (current is not deleted unless told to
729 and new is used) So up to user to delete current. This was used where
730 matrices were being rotated. This version changes CoinPackedMatrix
731 to ClpPackedMatrix. ClpModel takes ownership.
732 */
733 inline void replaceMatrix(CoinPackedMatrix * newmatrix,
734 bool deleteCurrent = false) {
735 replaceMatrix(new ClpPackedMatrix(newmatrix), deleteCurrent);
736 }
737 /// Objective value
738 inline double objectiveValue() const {
739 return objectiveValue_ * optimizationDirection_ - dblParam_[ClpObjOffset];
740 }
741 inline void setObjectiveValue(double value) {
742 objectiveValue_ = (value + dblParam_[ClpObjOffset]) / optimizationDirection_;
743 }
744 inline double getObjValue() const {
745 return objectiveValue_ * optimizationDirection_ - dblParam_[ClpObjOffset];
746 }
747 /// Integer information
748 inline char * integerInformation() const {
749 return integerType_;
750 }
751 /** Infeasibility/unbounded ray (NULL returned if none/wrong)
752 Up to user to use delete [] on these arrays. */
753 double * infeasibilityRay() const;
754 double * unboundedRay() const;
755 /// just test if infeasibility or unbounded Ray exists
756 inline bool rayExists() const {
757 return (ray_!=nullptr);
758 }
759 /// just delete ray if exists
760 inline void deleteRay() {
761 delete [] ray_;
762 ray_=nullptr;
763 }
764 /// See if status (i.e. basis) array exists (partly for OsiClp)
765 inline bool statusExists() const {
766 return (status_ != nullptr);
767 }
768 /// Return address of status (i.e. basis) array (char[numberRows+numberColumns])
769 inline unsigned char * statusArray() const {
770 return status_;
771 }
772 /** Return copy of status (i.e. basis) array (char[numberRows+numberColumns]),
773 use delete [] */
774 unsigned char * statusCopy() const;
775 /// Copy in status (basis) vector
776 void copyinStatus(const unsigned char * statusArray);
777
778 /// User pointer for whatever reason
779 inline void setUserPointer (void * pointer) {
780 userPointer_ = pointer;
781 }
782 inline void * getUserPointer () const {
783 return userPointer_;
784 }
785 /// Trusted user pointer
786 inline void setTrustedUserPointer (ClpTrustedData * pointer) {
787 trustedUserPointer_ = pointer;
788 }
789 inline ClpTrustedData * getTrustedUserPointer () const {
790 return trustedUserPointer_;
791 }
792 /// What has changed in model (only for masochistic users)
793 inline int whatsChanged() const {
794 return whatsChanged_;
795 }
796 inline void setWhatsChanged(int value) {
797 whatsChanged_ = value;
798 }
799 /// Number of threads (not really being used)
800 inline int numberThreads() const {
801 return numberThreads_;
802 }
803 inline void setNumberThreads(int value) {
804 numberThreads_ = value;
805 }
806 //@}
807 /**@name Message handling */
808 //@{
809 /// Pass in Message handler (not deleted at end)
810 void passInMessageHandler(CoinMessageHandler * handler);
811 /// Pass in Message handler (not deleted at end) and return current
812 CoinMessageHandler * pushMessageHandler(CoinMessageHandler * handler,
813 bool & oldDefault);
814 /// back to previous message handler
815 void popMessageHandler(CoinMessageHandler * oldHandler, bool oldDefault);
816 /// Set language
817 void newLanguage(CoinMessages::Language language);
818 inline void setLanguage(CoinMessages::Language language) {
819 newLanguage(language);
820 }
821 /// Return handler
822 inline CoinMessageHandler * messageHandler() const {
823 return handler_;
824 }
825 /// Return messages
826 inline CoinMessages messages() const {
827 return messages_;
828 }
829 /// Return pointer to messages
830 inline CoinMessages * messagesPointer() {
831 return & messages_;
832 }
833 /// Return Coin messages
834 inline CoinMessages coinMessages() const {
835 return coinMessages_;
836 }
837 /// Return pointer to Coin messages
838 inline CoinMessages * coinMessagesPointer() {
839 return & coinMessages_;
840 }
841 /** Amount of print out:
842 0 - none
843 1 - just final
844 2 - just factorizations
845 3 - as 2 plus a bit more
846 4 - verbose
847 above that 8,16,32 etc just for selective debug
848 */
849 inline void setLogLevel(int value) {
850 handler_->setLogLevel(value);
851 }
852 inline int logLevel() const {
853 return handler_->logLevel();
854 }
855 /// Return true if default handler
856 inline bool defaultHandler() const {
857 return defaultHandler_;
858 }
859 /// Pass in Event handler (cloned and deleted at end)
860 void passInEventHandler(const ClpEventHandler * eventHandler);
861 /// Event handler
862 inline ClpEventHandler * eventHandler() const {
863 return eventHandler_;
864 }
865 /// Thread specific random number generator
866 inline CoinThreadRandom * randomNumberGenerator() {
867 return &randomNumberGenerator_;
868 }
869 /// Thread specific random number generator
870 inline CoinThreadRandom & mutableRandomNumberGenerator() {
871 return randomNumberGenerator_;
872 }
873 /// Set seed for thread specific random number generator
874 inline void setRandomSeed(int value) {
875 randomNumberGenerator_.setSeed(value);
876 }
877 /// length of names (0 means no names0
878 inline int lengthNames() const {
879 return lengthNames_;
880 }
881#ifndef CLP_NO_STD
882 /// length of names (0 means no names0
883 inline void setLengthNames(int value) {
884 lengthNames_ = value;
885 }
886 /// Row names
887 inline const std::vector<std::string> * rowNames() const {
888 return &rowNames_;
889 }
890 inline const std::string& rowName(int iRow) const {
891 return rowNames_[iRow];
892 }
893 /// Return name or Rnnnnnnn
894 std::string getRowName(int iRow) const;
895 /// Column names
896 inline const std::vector<std::string> * columnNames() const {
897 return &columnNames_;
898 }
899 inline const std::string& columnName(int iColumn) const {
900 return columnNames_[iColumn];
901 }
902 /// Return name or Cnnnnnnn
903 std::string getColumnName(int iColumn) const;
904#endif
905 /// Objective methods
906 inline ClpObjective * objectiveAsObject() const {
907 return objective_;
908 }
909 void setObjective(ClpObjective * objective);
910 inline void setObjectivePointer(ClpObjective * newobjective) {
911 objective_ = newobjective;
912 }
913 /** Solve a problem with no elements - return status and
914 dual and primal infeasibilites */
915 int emptyProblem(int * infeasNumber = nullptr, double * infeasSum = nullptr, bool printMessage = true);
916
917 //@}
918
919 /**@name Matrix times vector methods
920 They can be faster if scalar is +- 1
921 These are covers so user need not worry about scaling
922 Also for simplex I am not using basic/non-basic split */
923 //@{
924 /** Return <code>y + A * x * scalar</code> in <code>y</code>.
925 @pre <code>x</code> must be of size <code>numColumns()</code>
926 @pre <code>y</code> must be of size <code>numRows()</code> */
927 void times(double scalar,
928 const double * x, double * y) const;
929 /** Return <code>y + x * scalar * A</code> in <code>y</code>.
930 @pre <code>x</code> must be of size <code>numRows()</code>
931 @pre <code>y</code> must be of size <code>numColumns()</code> */
932 void transposeTimes(double scalar,
933 const double * x, double * y) const ;
934 //@}
935
936
937 //---------------------------------------------------------------------------
938 /**@name Parameter set/get methods
939
940 The set methods return true if the parameter was set to the given value,
941 false otherwise. There can be various reasons for failure: the given
942 parameter is not applicable for the solver (e.g., refactorization
943 frequency for the volume algorithm), the parameter is not yet implemented
944 for the solver or simply the value of the parameter is out of the range
945 the solver accepts. If a parameter setting call returns false check the
946 details of your solver.
947
948 The get methods return true if the given parameter is applicable for the
949 solver and is implemented. In this case the value of the parameter is
950 returned in the second argument. Otherwise they return false.
951
952 ** once it has been decided where solver sits this may be redone
953 */
954 //@{
955 /// Set an integer parameter
956 bool setIntParam(ClpIntParam key, int value) ;
957 /// Set an double parameter
958 bool setDblParam(ClpDblParam key, double value) ;
959#ifndef CLP_NO_STD
960 /// Set an string parameter
961 bool setStrParam(ClpStrParam key, const std::string & value);
962#endif
963 // Get an integer parameter
964 inline bool getIntParam(ClpIntParam key, int& value) const {
965 if (key < ClpLastIntParam) {
966 value = intParam_[key];
967 return true;
968 } else {
969 return false;
970 }
971 }
972 // Get an double parameter
973 inline bool getDblParam(ClpDblParam key, double& value) const {
974 if (key < ClpLastDblParam) {
975 value = dblParam_[key];
976 return true;
977 } else {
978 return false;
979 }
980 }
981#ifndef CLP_NO_STD
982 // Get a string parameter
983 inline bool getStrParam(ClpStrParam key, std::string& value) const {
984 if (key < ClpLastStrParam) {
985 value = strParam_[key];
986 return true;
987 } else {
988 return false;
989 }
990 }
991#endif
992 /// Create C++ lines to get to current state
993 void generateCpp( FILE * fp);
994 /** For advanced options
995 1 - Don't keep changing infeasibility weight
996 2 - Keep nonLinearCost round solves
997 4 - Force outgoing variables to exact bound (primal)
998 8 - Safe to use dense initial factorization
999 16 -Just use basic variables for operation if column generation
1000 32 -Create ray even in BAB
1001 64 -Treat problem as feasible until last minute (i.e. minimize infeasibilities)
1002 128 - Switch off all matrix sanity checks
1003 256 - No row copy
1004 512 - If not in values pass, solution guaranteed, skip as much as possible
1005 1024 - In branch and bound
1006 2048 - Don't bother to re-factorize if < 20 iterations
1007 4096 - Skip some optimality checks
1008 8192 - Do Primal when cleaning up primal
1009 16384 - In fast dual (so we can switch off things)
1010 32768 - called from Osi
1011 65536 - keep arrays around as much as possible (also use maximumR/C)
1012 131072 - transposeTimes is -1.0 and can skip basic and fixed
1013 262144 - extra copy of scaled matrix
1014 524288 - Clp fast dual
1015 1048576 - don't need to finish dual (can return 3)
1016 NOTE - many applications can call Clp but there may be some short cuts
1017 which are taken which are not guaranteed safe from all applications.
1018 Vetted applications will have a bit set and the code may test this
1019 At present I expect a few such applications - if too many I will
1020 have to re-think. It is up to application owner to change the code
1021 if she/he needs these short cuts. I will not debug unless in Coin
1022 repository. See COIN_CLP_VETTED comments.
1023 0x01000000 is Cbc (and in branch and bound)
1024 0x02000000 is in a different branch and bound
1025 */
1026 inline unsigned int specialOptions() const {
1027 return specialOptions_;
1028 }
1029 void setSpecialOptions(unsigned int value);
1030#define COIN_CBC_USING_CLP 0x01000000
1031 inline bool inCbcBranchAndBound() const {
1032 return (specialOptions_ & COIN_CBC_USING_CLP) != 0;
1033 }
1034 //@}
1035
1036 /**@name private or protected methods */
1037 //@{
1038protected:
1039 /// Does most of deletion (0 = all, 1 = most)
1040 void gutsOfDelete(int type);
1041 /** Does most of copying
1042 If trueCopy 0 then just points to arrays
1043 If -1 leaves as much as possible */
1044 void gutsOfCopy(const ClpModel & rhs, int trueCopy = 1);
1045 /// gets lower and upper bounds on rows
1046 void getRowBound(int iRow, double& lower, double& upper) const;
1047 /// puts in format I like - 4 array matrix - may make row copy
1048 void gutsOfLoadModel ( int numberRows, int numberColumns,
1049 const double* collb, const double* colub,
1050 const double* obj,
1051 const double* rowlb, const double* rowub,
1052 const double * rowObjective = nullptr);
1053 /// Does much of scaling
1054 void gutsOfScaling();
1055 /// Objective value - always minimize
1056 inline double rawObjectiveValue() const {
1057 return objectiveValue_;
1058 }
1059 /// If we are using maximumRows_ and Columns_
1060 inline bool permanentArrays() const {
1061 return (specialOptions_ & 65536) != 0;
1062 }
1063 /// Start using maximumRows_ and Columns_
1064 void startPermanentArrays();
1065 /// Stop using maximumRows_ and Columns_
1066 void stopPermanentArrays();
1067 /// Create row names as char **
1068 const char * const * rowNamesAsChar() const;
1069 /// Create column names as char **
1070 const char * const * columnNamesAsChar() const;
1071 /// Delete char * version of names
1072 void deleteNamesAsChar(const char * const * names, int number) const;
1073 /// On stopped - sets secondary status
1074 void onStopped();
1075 //@}
1076
1077
1078////////////////// data //////////////////
1079protected:
1080
1081 /**@name data */
1082 //@{
1083 /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore
1084 double optimizationDirection_;
1085 /// Array of double parameters
1086 double dblParam_[ClpLastDblParam];
1087 /// Objective value
1088 double objectiveValue_;
1089 /// Small element value
1090 double smallElement_;
1091 /// Scaling of objective
1092 double objectiveScale_;
1093 /// Scaling of rhs and bounds
1094 double rhsScale_;
1095 /// Number of rows
1096 int numberRows_;
1097 /// Number of columns
1098 int numberColumns_;
1099 /// Row activities
1100 double * rowActivity_;
1101 /// Column activities
1102 double * columnActivity_;
1103 /// Duals
1104 double * dual_;
1105 /// Reduced costs
1106 double * reducedCost_;
1107 /// Row lower
1108 double* rowLower_;
1109 /// Row upper
1110 double* rowUpper_;
1111 /// Objective
1112 ClpObjective * objective_;
1113 /// Row Objective (? sign) - may be NULL
1114 double * rowObjective_;
1115 /// Column Lower
1116 double * columnLower_;
1117 /// Column Upper
1118 double * columnUpper_;
1119 /// Packed matrix
1120 ClpMatrixBase * matrix_;
1121 /// Row copy if wanted
1122 ClpMatrixBase * rowCopy_;
1123 /// Scaled packed matrix
1124 ClpPackedMatrix * scaledMatrix_;
1125 /// Infeasible/unbounded ray
1126 double * ray_;
1127 /// Row scale factors for matrix
1128 double * rowScale_;
1129 /// Column scale factors
1130 double * columnScale_;
1131 /// Inverse row scale factors for matrix (end of rowScale_)
1132 double * inverseRowScale_;
1133 /// Inverse column scale factors for matrix (end of columnScale_)
1134 double * inverseColumnScale_;
1135 /** Scale flag, 0 none, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic,
1136 5 geometric on rows */
1137 int scalingFlag_;
1138 /** Status (i.e. basis) Region. I know that not all algorithms need a status
1139 array, but it made sense for things like crossover and put
1140 all permanent stuff in one place. No assumption is made
1141 about what is in status array (although it might be good to reserve
1142 bottom 3 bits (i.e. 0-7 numeric) for classic status). This
1143 is number of columns + number of rows long (in that order).
1144 */
1145 unsigned char * status_;
1146 /// Integer information
1147 char * integerType_;
1148 /// User pointer for whatever reason
1149 void * userPointer_;
1150 /// Trusted user pointer e.g. for heuristics
1151 ClpTrustedData * trustedUserPointer_;
1152 /// Array of integer parameters
1153 int intParam_[ClpLastIntParam];
1154 /// Number of iterations
1155 int numberIterations_;
1156 /** Solve type - 1 simplex, 2 simplex interface, 3 Interior.*/
1157 int solveType_;
1158 /** Whats changed since last solve. This is a work in progress
1159 It is designed so careful people can make go faster.
1160 It is only used when startFinishOptions used in dual or primal.
1161 Bit 1 - number of rows/columns has not changed (so work arrays valid)
1162 2 - matrix has not changed
1163 4 - if matrix has changed only by adding rows
1164 8 - if matrix has changed only by adding columns
1165 16 - row lbs not changed
1166 32 - row ubs not changed
1167 64 - column objective not changed
1168 128 - column lbs not changed
1169 256 - column ubs not changed
1170 512 - basis not changed (up to user to set this to 0)
1171 top bits may be used internally
1172 shift by 65336 is 3 all same, 1 all except col bounds
1173 */
1174 unsigned int whatsChanged_;
1175 /// Status of problem
1176 int problemStatus_;
1177 /// Secondary status of problem
1178 int secondaryStatus_;
1179 /// length of names (0 means no names)
1180 int lengthNames_;
1181 /// Number of threads (not very operational)
1182 int numberThreads_;
1183 /** For advanced options
1184 See get and set for meaning
1185 */
1186 unsigned int specialOptions_;
1187 /// Message handler
1188 CoinMessageHandler * handler_;
1189 /// Flag to say if default handler (so delete)
1190 bool defaultHandler_;
1191 /// Thread specific random number generator
1192 CoinThreadRandom randomNumberGenerator_;
1193 /// Event handler
1194 ClpEventHandler * eventHandler_;
1195#ifndef CLP_NO_STD
1196 /// Row names
1197 std::vector<std::string> rowNames_;
1198 /// Column names
1199 std::vector<std::string> columnNames_;
1200#endif
1201 /// Messages
1202 CoinMessages messages_;
1203 /// Coin messages
1204 CoinMessages coinMessages_;
1205 /// Maximum number of columns in model
1206 int maximumColumns_;
1207 /// Maximum number of rows in model
1208 int maximumRows_;
1209 /// Maximum number of columns (internal arrays) in model
1210 int maximumInternalColumns_;
1211 /// Maximum number of rows (internal arrays) in model
1212 int maximumInternalRows_;
1213 /// Base packed matrix
1214 CoinPackedMatrix baseMatrix_;
1215 /// Base row copy
1216 CoinPackedMatrix baseRowCopy_;
1217 /// Saved row scale factors for matrix
1218 double * savedRowScale_;
1219 /// Saved column scale factors
1220 double * savedColumnScale_;
1221#ifndef CLP_NO_STD
1222 /// Array of string parameters
1223 std::string strParam_[ClpLastStrParam];
1224#endif
1225 //@}
1226};
1227/** This is a tiny class where data can be saved round calls.
1228 */
1229class ClpDataSave {
1230
1231public:
1232 /**@name Constructors and destructor
1233 */
1234 //@{
1235 /// Default constructor
1236 ClpDataSave ( );
1237
1238 /// Copy constructor.
1239 ClpDataSave(const ClpDataSave &);
1240 /// Assignment operator. This copies the data
1241 ClpDataSave & operator=(const ClpDataSave & rhs);
1242 /// Destructor
1243 ~ClpDataSave ( );
1244
1245 //@}
1246
1247////////////////// data //////////////////
1248public:
1249
1250 /**@name data - with same names as in other classes*/
1251 //@{
1252 double dualBound_;
1253 double infeasibilityCost_;
1254 double pivotTolerance_;
1255 double zeroFactorizationTolerance_;
1256 double zeroSimplexTolerance_;
1257 double acceptablePivot_;
1258 double objectiveScale_;
1259 int sparseThreshold_;
1260 int perturbation_;
1261 int forceFactorization_;
1262 int scalingFlag_;
1263 unsigned int specialOptions_;
1264 //@}
1265};
1266
1267#endif
1268