source: trunk/include/ClpModel.hpp @ 348

Last change on this file since 348 was 348, checked in by forrest, 17 years ago

New status 5

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.1 KB
Line 
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 <iostream>
7#include <cassert>
8#include <cmath>
9#include <vector>
10#include <string>
11
12#include "ClpMatrixBase.hpp"
13#include "CoinMessageHandler.hpp"
14#include "ClpParameters.hpp"
15#include "ClpObjective.hpp"
16class ClpEventHandler;
17
18// Plus infinity
19#ifndef COIN_DBL_MAX
20#define COIN_DBL_MAX DBL_MAX
21#endif
22
23/** This is the base class for Linear and quadratic Models
24    This knows nothing about the algorithm, but it seems to
25    have a reasonable amount of information
26
27    I would welcome suggestions for what should be in this and
28    how it relates to OsiSolverInterface.  Some methods look
29    very similar.
30
31*/
32
33class ClpModel {
34
35public:
36
37  /**@name Constructors and destructor
38     Note - copy methods copy ALL data so can chew up memory
39     until other copy is freed
40   */
41  //@{
42    /// Default constructor
43    ClpModel (  );
44
45    /// Copy constructor.
46    ClpModel(const ClpModel &);
47    /// Assignment operator. This copies the data
48    ClpModel & operator=(const ClpModel & rhs);
49  /** Subproblem constructor.  A subset of whole model is created from the
50      row and column lists given.  The new order is given by list order and
51      duplicates are allowed.  Name and integer information can be dropped
52  */
53    ClpModel (const ClpModel * wholeModel,
54      int numberRows, const int * whichRows,
55      int numberColumns, const int * whichColumns,
56              bool dropNames=true, bool dropIntegers=true);
57    /// Destructor
58    ~ClpModel (  );
59  //@}
60
61  /**@name Load model - loads some stuff and initializes others */
62  //@{
63    /** Loads a problem (the constraints on the
64        rows are given by lower and upper bounds). If a pointer is 0 then the
65        following values are the default:
66        <ul>
67          <li> <code>colub</code>: all columns have upper bound infinity
68          <li> <code>collb</code>: all columns have lower bound 0
69          <li> <code>rowub</code>: all rows have upper bound infinity
70          <li> <code>rowlb</code>: all rows have lower bound -infinity
71          <li> <code>obj</code>: all variables have 0 objective coefficient
72        </ul>
73    */
74  void loadProblem (  const ClpMatrixBase& matrix,
75                     const double* collb, const double* colub,   
76                     const double* obj,
77                     const double* rowlb, const double* rowub,
78                      const double * rowObjective=NULL);
79  void loadProblem (  const CoinPackedMatrix& matrix,
80                     const double* collb, const double* colub,   
81                     const double* obj,
82                     const double* rowlb, const double* rowub,
83                      const double * rowObjective=NULL);
84
85  /** Just like the other loadProblem() method except that the matrix is
86        given in a standard column major ordered format (without gaps). */
87  void loadProblem (  const int numcols, const int numrows,
88                     const CoinBigIndex* start, const int* index,
89                     const double* value,
90                     const double* collb, const double* colub,   
91                     const double* obj,
92                      const double* rowlb, const double* rowub,
93                      const double * rowObjective=NULL);
94  /// This one is for after presolve to save memory
95  void loadProblem (  const int numcols, const int numrows,
96                     const CoinBigIndex* start, const int* index,
97                      const double* value,const int * length,
98                     const double* collb, const double* colub,   
99                     const double* obj,
100                      const double* rowlb, const double* rowub,
101                      const double * rowObjective=NULL);
102  /** Load up quadratic objective.  This is stored as a CoinPackedMatrix */
103  void loadQuadraticObjective(const int numberColumns, 
104                              const CoinBigIndex * start,
105                              const int * column, const double * element);
106  void loadQuadraticObjective (  const CoinPackedMatrix& matrix);
107  /// Get rid of quadratic objective
108  void deleteQuadraticObjective();
109  /// This just loads up a row objective
110  void setRowObjective(const double * rowObjective);
111  /// Read an mps file from the given filename
112  int readMps(const char *filename,
113              bool keepNames=false,
114              bool ignoreErrors = false);
115  /// Copy in integer informations
116  void copyInIntegerInformation(const char * information);
117  /// Drop integer informations
118  void deleteIntegerInformation();
119  /// Resizes rim part of model
120  void resize (int newNumberRows, int newNumberColumns);
121  /// Deletes rows
122  void deleteRows(int number, const int * which);
123  /// Add rows
124  void addRows(int number, const double * rowLower, 
125               const double * rowUpper,
126               const int * rowStarts, const int * columns,
127               const double * elements);
128  /// Add rows
129  void addRows(int number, const double * rowLower, 
130               const double * rowUpper,
131               const int * rowStarts, const int * rowLengths,
132               const int * columns,
133               const double * elements);
134  void addRows(int number, const double * rowLower, 
135               const double * rowUpper,
136               const CoinPackedVectorBase * const * rows);
137
138  /// Deletes columns
139  void deleteColumns(int number, const int * which);
140  /// Add columns
141  void addColumns(int number, const double * columnLower, 
142                  const double * columnUpper,
143                  const double * objective,
144                  const int * columnStarts, const int * rows,
145                  const double * elements);
146  void addColumns(int number, const double * columnLower, 
147                  const double * columnUpper,
148                  const double * objective,
149                  const int * columnStarts, const int * columnLengths,
150                  const int * rows,
151                  const double * elements);
152  void addColumns(int number, const double * columnLower, 
153               const double * columnUpper,
154                  const double * objective,
155               const CoinPackedVectorBase * const * columns);
156  /** Borrow model.  This is so we don't have to copy large amounts
157      of data around.  It assumes a derived class wants to overwrite
158      an empty model with a real one - while it does an algorithm */
159  void borrowModel(ClpModel & otherModel);
160  /** Return model - nulls all arrays so can be deleted safely
161      also updates any scalars */
162  void returnModel(ClpModel & otherModel);
163
164  /// Create empty ClpPackedMatrix
165  void createEmptyMatrix();
166  /// Drops names - makes lengthnames 0 and names empty
167  void dropNames();
168  /// Copies in names
169  void copyNames(std::vector<std::string> & rowNames,
170                 std::vector<std::string> & columnNames);
171 
172    /** Write the problem in MPS format to the specified file.
173
174        Row and column names may be null.
175        formatType is
176        <ul>
177          <li> 0 - normal
178          <li> 1 - extra accuracy
179          <li> 2 - IEEE hex (later)
180        </ul>
181
182        Returns non-zero on I/O error
183    */
184    int writeMps(const char *filename, 
185                  int formatType=0,int numberAcross=2,
186                 double objSense=0.0) const ;
187  //@}
188  /**@name gets and sets */
189  //@{
190   /// Number of rows
191   inline int numberRows() const {
192      return numberRows_;
193   }
194   inline int getNumRows() const {
195      return numberRows_;
196   }
197   /// Number of columns
198   inline int getNumCols() const {
199      return numberColumns_;
200   }
201   inline int numberColumns() const {
202      return numberColumns_;
203   }
204   /// Primal tolerance to use
205   inline double primalTolerance() const {
206      return dblParam_[ClpPrimalTolerance];
207   }
208   void setPrimalTolerance( double value) ;
209   /// Dual tolerance to use
210   inline double dualTolerance() const  { return dblParam_[ClpDualTolerance]; }
211   void setDualTolerance( double value) ;
212  /// Dual objective limit
213  inline double dualObjectiveLimit() const { return dblParam_[ClpDualObjectiveLimit];}
214  void setDualObjectiveLimit(double value);
215  /// Objective offset
216  inline double objectiveOffset() const { return dblParam_[ClpObjOffset];}
217  void setObjectiveOffset(double value);
218  inline std::string problemName() const { return strParam_[ClpProbName]; };
219   /// Number of iterations
220   inline int numberIterations() const  { return numberIterations_; }
221   inline int getIterationCount() const { return numberIterations_; }
222  inline void setNumberIterations(int numberIterations)
223  { numberIterations_ = numberIterations;};
224  /** Solve type - 1 simplex, 2 simplex interface, 3 Interior.*/
225  inline int solveType() const
226  { return solveType_;};
227  inline void setSolveType(int type)
228  { solveType_=type;};
229   /// Maximum number of iterations
230   inline int maximumIterations() const { return intParam_[ClpMaxNumIteration]; }
231   void setMaximumIterations(int value);
232  /// Maximum time in seconds (from when set called)
233   inline double maximumSeconds() const { return dblParam_[ClpMaxSeconds]; }
234   void setMaximumSeconds(double value);
235  /// Returns true if hit maximum iterations (or time)
236  bool hitMaximumIterations() const;
237   /** Status of problem:
238       0 - optimal
239       1 - primal infeasible
240       2 - dual infeasible
241       3 - stopped on iterations or time
242       4 - stopped due to errors
243       5 - stopped by event handler (virtual int ClpEventHandler::event())
244   */
245   inline int status() const            { return problemStatus_; }
246  /// Set problem status
247  inline void setProblemStatus(int problemStatus)
248  { problemStatus_ = problemStatus;};
249   /** Secondary status of problem - may get extended
250       0 - none
251       1 - primal infeasible because dual limit reached
252       2 - scaled problem optimal - unscaled problem has primal infeasibilities
253       3 - scaled problem optimal - unscaled problem has dual infeasibilities
254       4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities
255       100 up - translation of enum from ClpEventHandler
256   */
257   inline int secondaryStatus() const            { return secondaryStatus_; }
258  inline void setSecondaryStatus(int status)
259  { secondaryStatus_ = status;};
260   /// Are there a numerical difficulties?
261   bool isAbandoned() const             { return problemStatus_==4; }
262   /// Is optimality proven?
263   bool isProvenOptimal() const         { return problemStatus_==0; }
264   /// Is primal infeasiblity proven?
265   bool isProvenPrimalInfeasible() const { return problemStatus_==1; }
266   /// Is dual infeasiblity proven?
267   bool isProvenDualInfeasible() const  { return problemStatus_==2; }
268   /// Is the given primal objective limit reached?
269   bool isPrimalObjectiveLimitReached() const ;
270   /// Is the given dual objective limit reached?
271   bool isDualObjectiveLimitReached() const ;
272   /// Iteration limit reached?
273   bool isIterationLimitReached() const { return problemStatus_==3; }
274   /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore
275   inline double optimizationDirection() const {
276      return  optimizationDirection_;
277   }
278   inline double getObjSense() const    { return optimizationDirection_; }
279   void setOptimizationDirection(double value);
280   /// Primal row solution
281   inline double * primalRowSolution() const    { return rowActivity_; }
282   inline const double * getRowActivity() const { return rowActivity_; }
283   /// Primal column solution
284   inline double * primalColumnSolution() const { return columnActivity_; }
285   inline const double * getColSolution() const { return columnActivity_; }
286   inline void setColSolution(const double * input)
287   { memcpy(columnActivity_,input,numberColumns_*sizeof(double));};
288   /// Dual row solution
289   inline double * dualRowSolution() const      { return dual_; }
290   inline const double * getRowPrice() const    { return dual_; }
291   /// Reduced costs
292   inline double * dualColumnSolution() const   { return reducedCost_; }
293   inline const double * getReducedCost() const { return reducedCost_; }
294   /// Row lower
295   inline double* rowLower() const              { return rowLower_; }
296   inline const double* getRowLower() const     { return rowLower_; }
297   /// Row upper
298   inline double* rowUpper() const              { return rowUpper_; }
299   inline const double* getRowUpper() const     { return rowUpper_; }
300   /// Objective
301   inline double * objective() const           
302  {
303    if (objective_) {
304      double offset; 
305      return objective_->gradient(NULL,offset,false);
306    } else {
307      return NULL;
308    }
309  }
310   inline double * objective(const double * solution, double & offset,bool refresh=true) const           
311  {
312    offset=0.0;
313    if (objective_) {
314      return objective_->gradient(solution,offset,refresh);
315    } else {
316      return NULL;
317    }
318  }
319   inline const double * getObjCoefficients() const 
320  { 
321    if (objective_) {
322      double offset; 
323      return objective_->gradient(NULL,offset,false);
324    } else {
325      return NULL;
326    }
327  }
328   /// Row Objective
329   inline double * rowObjective() const         { return rowObjective_; }
330   inline const double * getRowObjCoefficients() const {
331      return rowObjective_;
332   }
333   /// Column Lower
334   inline double * columnLower() const          { return columnLower_; }
335   inline const double * getColLower() const    { return columnLower_; }
336   /// Column Upper
337   inline double * columnUpper() const          { return columnUpper_; }
338   inline const double * getColUpper() const    { return columnUpper_; }
339   /// Matrix (if not ClpPackedmatrix be careful about memory leak
340   inline CoinPackedMatrix * matrix() const {
341     if ( matrix_ == NULL ) return NULL;
342     else return matrix_->getPackedMatrix();
343   }
344   /// Number of elements in matrix
345   inline int getNumElements() const 
346     { return matrix_->getNumElements();};
347   /** Small element value - elements less than this set to zero,
348      default is 1.0e-20 */
349   inline double getSmallElementValue() const
350  { return smallElement_;}; 
351  inline void setSmallElementValue(double value)
352  { smallElement_=value;}; 
353   /// Row Matrix
354   inline ClpMatrixBase * rowCopy() const       { return rowCopy_; }
355   /// Clp Matrix
356   inline ClpMatrixBase * clpMatrix() const     { return matrix_; }
357  /** Replace Clp Matrix (current is not deleted and new is used)
358      So up to user to delete one
359  */
360   void replaceMatrix(ClpMatrixBase * matrix);
361   /// Objective value
362   inline double objectiveValue() const {
363      return objectiveValue_*optimizationDirection_ - dblParam_[ClpObjOffset];
364   }
365   inline double getObjValue() const {
366      return objectiveValue_*optimizationDirection_ - dblParam_[ClpObjOffset];
367   }
368   /// Integer information
369   inline char * integerInformation() const     { return integerType_; }
370   /** Infeasibility/unbounded ray (NULL returned if none/wrong)
371       Up to user to use delete [] on these arrays.  */
372   double * infeasibilityRay() const;
373   double * unboundedRay() const;
374  /// See if status array exists (partly for OsiClp)
375  inline bool statusExists() const
376  { return (status_!=NULL);};
377  /// Return address of status array (char[numberRows+numberColumns])
378  inline unsigned char *  statusArray() const
379  { return status_;};
380  /** Return copy of status array (char[numberRows+numberColumns]),
381      use delete [] */
382  unsigned char *  statusCopy() const;
383  /// Copy in status vector
384  void copyinStatus(const unsigned char * statusArray);
385
386  /// User pointer for whatever reason
387  inline void setUserPointer (void * pointer)
388  { userPointer_=pointer;};
389  inline void * getUserPointer () const
390  { return userPointer_;};
391  //@}
392  /**@name Message handling */
393  //@{
394   /// Pass in Message handler (not deleted at end)
395   void passInMessageHandler(CoinMessageHandler * handler);
396   /// Set language
397   void newLanguage(CoinMessages::Language language);
398   void setLanguage(CoinMessages::Language language) { newLanguage(language); }
399   /// Return handler
400   CoinMessageHandler * messageHandler() const       { return handler_; }
401   /// Return messages
402   CoinMessages messages() const                     { return messages_; }
403   /// Return pointer to messages
404   CoinMessages * messagesPointer()                  { return & messages_; }
405  /** Amount of print out:
406      0 - none
407      1 - just final
408      2 - just factorizations
409      3 - as 2 plus a bit more
410      4 - verbose
411      above that 8,16,32 etc just for selective debug
412  */
413   void setLogLevel(int value)    { handler_->setLogLevel(value); }
414   int logLevel() const           { return handler_->logLevel(); }
415   /// Pass in Event handler (cloned and deleted at end)
416   void passInEventHandler(const ClpEventHandler * eventHandler);
417   /// length of names (0 means no names0
418   inline int lengthNames() const { return lengthNames_; }
419   /// Row names
420   const std::vector<std::string> * rowNames() const {
421      return &rowNames_;
422   }
423   const std::string& rowName(int iRow) const {
424      return rowNames_[iRow];
425   }
426   /// Column names
427   const std::vector<std::string> * columnNames() const {
428      return &columnNames_;
429   }
430   const std::string& columnName(int iColumn) const {
431      return columnNames_[iColumn];
432   }
433  /// Objective methods
434  inline ClpObjective * objectiveAsObject() const
435  { return objective_;};
436  void setObjective(ClpObjective * objective);
437  void setObjectivePointer(ClpObjective * objective)
438  { objective_ = objective;};
439  /** Solve a problem with no elements - return status and
440      dual and primal infeasibilites */
441  int emptyProblem(int * infeasNumber=NULL, double * infeasSum=NULL,bool printMessage=true);
442 
443  //@}
444
445
446  //---------------------------------------------------------------------------
447  /**@name Parameter set/get methods
448
449     The set methods return true if the parameter was set to the given value,
450     false otherwise. There can be various reasons for failure: the given
451     parameter is not applicable for the solver (e.g., refactorization
452     frequency for the volume algorithm), the parameter is not yet implemented
453     for the solver or simply the value of the parameter is out of the range
454     the solver accepts. If a parameter setting call returns false check the
455     details of your solver.
456
457     The get methods return true if the given parameter is applicable for the
458     solver and is implemented. In this case the value of the parameter is
459     returned in the second argument. Otherwise they return false.
460
461     ** once it has been decided where solver sits this may be redone
462  */
463  //@{
464    /// Set an integer parameter
465    bool setIntParam(ClpIntParam key, int value) ;
466    /// Set an double parameter
467    bool setDblParam(ClpDblParam key, double value) ;
468    /// Set an string parameter
469    bool setStrParam(ClpStrParam key, const std::string & value);
470    // Get an integer parameter
471    inline bool getIntParam(ClpIntParam key, int& value) const {
472      if (key!=ClpLastIntParam) {
473        value = intParam_[key];
474        return true;
475      } else {
476        return false;
477      }
478    }
479    // Get an double parameter
480    inline bool getDblParam(ClpDblParam key, double& value) const {
481      if (key!=ClpLastDblParam) {
482        value = dblParam_[key];
483        return true;
484      } else {
485        return false;
486      }
487    }
488    // Get a string parameter
489    inline bool getStrParam(ClpStrParam key, std::string& value) const {
490      if (key!=ClpLastStrParam) {
491        value = strParam_[key];
492        return true;
493      } else {
494        return false;
495      }
496    }
497  //@}
498
499  /**@name private or protected methods */
500  //@{
501protected:
502  /// Does most of deletion
503  void gutsOfDelete();
504  /** Does most of copying
505      If trueCopy false then just points to arrays */
506  void gutsOfCopy(const ClpModel & rhs, bool trueCopy=true);
507  /// gets lower and upper bounds on rows
508  void getRowBound(int iRow, double& lower, double& upper) const;
509  /// puts in format I like - 4 array matrix - may make row copy
510  void gutsOfLoadModel ( int numberRows, int numberColumns,
511                     const double* collb, const double* colub,   
512                     const double* obj,
513                     const double* rowlb, const double* rowub,
514                      const double * rowObjective=NULL);
515  //@}
516
517
518////////////////// data //////////////////
519protected:
520
521  /**@name data */
522  //@{
523  /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore
524  double optimizationDirection_;
525  /// Array of double parameters
526  double dblParam_[ClpLastDblParam];
527  /// Objective value
528  double objectiveValue_;
529  /// Small element value
530  double smallElement_;
531  /// Number of rows
532  int numberRows_;
533  /// Number of columns
534  int numberColumns_;
535  /// Row activities
536  double * rowActivity_;
537  /// Column activities
538  double * columnActivity_;
539  /// Duals
540  double * dual_;
541  /// Reduced costs
542  double * reducedCost_;
543  /// Row lower
544  double* rowLower_;
545  /// Row upper
546  double* rowUpper_;
547  /// Objective
548  ClpObjective * objective_;
549  /// Row Objective (? sign)  - may be NULL
550  double * rowObjective_;
551  /// Column Lower
552  double * columnLower_;
553  /// Column Upper
554  double * columnUpper_;
555  /// Packed matrix
556  ClpMatrixBase * matrix_;
557  /// Row copy if wanted
558  ClpMatrixBase * rowCopy_;
559  /// Infeasible/unbounded ray
560  double * ray_;
561  /** Status Region.  I know that not all algorithms need a status
562      array, but it made sense for things like crossover and put
563      all permanent stuff in one place.  No assumption is made
564      about what is in status array (although it might be good to reserve
565      bottom 3 bits (i.e. 0-7 numeric) for classic status).  This
566      is number of columns + number of rows long (in that order).
567  */
568  unsigned char * status_;
569  /// Integer information
570  char * integerType_;
571  /// User pointer for whatever reason
572  void * userPointer_;
573  /// Array of integer parameters
574  int intParam_[ClpLastIntParam];
575  /// Number of iterations
576  int numberIterations_;
577  /** Solve type - 1 simplex, 2 simplex interface, 3 Interior.*/
578  int solveType_;
579  /// Status of problem
580  int problemStatus_;
581  /// Secondary status of problem
582  int secondaryStatus_;
583  /// length of names (0 means no names)
584  int lengthNames_;
585  /// Message handler
586  CoinMessageHandler * handler_;
587  /// Flag to say if default handler (so delete)
588  bool defaultHandler_;
589  /// Event handler
590  ClpEventHandler * eventHandler_;
591  /// Row names
592  std::vector<std::string> rowNames_;
593  /// Column names
594  std::vector<std::string> columnNames_;
595  /// Messages
596  CoinMessages messages_;
597  /// Array of string parameters
598  std::string strParam_[ClpLastStrParam];
599  //@}
600};
601/** This is a tiny class where data can be saved round calls */
602class ClpDataSave {
603
604public:
605  /**@name Constructors and destructor
606   */
607  //@{
608    /// Default constructor
609    ClpDataSave (  );
610
611    /// Copy constructor.
612    ClpDataSave(const ClpDataSave &);
613    /// Assignment operator. This copies the data
614    ClpDataSave & operator=(const ClpDataSave & rhs);
615    /// Destructor
616    ~ClpDataSave (  );
617
618  //@}
619
620////////////////// data //////////////////
621public:
622
623  /**@name data - with same names as in other classes*/
624  //@{
625  double dualBound_;
626  double infeasibilityCost_;
627  int sparseThreshold_;
628  int perturbation_;
629
630  //@}
631};
632
633#endif
Note: See TracBrowser for help on using the repository browser.