1 // $Id$
2 // Copyright (C) 2000, 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 OsiCbcSolverInterface_H
7 #define OsiCbcSolverInterface_H
8 
9 #include <string>
10 #include <cfloat>
11 #include <map>
12 #include "CbcModel.hpp"
13 #include "CoinPackedMatrix.hpp"
14 #include "OsiSolverInterface.hpp"
15 #include "CbcStrategy.hpp"
16 #include "CoinWarmStartBasis.hpp"
17 
18 class OsiRowCut;
19 class OsiClpSolverInterface;
20 static const double OsiCbcInfinity = COIN_DBL_MAX;
21 
22 //#############################################################################
23 
24 /** Cbc Solver Interface
25 
26 Instantiation of OsiCbcSolverInterface for the Model Algorithm.
27 
28 */
29 
30 class OsiCbcSolverInterface : virtual public OsiSolverInterface {
31   friend void OsiCbcSolverInterfaceUnitTest(const std::string &mpsDir, const std::string &netlibDir);
32 
33 public:
34   //---------------------------------------------------------------------------
35   /**@name Solve methods */
36   //@{
37   /// Solve initial LP relaxation
38   virtual void initialSolve();
39 
40   /// Resolve an LP relaxation after problem modification
41   virtual void resolve();
42 
43   /// Invoke solver's built-in enumeration algorithm
44   virtual void branchAndBound();
45   //@}
46 
47   //---------------------------------------------------------------------------
48   /**@name Parameter set/get methods
49 
50   The set methods return true if the parameter was set to the given value,
51   false otherwise. There can be various reasons for failure: the given
52   parameter is not applicable for the solver (e.g., refactorization
53   frequency for the cbc algorithm), the parameter is not yet implemented
54   for the solver or simply the value of the parameter is out of the range
55   the solver accepts. If a parameter setting call returns false check the
56   details of your solver.
57 
58   The get methods return true if the given parameter is applicable for the
59   solver and is implemented. In this case the value of the parameter is
60   returned in the second argument. Otherwise they return false.
61   */
62   //@{
63   // Set an integer parameter
64   bool setIntParam(OsiIntParam key, int value);
65   // Set an double parameter
66   bool setDblParam(OsiDblParam key, double value);
67   // Set a string parameter
68   bool setStrParam(OsiStrParam key, const std::string &value);
69   // Get an integer parameter
70   bool getIntParam(OsiIntParam key, int &value) const;
71   // Get an double parameter
72   bool getDblParam(OsiDblParam key, double &value) const;
73   // Get a string parameter
74   bool getStrParam(OsiStrParam key, std::string &value) const;
75   // Set a hint parameter - overrides OsiSolverInterface
76   virtual bool setHintParam(OsiHintParam key, bool yesNo = true,
77     OsiHintStrength strength = OsiHintTry,
78     void *otherInformation = NULL);
79   /// Get a hint parameter
80   virtual bool getHintParam(OsiHintParam key, bool &yesNo,
81     OsiHintStrength &strength,
82     void *&otherInformation) const;
83 
84   using OsiSolverInterface::getHintParam;
85   /// Get a hint parameter
86   virtual bool getHintParam(OsiHintParam key, bool &yesNo,
87     OsiHintStrength &strength) const;
88   //@}
89 
90   //---------------------------------------------------------------------------
91   ///@name Methods returning info on how the solution process terminated
92   //@{
93   /// Are there a numerical difficulties?
94   virtual bool isAbandoned() const;
95   /// Is optimality proven?
96   virtual bool isProvenOptimal() const;
97   /// Is primal infeasiblity proven?
98   virtual bool isProvenPrimalInfeasible() const;
99   /// Is dual infeasiblity proven?
100   virtual bool isProvenDualInfeasible() const;
101   /// Is the given primal objective limit reached?
102   virtual bool isPrimalObjectiveLimitReached() const;
103   /// Is the given dual objective limit reached?
104   virtual bool isDualObjectiveLimitReached() const;
105   /// Iteration limit reached?
106   virtual bool isIterationLimitReached() const;
107   //@}
108 
109   //---------------------------------------------------------------------------
110   /**@name WarmStart related methods */
111   //@{
112 
113   /*! \brief Get an empty warm start object
114 
115   This routine returns an empty CoinWarmStartBasis object. Its purpose is
116   to provide a way to give a client a warm start basis object of the
117   appropriate type, which can resized and modified as desired.
118   */
119 
120   virtual CoinWarmStart *getEmptyWarmStart() const;
121 
122   /// Get warmstarting information
123   virtual CoinWarmStart *getWarmStart() const;
124   /** Set warmstarting information. Return true/false depending on whether
125       the warmstart information was accepted or not. */
126   virtual bool setWarmStart(const CoinWarmStart *warmstart);
127   //@}
128 
129   //---------------------------------------------------------------------------
130   /**@name Hotstart related methods (primarily used in strong branching). <br>
131      The user can create a hotstart (a snapshot) of the optimization process
132      then reoptimize over and over again always starting from there.<br>
133      <strong>NOTE</strong>: between hotstarted optimizations only
134      bound changes are allowed. */
135   //@{
136   /// Create a hotstart point of the optimization process
137   virtual void markHotStart();
138   /// Optimize starting from the hotstart
139   virtual void solveFromHotStart();
140   /// Delete the snapshot
141   virtual void unmarkHotStart();
142   //@}
143 
144   //---------------------------------------------------------------------------
145   /**@name Problem information methods
146 
147   These methods call the solver's query routines to return
148   information about the problem referred to by the current object.
149   Querying a problem that has no data associated with it result in
150   zeros for the number of rows and columns, and NULL pointers from
151   the methods that return vectors.
152 
153   Const pointers returned from any data-query method are valid as
154   long as the data is unchanged and the solver is not called.
155   */
156   //@{
157   /**@name Methods related to querying the input data */
158   //@{
159   /// Get number of columns
160   virtual int getNumCols() const;
161 
162   /// Get number of rows
163   virtual int getNumRows() const;
164 
165   /// Get number of nonzero elements
166   virtual CoinBigIndex getNumElements() const;
167 
168   /// Get pointer to array[getNumCols()] of column lower bounds
169   virtual const double *getColLower() const;
170 
171   /// Get pointer to array[getNumCols()] of column upper bounds
172   virtual const double *getColUpper() const;
173 
174   /** Get pointer to array[getNumRows()] of row constraint senses.
175       <ul>
176       <li>'L' <= constraint
177       <li>'E' =  constraint
178       <li>'G' >= constraint
179       <li>'R' ranged constraint
180       <li>'N' free constraint
181       </ul>
182   */
183   virtual const char *getRowSense() const;
184 
185   /** Get pointer to array[getNumRows()] of rows right-hand sides
186       <ul>
187       <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i]
188       <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i]
189       <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i]
190       <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0
191       </ul>
192   */
193   virtual const double *getRightHandSide() const;
194 
195   /** Get pointer to array[getNumRows()] of row ranges.
196       <ul>
197       <li> if rowsense()[i] == 'R' then
198       rowrange()[i] == rowupper()[i] - rowlower()[i]
199       <li> if rowsense()[i] != 'R' then
200       rowrange()[i] is undefined
201       </ul>
202   */
203   virtual const double *getRowRange() const;
204 
205   /// Get pointer to array[getNumRows()] of row lower bounds
206   virtual const double *getRowLower() const;
207 
208   /// Get pointer to array[getNumRows()] of row upper bounds
209   virtual const double *getRowUpper() const;
210 
211   /// Get pointer to array[getNumCols()] of objective function coefficients
212   virtual const double *getObjCoefficients() const;
213 
214   /// Get objective function sense (1 for min (default), -1 for max)
215   virtual double getObjSense() const;
216 
217   /// Return true if column is continuous
218   virtual bool isContinuous(int colNumber) const;
219 
220   /// Get pointer to row-wise copy of matrix
221   virtual const CoinPackedMatrix *getMatrixByRow() const;
222 
223   /// Get pointer to column-wise copy of matrix
224   virtual const CoinPackedMatrix *getMatrixByCol() const;
225 
226   /// Get solver's value for infinity
227   virtual double getInfinity() const;
228   //@}
229 
230   /**@name Methods related to querying the solution */
231   //@{
232   /// Get pointer to array[getNumCols()] of primal solution vector
233   virtual const double *getColSolution() const;
234 
235   /// Get pointer to array[getNumRows()] of dual prices
236   virtual const double *getRowPrice() const;
237 
238   /// Get a pointer to array[getNumCols()] of reduced costs
239   virtual const double *getReducedCost() const;
240 
241   /** Get pointer to array[getNumRows()] of row activity levels (constraint
242       matrix times the solution vector */
243   virtual const double *getRowActivity() const;
244 
245   /// Get objective function value
246   virtual double getObjValue() const;
247 
248   /** Get how many iterations it took to solve the problem (whatever
249       "iteration" mean to the solver. */
250   virtual int getIterationCount() const;
251 
252   /** Get as many dual rays as the solver can provide. (In case of proven
253       primal infeasibility there should be at least one.)
254 
255       The first getNumRows() ray components will always be associated with
256       the row duals (as returned by getRowPrice()). If \c fullRay is true,
257       the final getNumCols() entries will correspond to the ray components
258       associated with the nonbasic variables. If the full ray is requested
259       and the method cannot provide it, it will throw an exception.
260 
261       <strong>NOTE for implementers of solver interfaces:</strong> <br>
262       The double pointers in the vector should point to arrays of length
263       getNumRows() and they should be allocated via new[]. <br>
264 
265       <strong>NOTE for users of solver interfaces:</strong> <br>
266       It is the user's responsibility to free the double pointers in the
267       vector using delete[].
268   */
269   virtual std::vector< double * > getDualRays(int maxNumRays,
270     bool fullRay = false) const;
271   /** Get as many primal rays as the solver can provide. (In case of proven
272       dual infeasibility there should be at least one.)
273 
274       <strong>NOTE for implementers of solver interfaces:</strong> <br>
275       The double pointers in the vector should point to arrays of length
276       getNumCols() and they should be allocated via new[]. <br>
277 
278       <strong>NOTE for users of solver interfaces:</strong> <br>
279       It is the user's responsibility to free the double pointers in the
280       vector using delete[].
281   */
282   virtual std::vector< double * > getPrimalRays(int maxNumRays) const;
283 
284   //@}
285 
286   /*! \name Methods for row and column names.
287 
288     Because OsiCbc is a pass-through class, it's necessary to override any
289     virtual method in order to be sure we catch an override by the underlying
290     solver. See the OsiSolverInterface class documentation for detailed
291     descriptions.
292   */
293   //@{
294 
295   /*! \brief Generate a standard name of the form Rnnnnnnn or Cnnnnnnn */
296 
297   virtual std::string dfltRowColName(char rc,
298     int ndx, unsigned digits = 7) const;
299 
300   /*! \brief Return the name of the objective function */
301 
302   virtual std::string getObjName(std::string::size_type maxLen = std::string::npos) const;
303 
304   /*! \brief Set the name of the objective function */
305 
306   virtual void setObjName(std::string name);
307 
308   /*! \brief Return the name of the row.  */
309 
310   virtual std::string getRowName(int rowIndex,
311     std::string::size_type maxLen = std::string::npos) const;
312 
313   /*! \brief Return a pointer to a vector of row names */
314 
315   virtual const OsiNameVec &getRowNames();
316 
317   /*! \brief Set a row name */
318 
319   virtual void setRowName(int ndx, std::string name);
320 
321   /*! \brief Set multiple row names */
322 
323   virtual void setRowNames(OsiNameVec &srcNames,
324     int srcStart, int len, int tgtStart);
325 
326   /*! \brief Delete len row names starting at index tgtStart */
327 
328   virtual void deleteRowNames(int tgtStart, int len);
329 
330   /*! \brief Return the name of the column */
331 
332   virtual std::string getColName(int colIndex,
333     std::string::size_type maxLen = std::string::npos) const;
334 
335   /*! \brief Return a pointer to a vector of column names */
336 
337   virtual const OsiNameVec &getColNames();
338 
339   /*! \brief Set a column name */
340 
341   virtual void setColName(int ndx, std::string name);
342 
343   /*! \brief Set multiple column names */
344 
345   virtual void setColNames(OsiNameVec &srcNames,
346     int srcStart, int len, int tgtStart);
347 
348   /*! \brief Delete len column names starting at index tgtStart */
349   virtual void deleteColNames(int tgtStart, int len);
350 
351   //@}
352 
353   //@}
354 
355   //---------------------------------------------------------------------------
356 
357   /**@name Problem modifying methods */
358   //@{
359   //-------------------------------------------------------------------------
360   /**@name Changing bounds on variables and constraints */
361   //@{
362   /** Set an objective function coefficient */
363   virtual void setObjCoeff(int elementIndex, double elementValue);
364 
365   using OsiSolverInterface::setColLower;
366   /** Set a single column lower bound<br>
367       Use -DBL_MAX for -infinity. */
368   virtual void setColLower(int elementIndex, double elementValue);
369 
370   using OsiSolverInterface::setColUpper;
371   /** Set a single column upper bound<br>
372       Use DBL_MAX for infinity. */
373   virtual void setColUpper(int elementIndex, double elementValue);
374 
375   /** Set a single column lower and upper bound */
376   virtual void setColBounds(int elementIndex,
377     double lower, double upper);
378 
379   /** Set the bounds on a number of columns simultaneously<br>
380       The default implementation just invokes setColLower() and
381       setColUpper() over and over again.
382       @param indexFirst,indexLast pointers to the beginning and after the
383       end of the array of the indices of the variables whose
384       <em>either</em> bound changes
385       @param boundList the new lower/upper bound pairs for the variables
386   */
387   virtual void setColSetBounds(const int *indexFirst,
388     const int *indexLast,
389     const double *boundList);
390 
391   /** Set a single row lower bound<br>
392       Use -DBL_MAX for -infinity. */
393   virtual void setRowLower(int elementIndex, double elementValue);
394 
395   /** Set a single row upper bound<br>
396       Use DBL_MAX for infinity. */
397   virtual void setRowUpper(int elementIndex, double elementValue);
398 
399   /** Set a single row lower and upper bound */
400   virtual void setRowBounds(int elementIndex,
401     double lower, double upper);
402 
403   /** Set the type of a single row<br> */
404   virtual void setRowType(int index, char sense, double rightHandSide,
405     double range);
406 
407   /** Set the bounds on a number of rows simultaneously<br>
408       The default implementation just invokes setRowLower() and
409       setRowUpper() over and over again.
410       @param indexFirst,indexLast pointers to the beginning and after the
411       end of the array of the indices of the constraints whose
412       <em>either</em> bound changes
413       @param boundList the new lower/upper bound pairs for the constraints
414   */
415   virtual void setRowSetBounds(const int *indexFirst,
416     const int *indexLast,
417     const double *boundList);
418 
419   /** Set the type of a number of rows simultaneously<br>
420       The default implementation just invokes setRowType()
421       over and over again.
422       @param indexFirst,indexLast pointers to the beginning and after the
423       end of the array of the indices of the constraints whose
424       <em>any</em> characteristics changes
425       @param senseList the new senses
426       @param rhsList   the new right hand sides
427       @param rangeList the new ranges
428   */
429   virtual void setRowSetTypes(const int *indexFirst,
430     const int *indexLast,
431     const char *senseList,
432     const double *rhsList,
433     const double *rangeList);
434   //@}
435 
436   //-------------------------------------------------------------------------
437   /**@name Integrality related changing methods */
438   //@{
439   /** Set the index-th variable to be a continuous variable */
440   virtual void setContinuous(int index);
441   /** Set the index-th variable to be an integer variable */
442   virtual void setInteger(int index);
443   /** Set the variables listed in indices (which is of length len) to be
444       continuous variables */
445   virtual void setContinuous(const int *indices, int len);
446   /** Set the variables listed in indices (which is of length len) to be
447       integer variables */
448   virtual void setInteger(const int *indices, int len);
449   //@}
450 
451   //-------------------------------------------------------------------------
452   /// Set objective function sense (1 for min (default), -1 for max,)
453   virtual void setObjSense(double s);
454 
455   /** Set the primal solution column values
456 
457   colsol[numcols()] is an array of values of the problem column
458   variables. These values are copied to memory owned by the
459   solver object or the solver.  They will be returned as the
460   result of colsol() until changed by another call to
461   setColsol() or by a call to any solver routine.  Whether the
462   solver makes use of the solution in any way is
463   solver-dependent.
464   */
465   virtual void setColSolution(const double *colsol);
466 
467   /** Set dual solution vector
468 
469   rowprice[numrows()] is an array of values of the problem row
470   dual variables. These values are copied to memory owned by the
471   solver object or the solver.  They will be returned as the
472   result of rowprice() until changed by another call to
473   setRowprice() or by a call to any solver routine.  Whether the
474   solver makes use of the solution in any way is
475   solver-dependent.
476   */
477   virtual void setRowPrice(const double *rowprice);
478 
479   //-------------------------------------------------------------------------
480   /**@name Methods to expand a problem.<br>
481      Note that if a column is added then by default it will correspond to a
482      continuous variable. */
483   //@{
484   using OsiSolverInterface::addCol;
485   /** */
486   virtual void addCol(const CoinPackedVectorBase &vec,
487     const double collb, const double colub,
488     const double obj);
489   /** Add a column (primal variable) to the problem. */
490   virtual void addCol(int numberElements, const int *rows, const double *elements,
491     const double collb, const double colub,
492     const double obj);
493 
494   using OsiSolverInterface::addCols;
495   /** */
496   virtual void addCols(const int numcols,
497     const CoinPackedVectorBase *const *cols,
498     const double *collb, const double *colub,
499     const double *obj);
500   /** */
501   virtual void deleteCols(const int num, const int *colIndices);
502 
503   using OsiSolverInterface::addRow;
504   /** */
505   virtual void addRow(const CoinPackedVectorBase &vec,
506     const double rowlb, const double rowub);
507   /** */
508   virtual void addRow(const CoinPackedVectorBase &vec,
509     const char rowsen, const double rowrhs,
510     const double rowrng);
511 
512   using OsiSolverInterface::addRows;
513   /** */
514   virtual void addRows(const int numrows,
515     const CoinPackedVectorBase *const *rows,
516     const double *rowlb, const double *rowub);
517   /** */
518   virtual void addRows(const int numrows,
519     const CoinPackedVectorBase *const *rows,
520     const char *rowsen, const double *rowrhs,
521     const double *rowrng);
522   /** */
523   virtual void deleteRows(const int num, const int *rowIndices);
524 
525   //-----------------------------------------------------------------------
526   /** Apply a collection of row cuts which are all effective.
527       applyCuts seems to do one at a time which seems inefficient.
528   */
529   virtual void applyRowCuts(int numberCuts, const OsiRowCut *cuts);
530   /** Apply a collection of row cuts which are all effective.
531       applyCuts seems to do one at a time which seems inefficient.
532       This uses array of pointers
533   */
534   virtual void applyRowCuts(int numberCuts, const OsiRowCut **cuts);
535   //@}
536   //@}
537 
538   //---------------------------------------------------------------------------
539 
540 public:
541   /**@name Methods to input a problem */
542   //@{
543   /** Load in an problem by copying the arguments (the constraints on the
544       rows are given by lower and upper bounds). If a pointer is 0 then the
545       following values are the default:
546       <ul>
547       <li> <code>colub</code>: all columns have upper bound infinity
548       <li> <code>collb</code>: all columns have lower bound 0
549       <li> <code>rowub</code>: all rows have upper bound infinity
550       <li> <code>rowlb</code>: all rows have lower bound -infinity
551       <li> <code>obj</code>: all variables have 0 objective coefficient
552       </ul>
553   */
554   virtual void loadProblem(const CoinPackedMatrix &matrix,
555     const double *collb, const double *colub,
556     const double *obj,
557     const double *rowlb, const double *rowub);
558 
559   /** Load in an problem by assuming ownership of the arguments (the
560       constraints on the rows are given by lower and upper bounds). For
561       default values see the previous method.  <br>
562       <strong>WARNING</strong>: The arguments passed to this method will be
563       freed using the C++ <code>delete</code> and <code>delete[]</code>
564       functions.
565   */
566   virtual void assignProblem(CoinPackedMatrix *&matrix,
567     double *&collb, double *&colub, double *&obj,
568     double *&rowlb, double *&rowub);
569 
570   /** Load in an problem by copying the arguments (the constraints on the
571       rows are given by sense/rhs/range triplets). If a pointer is 0 then the
572       following values are the default:
573       <ul>
574       <li> <code>colub</code>: all columns have upper bound infinity
575       <li> <code>collb</code>: all columns have lower bound 0
576       <li> <code>obj</code>: all variables have 0 objective coefficient
577       <li> <code>rowsen</code>: all rows are >=
578       <li> <code>rowrhs</code>: all right hand sides are 0
579       <li> <code>rowrng</code>: 0 for the ranged rows
580       </ul>
581   */
582   virtual void loadProblem(const CoinPackedMatrix &matrix,
583     const double *collb, const double *colub,
584     const double *obj,
585     const char *rowsen, const double *rowrhs,
586     const double *rowrng);
587 
588   /** Load in an problem by assuming ownership of the arguments (the
589       constraints on the rows are given by sense/rhs/range triplets). For
590       default values see the previous method. <br>
591       <strong>WARNING</strong>: The arguments passed to this method will be
592       freed using the C++ <code>delete</code> and <code>delete[]</code>
593       functions.
594   */
595   virtual void assignProblem(CoinPackedMatrix *&matrix,
596     double *&collb, double *&colub, double *&obj,
597     char *&rowsen, double *&rowrhs,
598     double *&rowrng);
599 
600   /** Just like the other loadProblem() methods except that the matrix is
601       given in a standard column major ordered format (without gaps). */
602   virtual void loadProblem(const int numcols, const int numrows,
603     const CoinBigIndex *start, const int *index,
604     const double *value,
605     const double *collb, const double *colub,
606     const double *obj,
607     const double *rowlb, const double *rowub);
608 
609   /** Just like the other loadProblem() methods except that the matrix is
610       given in a standard column major ordered format (without gaps). */
611   virtual void loadProblem(const int numcols, const int numrows,
612     const CoinBigIndex *start, const int *index,
613     const double *value,
614     const double *collb, const double *colub,
615     const double *obj,
616     const char *rowsen, const double *rowrhs,
617     const double *rowrng);
618 
619   using OsiSolverInterface::readMps;
620   /** Read an mps file from the given filename (defaults to Osi reader) - returns
621       number of errors (see OsiMpsReader class) */
622   virtual int readMps(const char *filename,
623     const char *extension = "mps");
624 
625   /** Write the problem into an mps file of the given filename.
626       If objSense is non zero then -1.0 forces the code to write a
627       maximization objective and +1.0 to write a minimization one.
628       If 0.0 then solver can do what it wants */
629   virtual void writeMps(const char *filename,
630     const char *extension = "mps",
631     double objSense = 0.0) const;
632   /** Write the problem into an mps file of the given filename,
633       names may be null.  formatType is
634       0 - normal
635       1 - extra accuracy
636       2 - IEEE hex (later)
637 
638       Returns non-zero on I/O error
639   */
640   virtual int writeMpsNative(const char *filename,
641     const char **rowNames, const char **columnNames,
642     int formatType = 0, int numberAcross = 2,
643     double objSense = 0.0) const;
644   //@}
645 
646   /**@name Message handling (extra for Cbc messages).
647      Normally I presume you would want the same language.
648      If not then you could use underlying model pointer */
649   //@{
650   /// Set language
651   void newLanguage(CoinMessages::Language language);
setLanguage(CoinMessages::Language language)652   void setLanguage(CoinMessages::Language language)
653   {
654     newLanguage(language);
655   }
656   //@}
657   //---------------------------------------------------------------------------
658 
659   /**@name Cbc specific public interfaces */
660   //@{
661   /// Get pointer to Cbc model
getModelPtr() const662   inline CbcModel *getModelPtr() const
663   {
664     return modelPtr_;
665   }
666   /// Get pointer to underlying solver
getRealSolverPtr() const667   inline OsiSolverInterface *getRealSolverPtr() const
668   {
669     return modelPtr_->solver();
670   }
671   /// Set cutoff bound on the objective function.
setCutoff(double value)672   inline void setCutoff(double value)
673   {
674     modelPtr_->setCutoff(value);
675   }
676   /// Get the cutoff bound on the objective function - always as minimize
getCutoff() const677   inline double getCutoff() const
678   {
679     return modelPtr_->getCutoff();
680   }
681   /// Set the CbcModel::CbcMaxNumNode maximum node limit
setMaximumNodes(int value)682   inline void setMaximumNodes(int value)
683   {
684     modelPtr_->setMaximumNodes(value);
685   }
686   /// Get the CbcModel::CbcMaxNumNode maximum node limit
getMaximumNodes() const687   inline int getMaximumNodes() const
688   {
689     return modelPtr_->getMaximumNodes();
690   }
691   /// Set the CbcModel::CbcMaxNumSol maximum number of solutions
setMaximumSolutions(int value)692   inline void setMaximumSolutions(int value)
693   {
694     modelPtr_->setMaximumSolutions(value);
695   }
696   /// Get the CbcModel::CbcMaxNumSol maximum number of solutions
getMaximumSolutions() const697   inline int getMaximumSolutions() const
698   {
699     return modelPtr_->getMaximumSolutions();
700   }
701   /// Set the CbcModel::CbcMaximumSeconds maximum number of seconds
setMaximumSeconds(double value)702   inline void setMaximumSeconds(double value)
703   {
704     modelPtr_->setMaximumSeconds(value);
705   }
706   /// Get the CbcModel::CbcMaximumSeconds maximum number of seconds
getMaximumSeconds() const707   inline double getMaximumSeconds() const
708   {
709     return modelPtr_->getMaximumSeconds();
710   }
711   /// Node limit reached?
isNodeLimitReached() const712   inline bool isNodeLimitReached() const
713   {
714     return modelPtr_->isNodeLimitReached();
715   }
716   /// Solution limit reached?
isSolutionLimitReached() const717   inline bool isSolutionLimitReached() const
718   {
719     return modelPtr_->isSolutionLimitReached();
720   }
721   /// Get how many Nodes it took to solve the problem.
getNodeCount() const722   inline int getNodeCount() const
723   {
724     return modelPtr_->getNodeCount();
725   }
726   /// Final status of problem - 0 finished, 1 stopped, 2 difficulties
status() const727   inline int status() const
728   {
729     return modelPtr_->status();
730   }
731   /** Pass in a message handler
732 
733     It is the client's responsibility to destroy a message handler installed
734     by this routine; it will not be destroyed when the solver interface is
735     destroyed.
736   */
737   virtual void passInMessageHandler(CoinMessageHandler *handler);
738   //@}
739 
740   //---------------------------------------------------------------------------
741 
742   /**@name Constructors and destructors */
743   //@{
744   /// Default Constructor
745   OsiCbcSolverInterface(OsiSolverInterface *solver = NULL,
746     CbcStrategy *strategy = NULL);
747 
748   /// Clone
749   virtual OsiSolverInterface *clone(bool copyData = true) const;
750 
751   /// Copy constructor
752   OsiCbcSolverInterface(const OsiCbcSolverInterface &);
753 #if 0
754   /// Borrow constructor - only delete one copy
755   OsiCbcSolverInterface (CbcModel * rhs, bool reallyOwn=false);
756 
757   /// Releases so won't error
758   void releaseCbc();
759 #endif
760   /// Assignment operator
761   OsiCbcSolverInterface &operator=(const OsiCbcSolverInterface &rhs);
762 
763   /// Destructor
764   virtual ~OsiCbcSolverInterface();
765 
766   //@}
767   //---------------------------------------------------------------------------
768 
769 protected:
770   ///@name Protected methods
771   //@{
772   /** Apply a row cut (append to constraint matrix). */
773   virtual void applyRowCut(const OsiRowCut &rc);
774 
775   /** Apply a column cut (adjust one or more bounds). */
776   virtual void applyColCut(const OsiColCut &cc);
777   //@}
778   /**@name Protected member data */
779   //@{
780   /// Cbc model represented by this class instance
781   mutable CbcModel *modelPtr_;
782   //@}
783 };
784 // So unit test can find out if NDEBUG set
785 bool OsiCbcHasNDEBUG();
786 
787 //#############################################################################
788 /** A function that tests the methods in the OsiCbcSolverInterface class. */
789 void OsiCbcSolverInterfaceUnitTest(const std::string &mpsDir, const std::string &netlibDir);
790 
791 #endif
792