1 : // Copyright (C) 2002, International Business Machines
2 : // Corporation and others. All Rights Reserved.
3 : #ifndef ClpModel_H
4 : #define ClpModel_H
5 :
6 : #include "ClpConfig.h"
7 :
8 : #include <iostream>
9 : #include <cassert>
10 : #include <cmath>
11 : #include <vector>
12 : #include <string>
13 : //#ifndef COIN_USE_CLP
14 : //#define COIN_USE_CLP
15 : //#endif
16 : #include "ClpPackedMatrix.hpp"
17 : #include "CoinMessageHandler.hpp"
18 : #include "ClpParameters.hpp"
19 : #include "ClpObjective.hpp"
20 : class ClpEventHandler;
21 :
22 : // Plus infinity
23 : #ifndef COIN_DBL_MAX
24 : #define COIN_DBL_MAX DBL_MAX
25 : #endif
26 :
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 : */
36 : class CoinBuild;
37 : class CoinModel;
38 : class ClpModel {
39 :
40 : public:
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 dynamic(later)
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=NULL);
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=NULL);
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=NULL);
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=NULL);
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 0 : bool keepZero=false)
230 0 : {matrix_->modifyCoefficient(row,column,newElement,keepZero);}
231 : /** Change row lower bounds */
232 : void chgRowLower(const double * rowLower);
233 : /** Change row upper bounds */
234 : void chgRowUpper(const double * rowUpper);
235 : /** Change column lower bounds */
236 : void chgColumnLower(const double * columnLower);
237 : /** Change column upper bounds */
238 : void chgColumnUpper(const double * columnUpper);
239 : /** Change objective coefficients */
240 : void chgObjCoefficients(const double * objIn);
241 : /** Borrow model. This is so we don't have to copy large amounts
242 : of data around. It assumes a derived class wants to overwrite
243 : an empty model with a real one - while it does an algorithm */
244 : void borrowModel(ClpModel & otherModel);
245 : /** Return model - nulls all arrays so can be deleted safely
246 : also updates any scalars */
247 : void returnModel(ClpModel & otherModel);
248 :
249 : /// Create empty ClpPackedMatrix
250 : void createEmptyMatrix();
251 : /** Really clean up matrix (if ClpPackedMatrix).
252 : a) eliminate all duplicate AND small elements in matrix
253 : b) remove all gaps and set extraGap_ and extraMajor_ to 0.0
254 : c) reallocate arrays and make max lengths equal to lengths
255 : d) orders elements
256 : returns number of elements eliminated or -1 if not ClpPackedMatrix
257 : */
258 : int cleanMatrix(double threshold=1.0e-20);
259 : #ifndef CLP_NO_STD
260 : /// Drops names - makes lengthnames 0 and names empty
261 : void dropNames();
262 : /// Copies in names
263 : void copyNames(std::vector<std::string> & rowNames,
264 : std::vector<std::string> & columnNames);
265 : /// Copies in Row names - modifies names first .. last-1
266 : void copyRowNames(const std::vector<std::string> & rowNames,int first, int last);
267 : /// Copies in Column names - modifies names first .. last-1
268 : void copyColumnNames(const std::vector<std::string> & columnNames, int first, int last);
269 : /// Copies in Row names - modifies names first .. last-1
270 : void copyRowNames(const char * const * rowNames,int first, int last);
271 : /// Copies in Column names - modifies names first .. last-1
272 : void copyColumnNames(const char * const * columnNames, int first, int last);
273 : /// Set name of row
274 : void setRowName(int rowIndex, std::string & name) ;
275 : /// Set name of col
276 : void setColumnName(int colIndex, std::string & name) ;
277 : #endif
278 : /** Find a network subset.
279 : rotate array should be numberRows. On output
280 : -1 not in network
281 : 0 in network as is
282 : 1 in network with signs swapped
283 : Returns number of network rows
284 : */
285 : int findNetwork(char * rotate, double fractionNeeded=0.75);
286 : /** This creates a coinModel object
287 : */
288 : CoinModel * createCoinModel() const;
289 :
290 : /** Write the problem in MPS format to the specified file.
291 :
292 : Row and column names may be null.
293 : formatType is
294 : <ul>
295 : <li> 0 - normal
296 : <li> 1 - extra accuracy
297 : <li> 2 - IEEE hex (later)
298 : </ul>
299 :
300 : Returns non-zero on I/O error
301 : */
302 : int writeMps(const char *filename,
303 : int formatType=0,int numberAcross=2,
304 : double objSense=0.0) const ;
305 : //@}
306 : /**@name gets and sets */
307 : //@{
308 : /// Number of rows
309 28038061 : inline int numberRows() const {
310 28038061 : return numberRows_;
311 : }
312 : inline int getNumRows() const {
313 : return numberRows_;
314 : }
315 : /// Number of columns
316 : inline int getNumCols() const {
317 : return numberColumns_;
318 : }
319 57305488 : inline int numberColumns() const {
320 57305488 : return numberColumns_;
321 : }
322 : /// Primal tolerance to use
323 : inline double primalTolerance() const {
324 : return dblParam_[ClpPrimalTolerance];
325 : }
326 : void setPrimalTolerance( double value) ;
327 : /// Dual tolerance to use
328 : inline double dualTolerance() const { return dblParam_[ClpDualTolerance]; }
329 : void setDualTolerance( double value) ;
330 : /// Primal objective limit
331 : inline double primalObjectiveLimit() const { return dblParam_[ClpPrimalObjectiveLimit];}
332 : void setPrimalObjectiveLimit(double value);
333 : /// Dual objective limit
334 : inline double dualObjectiveLimit() const { return dblParam_[ClpDualObjectiveLimit];}
335 : void setDualObjectiveLimit(double value);
336 : /// Objective offset
337 : inline double objectiveOffset() const { return dblParam_[ClpObjOffset];}
338 : void setObjectiveOffset(double value);
339 : #ifndef CLP_NO_STD
340 : inline std::string problemName() const { return strParam_[ClpProbName]; }
341 : #endif
342 : /// Number of iterations
343 11151404 : inline int numberIterations() const { return numberIterations_; }
344 : inline int getIterationCount() const { return numberIterations_; }
345 : inline void setNumberIterations(int numberIterations)
346 : { numberIterations_ = numberIterations;}
347 : /** Solve type - 1 simplex, 2 simplex interface, 3 Interior.*/
348 : inline int solveType() const
349 : { return solveType_;}
350 : inline void setSolveType(int type)
351 : { solveType_=type;}
352 : /// Maximum number of iterations
353 : inline int maximumIterations() const { return intParam_[ClpMaxNumIteration]; }
354 : void setMaximumIterations(int value);
355 : /// Maximum time in seconds (from when set called)
356 : inline double maximumSeconds() const { return dblParam_[ClpMaxSeconds]; }
357 : void setMaximumSeconds(double value);
358 : /// Returns true if hit maximum iterations (or time)
359 : bool hitMaximumIterations() const;
360 : /** Status of problem:
361 : -1 - unknown e.g. before solve or if postSolve says not optimal
362 : 0 - optimal
363 : 1 - primal infeasible
364 : 2 - dual infeasible
365 : 3 - stopped on iterations or time
366 : 4 - stopped due to errors
367 : 5 - stopped by event handler (virtual int ClpEventHandler::event())
368 : */
369 : inline int status() const { return problemStatus_; }
370 : inline int problemStatus() const { return problemStatus_; }
371 : /// Set problem status
372 : inline void setProblemStatus(int problemStatus)
373 : { problemStatus_ = problemStatus;}
374 : /** Secondary status of problem - may get extended
375 : 0 - none
376 : 1 - primal infeasible because dual limit reached OR probably primal
377 : infeasible but can't prove it (main status 4)
378 : 2 - scaled problem optimal - unscaled problem has primal infeasibilities
379 : 3 - scaled problem optimal - unscaled problem has dual infeasibilities
380 : 4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities
381 : 5 - giving up in primal with flagged variables
382 : 6 - failed due to empty problem check
383 : 7 - postSolve says not optimal
384 : 8 - failed due to bad element check
385 : 9 - status was 3 and stopped on time
386 : 100 up - translation of enum from ClpEventHandler
387 : */
388 : inline int secondaryStatus() const { return secondaryStatus_; }
389 : inline void setSecondaryStatus(int status)
390 : { secondaryStatus_ = status;}
391 : /// Are there a numerical difficulties?
392 : inline bool isAbandoned() const { return problemStatus_==4; }
393 : /// Is optimality proven?
394 : inline bool isProvenOptimal() const { return problemStatus_==0; }
395 : /// Is primal infeasiblity proven?
396 : inline bool isProvenPrimalInfeasible() const { return problemStatus_==1; }
397 : /// Is dual infeasiblity proven?
398 : inline bool isProvenDualInfeasible() const { return problemStatus_==2; }
399 : /// Is the given primal objective limit reached?
400 : bool isPrimalObjectiveLimitReached() const ;
401 : /// Is the given dual objective limit reached?
402 : bool isDualObjectiveLimitReached() const ;
403 : /// Iteration limit reached?
404 : inline bool isIterationLimitReached() const { return problemStatus_==3; }
405 : /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore
406 450066 : inline double optimizationDirection() const {
407 450066 : return optimizationDirection_;
408 : }
409 : inline double getObjSense() const { return optimizationDirection_; }
410 : void setOptimizationDirection(double value);
411 : /// Primal row solution
412 : inline double * primalRowSolution() const { return rowActivity_; }
413 : inline const double * getRowActivity() const { return rowActivity_; }
414 : /// Primal column solution
415 : inline double * primalColumnSolution() const { return columnActivity_; }
416 : inline const double * getColSolution() const { return columnActivity_; }
417 : inline void setColSolution(const double * input)
418 : { memcpy(columnActivity_,input,numberColumns_*sizeof(double));}
419 : /// Dual row solution
420 : inline double * dualRowSolution() const { return dual_; }
421 : inline const double * getRowPrice() const { return dual_; }
422 : /// Reduced costs
423 : inline double * dualColumnSolution() const { return reducedCost_; }
424 : inline const double * getReducedCost() const { return reducedCost_; }
425 : /// Row lower
426 696102 : inline double* rowLower() const { return rowLower_; }
427 : inline const double* getRowLower() const { return rowLower_; }
428 : /// Row upper
429 1971441 : inline double* rowUpper() const { return rowUpper_; }
430 : inline const double* getRowUpper() const { return rowUpper_; }
431 : //-------------------------------------------------------------------------
432 : /**@name Changing bounds on variables and constraints */
433 : //@{
434 : /** Set an objective function coefficient */
435 : void setObjectiveCoefficient( int elementIndex, double elementValue );
436 : /** Set an objective function coefficient */
437 : inline void setObjCoeff( int elementIndex, double elementValue )
438 : { setObjectiveCoefficient( elementIndex, elementValue);}
439 :
440 : /** Set a single column lower bound<br>
441 : Use -DBL_MAX for -infinity. */
442 : void setColumnLower( int elementIndex, double elementValue );
443 :
444 : /** Set a single column upper bound<br>
445 : Use DBL_MAX for infinity. */
446 : void setColumnUpper( int elementIndex, double elementValue );
447 :
448 : /** Set a single column lower and upper bound */
449 : void setColumnBounds( int elementIndex,
450 : double lower, double upper );
451 :
452 : /** Set the bounds on a number of columns simultaneously<br>
453 : The default implementation just invokes setColLower() and
454 : setColUpper() over and over again.
455 : @param indexFirst,indexLast pointers to the beginning and after the
456 : end of the array of the indices of the variables whose
457 : <em>either</em> bound changes
458 : @param boundList the new lower/upper bound pairs for the variables
459 : */
460 : void setColumnSetBounds(const int* indexFirst,
461 : const int* indexLast,
462 : const double* boundList);
463 :
464 : /** Set a single column lower bound<br>
465 : Use -DBL_MAX for -infinity. */
466 : inline void setColLower( int elementIndex, double elementValue )
467 : { setColumnLower(elementIndex, elementValue);}
468 : /** Set a single column upper bound<br>
469 : Use DBL_MAX for infinity. */
470 : inline void setColUpper( int elementIndex, double elementValue )
471 : { setColumnUpper(elementIndex, elementValue);}
472 :
473 : /** Set a single column lower and upper bound */
474 : inline void setColBounds( int elementIndex,
475 : double lower, double upper )
476 : { setColumnBounds(elementIndex, lower, upper);}
477 :
478 : /** Set the bounds on a number of columns simultaneously<br>
479 : @param indexFirst,indexLast pointers to the beginning and after the
480 : end of the array of the indices of the variables whose
481 : <em>either</em> bound changes
482 : @param boundList the new lower/upper bound pairs for the variables
483 : */
484 : inline void setColSetBounds(const int* indexFirst,
485 : const int* indexLast,
486 : const double* boundList)
487 : { setColumnSetBounds(indexFirst, indexLast, boundList);}
488 :
489 : /** Set a single row lower bound<br>
490 : Use -DBL_MAX for -infinity. */
491 : void setRowLower( int elementIndex, double elementValue );
492 :
493 : /** Set a single row upper bound<br>
494 : Use DBL_MAX for infinity. */
495 : void setRowUpper( int elementIndex, double elementValue ) ;
496 :
497 : /** Set a single row lower and upper bound */
498 : void setRowBounds( int elementIndex,
499 : double lower, double upper ) ;
500 :
501 : /** Set the bounds on a number of rows simultaneously<br>
502 : @param indexFirst,indexLast pointers to the beginning and after the
503 : end of the array of the indices of the constraints whose
504 : <em>either</em> bound changes
505 : @param boundList the new lower/upper bound pairs for the constraints
506 : */
507 : void setRowSetBounds(const int* indexFirst,
508 : const int* indexLast,
509 : const double* boundList);
510 :
511 : //@}
512 : /// Scaling
513 : inline const double * rowScale() const {return rowScale_;}
514 : inline const double * columnScale() const {return columnScale_;}
515 : inline void setRowScale(double * scale) { delete [] (double *) rowScale_; rowScale_ = scale;}
516 : inline void setColumnScale(double * scale) { delete [] (double *) columnScale_; columnScale_ = scale;}
517 : /// Scaling of objective
518 : inline double objectiveScale() const
519 : { return objectiveScale_;}
520 : inline void setObjectiveScale(double value)
521 : { objectiveScale_ = value;}
522 : /// Scaling of rhs and bounds
523 : inline double rhsScale() const
524 : { return rhsScale_;}
525 : inline void setRhsScale(double value)
526 : { rhsScale_ = value;}
527 : /// Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later)
528 : void scaling(int mode=1);
529 : /** If we constructed a "really" scaled model then this reverses the operation.
530 : Quantities may not be exactly as they were before due to rounding errors */
531 : void unscale();
532 : /// Gets scalingFlag
533 : inline int scalingFlag() const {return scalingFlag_;}
534 : /// Objective
535 2668794 : inline double * objective() const
536 : {
537 2668794 : if (objective_) {
538 : double offset;
539 2668794 : return objective_->gradient(NULL,NULL,offset,false);
540 : } else {
541 0 : return NULL;
542 : }
543 : }
544 : inline double * objective(const double * solution, double & offset,bool refresh=true) const
545 : {
546 : offset=0.0;
547 : if (objective_) {
548 : return objective_->gradient(NULL,solution,offset,refresh);
549 : } else {
550 : return NULL;
551 : }
552 : }
553 : inline const double * getObjCoefficients() const
554 : {
555 : if (objective_) {
556 : double offset;
557 : return objective_->gradient(NULL,NULL,offset,false);
558 : } else {
559 : return NULL;
560 : }
561 : }
562 : /// Row Objective
563 : inline double * rowObjective() const { return rowObjective_; }
564 : inline const double * getRowObjCoefficients() const {
565 : return rowObjective_;
566 : }
567 : /// Column Lower
568 509552 : inline double * columnLower() const { return columnLower_; }
569 : inline const double * getColLower() const { return columnLower_; }
570 : /// Column Upper
571 509161 : inline double * columnUpper() const { return columnUpper_; }
572 : inline const double * getColUpper() const { return columnUpper_; }
573 : /// Matrix (if not ClpPackedmatrix be careful about memory leak
574 1280480 : inline CoinPackedMatrix * matrix() const {
575 1280480 : if ( matrix_ == NULL ) return NULL;
576 1280480 : else return matrix_->getPackedMatrix();
577 : }
578 : /// Number of elements in matrix
579 : inline int getNumElements() const
580 : { return matrix_->getNumElements();}
581 : /** Small element value - elements less than this set to zero,
582 : default is 1.0e-20 */
583 : inline double getSmallElementValue() const
584 : { return smallElement_;}
585 : inline void setSmallElementValue(double value)
586 : { smallElement_=value;}
587 : /// Row Matrix
588 : inline ClpMatrixBase * rowCopy() const { return rowCopy_; }
589 : /// Clp Matrix
590 : inline ClpMatrixBase * clpMatrix() const { return matrix_; }
591 : /** Replace Clp Matrix (current is not deleted unless told to
592 : and new is used)
593 : So up to user to delete current. This was used where
594 : matrices were being rotated. ClpModel takes ownership.
595 : */
596 : void replaceMatrix(ClpMatrixBase * matrix,bool deleteCurrent=false);
597 : /** Replace Clp Matrix (current is not deleted unless told to
598 : and new is used) So up to user to delete current. This was used where
599 : matrices were being rotated. This version changes CoinPackedMatrix
600 : to ClpPackedMatrix. ClpModel takes ownership.
601 : */
602 : inline void replaceMatrix(CoinPackedMatrix * matrix,
603 : bool deleteCurrent=false)
604 : { replaceMatrix(new ClpPackedMatrix(matrix),deleteCurrent);}
605 : /// Objective value
606 : inline double objectiveValue() const {
607 : return objectiveValue_*optimizationDirection_ - dblParam_[ClpObjOffset];
608 : }
609 : inline void setObjectiveValue(double value) {
610 : objectiveValue_ = (value+ dblParam_[ClpObjOffset])/optimizationDirection_;
611 : }
612 : inline double getObjValue() const {
613 : return objectiveValue_*optimizationDirection_ - dblParam_[ClpObjOffset];
614 : }
615 : /// Integer information
616 : inline char * integerInformation() const { return integerType_; }
617 : /** Infeasibility/unbounded ray (NULL returned if none/wrong)
618 : Up to user to use delete [] on these arrays. */
619 : double * infeasibilityRay() const;
620 : double * unboundedRay() const;
621 : /// See if status (i.e. basis) array exists (partly for OsiClp)
622 1048963 : inline bool statusExists() const
623 1048963 : { return (status_!=NULL);}
624 : /// Return address of status (i.e. basis) array (char[numberRows+numberColumns])
625 : inline unsigned char * statusArray() const
626 : { return status_;}
627 : /** Return copy of status (i.e. basis) array (char[numberRows+numberColumns]),
628 : use delete [] */
629 : unsigned char * statusCopy() const;
630 : /// Copy in status (basis) vector
631 : void copyinStatus(const unsigned char * statusArray);
632 :
633 : /// User pointer for whatever reason
634 : inline void setUserPointer (void * pointer)
635 : { userPointer_=pointer;}
636 : inline void * getUserPointer () const
637 : { return userPointer_;}
638 : /// What has changed in model (only for masochistic users)
639 : inline int whatsChanged() const
640 : { return whatsChanged_;}
641 : inline void setWhatsChanged(int value)
642 : { whatsChanged_ = value;}
643 : /// Number of threads (not really being used)
644 : inline int numberThreads() const
645 : { return numberThreads_;}
646 : inline void setNumberThreads(int value)
647 : { numberThreads_ = value;}
648 : //@}
649 : /**@name Message handling */
650 : //@{
651 : /// Pass in Message handler (not deleted at end)
652 : void passInMessageHandler(CoinMessageHandler * handler);
653 : /// Pass in Message handler (not deleted at end) and return current
654 : CoinMessageHandler * pushMessageHandler(CoinMessageHandler * handler,
655 : bool & oldDefault);
656 : /// back to previous message handler
657 : void popMessageHandler(CoinMessageHandler * oldHandler,bool oldDefault);
658 : /// Set language
659 : void newLanguage(CoinMessages::Language language);
660 : inline void setLanguage(CoinMessages::Language language) { newLanguage(language); }
661 : /// Return handler
662 : inline CoinMessageHandler * messageHandler() const { return handler_; }
663 : /// Return messages
664 : inline CoinMessages messages() const { return messages_; }
665 : /// Return pointer to messages
666 : inline CoinMessages * messagesPointer() { return & messages_; }
667 : /// Return Coin messages
668 : inline CoinMessages coinMessages() const { return coinMessages_; }
669 : /// Return pointer to Coin messages
670 : inline CoinMessages * coinMessagesPointer() { return & coinMessages_; }
671 : /** Amount of print out:
672 : 0 - none
673 : 1 - just final
674 : 2 - just factorizations
675 : 3 - as 2 plus a bit more
676 : 4 - verbose
677 : above that 8,16,32 etc just for selective debug
678 : */
679 : inline void setLogLevel(int value) { handler_->setLogLevel(value); }
680 : inline int logLevel() const { return handler_->logLevel(); }
681 : /// Return true if default handler
682 : inline bool defaultHandler() const
683 : { return defaultHandler_;}
684 : /// Pass in Event handler (cloned and deleted at end)
685 : void passInEventHandler(const ClpEventHandler * eventHandler);
686 : /// Event handler
687 : inline ClpEventHandler * eventHandler() const
688 : { return eventHandler_;}
689 : /// length of names (0 means no names0
690 : inline int lengthNames() const { return lengthNames_; }
691 : #ifndef CLP_NO_STD
692 : /// length of names (0 means no names0
693 : inline void setLengthNames(int value) { lengthNames_=value; }
694 : /// Row names
695 : inline const std::vector<std::string> * rowNames() const {
696 : return &rowNames_;
697 : }
698 : inline const std::string& rowName(int iRow) const {
699 : return rowNames_[iRow];
700 : }
701 : /// Return name or Rnnnnnnn
702 : std::string getRowName(int iRow) const;
703 : /// Column names
704 : inline const std::vector<std::string> * columnNames() const {
705 : return &columnNames_;
706 : }
707 : inline const std::string& columnName(int iColumn) const {
708 : return columnNames_[iColumn];
709 : }
710 : /// Return name or Cnnnnnnn
711 : std::string getColumnName(int iColumn) const;
712 : #endif
713 : /// Objective methods
714 : inline ClpObjective * objectiveAsObject() const
715 : { return objective_;}
716 : void setObjective(ClpObjective * objective);
717 : inline void setObjectivePointer(ClpObjective * objective)
718 : { objective_ = objective;}
719 : /** Solve a problem with no elements - return status and
720 : dual and primal infeasibilites */
721 : int emptyProblem(int * infeasNumber=NULL, double * infeasSum=NULL,bool printMessage=true);
722 :
723 : //@}
724 :
725 : /**@name Matrix times vector methods
726 : They can be faster if scalar is +- 1
727 : These are covers so user need not worry about scaling
728 : Also for simplex I am not using basic/non-basic split */
729 : //@{
730 : /** Return <code>y + A * x * scalar</code> in <code>y</code>.
731 : @pre <code>x</code> must be of size <code>numColumns()</code>
732 : @pre <code>y</code> must be of size <code>numRows()</code> */
733 : void times(double scalar,
734 : const double * x, double * y) const;
735 : /** Return <code>y + x * scalar * A</code> in <code>y</code>.
736 : @pre <code>x</code> must be of size <code>numRows()</code>
737 : @pre <code>y</code> must be of size <code>numColumns()</code> */
738 : void transposeTimes(double scalar,
739 : const double * x, double * y) const ;
740 : //@}
741 :
742 :
743 : //---------------------------------------------------------------------------
744 : /**@name Parameter set/get methods
745 :
746 : The set methods return true if the parameter was set to the given value,
747 : false otherwise. There can be various reasons for failure: the given
748 : parameter is not applicable for the solver (e.g., refactorization
749 : frequency for the volume algorithm), the parameter is not yet implemented
750 : for the solver or simply the value of the parameter is out of the range
751 : the solver accepts. If a parameter setting call returns false check the
752 : details of your solver.
753 :
754 : The get methods return true if the given parameter is applicable for the
755 : solver and is implemented. In this case the value of the parameter is
756 : returned in the second argument. Otherwise they return false.
757 :
758 : ** once it has been decided where solver sits this may be redone
759 : */
760 : //@{
761 : /// Set an integer parameter
762 : bool setIntParam(ClpIntParam key, int value) ;
763 : /// Set an double parameter
764 : bool setDblParam(ClpDblParam key, double value) ;
765 : #ifndef CLP_NO_STD
766 : /// Set an string parameter
767 : bool setStrParam(ClpStrParam key, const std::string & value);
768 : #endif
769 : // Get an integer parameter
770 : inline bool getIntParam(ClpIntParam key, int& value) const {
771 : if (key<ClpLastIntParam) {
772 : value = intParam_[key];
773 : return true;
774 : } else {
775 : return false;
776 : }
777 : }
778 : // Get an double parameter
779 : inline bool getDblParam(ClpDblParam key, double& value) const {
780 : if (key<ClpLastDblParam) {
781 : value = dblParam_[key];
782 : return true;
783 : } else {
784 : return false;
785 : }
786 : }
787 : #ifndef CLP_NO_STD
788 : // Get a string parameter
789 : inline bool getStrParam(ClpStrParam key, std::string& value) const {
790 : if (key<ClpLastStrParam) {
791 : value = strParam_[key];
792 : return true;
793 : } else {
794 : return false;
795 : }
796 : }
797 : #endif
798 : /// Create C++ lines to get to current state
799 : void generateCpp( FILE * fp);
800 : /** For advanced options
801 : 1 - Don't keep changing infeasibility weight
802 : 2 - Keep nonLinearCost round solves
803 : 4 - Force outgoing variables to exact bound (primal)
804 : 8 - Safe to use dense initial factorization
805 : 16 -Just use basic variables for operation if column generation
806 : 32 -Clean up with primal before strong branching
807 : 64 -Treat problem as feasible until last minute (i.e. minimize infeasibilities)
808 : 128 - Switch off all matrix sanity checks
809 : 256 - No row copy
810 : 512 - If not in values pass, solution guaranteed, skip as much as possible
811 : 1024 - In branch and bound
812 : 2048 - Don't bother to re-factorize if < 20 iterations
813 : 4096 - Skip some optimality checks
814 : 8192 - Do Primal when cleaning up primal
815 : 16384 - In fast dual (so we can switch off things)
816 : 32678 - called from Osi
817 : 65356 - keep arrays around as much as possible
818 : 131072 - scale factor arrays have inverse values at end
819 : NOTE - many applications can call Clp but there may be some short cuts
820 : which are taken which are not guaranteed safe from all applications.
821 : Vetted applications will have a bit set and the code may test this
822 : At present I expect a few such applications - if too many I will
823 : have to re-think. It is up to application owner to change the code
824 : if she/he needs these short cuts. I will not debug unless in Coin
825 : repository. See COIN_CLP_VETTED comments.
826 : 0x01000000 is Cbc (and in branch and bound)
827 : 0x02000000 is in a different branch and bound
828 : */
829 : #define COIN_CBC_USING_CLP 0x01000000
830 : inline unsigned int specialOptions() const
831 : { return specialOptions_;}
832 : void setSpecialOptions(unsigned int value);
833 : //@}
834 :
835 : /**@name private or protected methods */
836 : //@{
837 : protected:
838 : /// Does most of deletion
839 : void gutsOfDelete();
840 : /** Does most of copying
841 : If trueCopy false then just points to arrays */
842 : void gutsOfCopy(const ClpModel & rhs, bool trueCopy=true);
843 : /// gets lower and upper bounds on rows
844 : void getRowBound(int iRow, double& lower, double& upper) const;
845 : /// puts in format I like - 4 array matrix - may make row copy
846 : void gutsOfLoadModel ( int numberRows, int numberColumns,
847 : const double* collb, const double* colub,
848 : const double* obj,
849 : const double* rowlb, const double* rowub,
850 : const double * rowObjective=NULL);
851 : /// Does much of scaling
852 : void gutsOfScaling();
853 : /// Objective value - always minimize
854 : inline double rawObjectiveValue() const {
855 : return objectiveValue_;
856 : }
857 : /// Create row names as char **
858 : const char * const * rowNamesAsChar() const;
859 : /// Create column names as char **
860 : const char * const * columnNamesAsChar() const;
861 : /// Delete char * version of names
862 : void deleteNamesAsChar(const char * const * names,int number) const;
863 : /// On stopped - sets secondary status
864 : void onStopped();
865 : //@}
866 :
867 :
868 : ////////////////// data //////////////////
869 : protected:
870 :
871 : /**@name data */
872 : //@{
873 : /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore
874 : double optimizationDirection_;
875 : /// Array of double parameters
876 : double dblParam_[ClpLastDblParam];
877 : /// Objective value
878 : double objectiveValue_;
879 : /// Small element value
880 : double smallElement_;
881 : /// Scaling of objective
882 : double objectiveScale_;
883 : /// Scaling of rhs and bounds
884 : double rhsScale_;
885 : /// Number of rows
886 : int numberRows_;
887 : /// Number of columns
888 : int numberColumns_;
889 : /// Row activities
890 : double * rowActivity_;
891 : /// Column activities
892 : double * columnActivity_;
893 : /// Duals
894 : double * dual_;
895 : /// Reduced costs
896 : double * reducedCost_;
897 : /// Row lower
898 : double* rowLower_;
899 : /// Row upper
900 : double* rowUpper_;
901 : /// Objective
902 : ClpObjective * objective_;
903 : /// Row Objective (? sign) - may be NULL
904 : double * rowObjective_;
905 : /// Column Lower
906 : double * columnLower_;
907 : /// Column Upper
908 : double * columnUpper_;
909 : /// Packed matrix
910 : ClpMatrixBase * matrix_;
911 : /// Row copy if wanted
912 : ClpMatrixBase * rowCopy_;
913 : /// Infeasible/unbounded ray
914 : double * ray_;
915 : /// Row scale factors for matrix
916 : double * rowScale_;
917 : /// Column scale factors
918 : double * columnScale_;
919 : /// Scale flag, 0 none, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic
920 : int scalingFlag_;
921 : /** Status (i.e. basis) Region. I know that not all algorithms need a status
922 : array, but it made sense for things like crossover and put
923 : all permanent stuff in one place. No assumption is made
924 : about what is in status array (although it might be good to reserve
925 : bottom 3 bits (i.e. 0-7 numeric) for classic status). This
926 : is number of columns + number of rows long (in that order).
927 : */
928 : unsigned char * status_;
929 : /// Integer information
930 : char * integerType_;
931 : /// User pointer for whatever reason
932 : void * userPointer_;
933 : /// Array of integer parameters
934 : int intParam_[ClpLastIntParam];
935 : /// Number of iterations
936 : int numberIterations_;
937 : /** Solve type - 1 simplex, 2 simplex interface, 3 Interior.*/
938 : int solveType_;
939 : /** Whats changed since last solve. This is a work in progress
940 : It is designed so careful people can make go faster.
941 : It is only used when startFinishOptions used in dual or primal.
942 : Bit 1 - number of rows/columns has not changed (so work arrays valid)
943 : 2 - matrix has not changed
944 : 4 - if matrix has changed only by adding rows
945 : 8 - if matrix has changed only by adding columns
946 : 16 - row lbs not changed
947 : 32 - row ubs not changed
948 : 64 - column objective not changed
949 : 128 - column lbs not changed
950 : 256 - column ubs not changed
951 : 512 - basis not changed (up to user to set this to 0)
952 : top bits may be used internally
953 : */
954 : unsigned int whatsChanged_;
955 : /// Status of problem
956 : int problemStatus_;
957 : /// Secondary status of problem
958 : int secondaryStatus_;
959 : /// length of names (0 means no names)
960 : int lengthNames_;
961 : /// Number of threads (not very operational)
962 : int numberThreads_;
963 : /** For advanced options
964 : See get and set for meaning
965 : */
966 : unsigned int specialOptions_;
967 : /// Message handler
968 : CoinMessageHandler * handler_;
969 : /// Flag to say if default handler (so delete)
970 : bool defaultHandler_;
971 : /// Event handler
972 : ClpEventHandler * eventHandler_;
973 : #ifndef CLP_NO_STD
974 : /// Row names
975 : std::vector<std::string> rowNames_;
976 : /// Column names
977 : std::vector<std::string> columnNames_;
978 : #endif
979 : /// Messages
980 : CoinMessages messages_;
981 : /// Coin messages
982 : CoinMessages coinMessages_;
983 : #ifndef CLP_NO_STD
984 : /// Array of string parameters
985 : std::string strParam_[ClpLastStrParam];
986 : #endif
987 : //@}
988 : };
989 : /** This is a tiny class where data can be saved round calls.
990 : */
991 : class ClpDataSave {
992 :
993 : public:
994 : /**@name Constructors and destructor
995 : */
996 : //@{
997 : /// Default constructor
998 : ClpDataSave ( );
999 :
1000 : /// Copy constructor.
1001 : ClpDataSave(const ClpDataSave &);
1002 : /// Assignment operator. This copies the data
1003 : ClpDataSave & operator=(const ClpDataSave & rhs);
1004 : /// Destructor
1005 : ~ClpDataSave ( );
1006 :
1007 : //@}
1008 :
1009 : ////////////////// data //////////////////
1010 : public:
1011 :
1012 : /**@name data - with same names as in other classes*/
1013 : //@{
1014 : double dualBound_;
1015 : double infeasibilityCost_;
1016 : double pivotTolerance_;
1017 : double acceptablePivot_;
1018 : double objectiveScale_;
1019 : int sparseThreshold_;
1020 : int perturbation_;
1021 : int forceFactorization_;
1022 : int scalingFlag_;
1023 : //@}
1024 : };
1025 :
1026 : #endif
|