source: trunk/Clp/src/ClpModel.hpp @ 2470

Last change on this file since 2470 was 2385, checked in by unxusr, 11 months ago

formatting

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