1 //-----------------------------------------------------------------------------
2 // name:     OSI Interface for SoPlex >= 1.4.2c
3 // authors:  Tobias Pfender
4 //           Ambros Gleixner
5 //           Wei Huang
6 //           Konrad-Zuse-Zentrum Berlin (Germany)
7 //           email: pfender@zib.de
8 // date:     01/16/2002
9 // license:  this file may be freely distributed under the terms of the EPL
10 //-----------------------------------------------------------------------------
11 // Copyright (C) 2002, Tobias Pfender, International Business Machines
12 // Corporation and others.  All Rights Reserved.
13 // Last edit: $Id: OsiSpxSolverInterface.hpp 2200 2019-01-06 23:02:02Z unxusr $
14 
15 #ifndef OsiSpxSolverInterface_H
16 #define OsiSpxSolverInterface_H
17 
18 #include <string>
19 #include "OsiSolverInterface.hpp"
20 #include "CoinWarmStartBasis.hpp"
21 
22 #ifndef _SOPLEX_H_
23 /* forward declarations so the header can be compiled without having to include soplex.h
24  * however, these declaration work only for SoPlex < 2.0, so we do them only if soplex.h hasn't been included already
25  */
26 namespace soplex {
27 class DIdxSet;
28 class DVector;
29 class SPxOut;
30 class SoPlex;
31 }
32 #endif
33 
34 /** SoPlex Solver Interface
35     Instantiation of OsiSpxSolverInterface for SoPlex
36 */
37 class OsiSpxSolverInterface : virtual public OsiSolverInterface {
38   friend void OsiSpxSolverInterfaceUnitTest(const std::string &mpsDir, const std::string &netlibDir);
39 
40 public:
41   //---------------------------------------------------------------------------
42   /**@name Solve methods */
43   //@{
44   /// Solve initial LP relaxation
45   virtual void initialSolve();
46 
47   /// Resolve an LP relaxation after problem modification
48   virtual void resolve();
49 
50   /// Invoke solver's built-in enumeration algorithm
51   virtual void branchAndBound();
52   //@}
53 
54   //---------------------------------------------------------------------------
55   /**@name Parameter set/get methods
56 
57      The set methods return true if the parameter was set to the given value,
58      false otherwise. There can be various reasons for failure: the given
59      parameter is not applicable for the solver (e.g., refactorization
60      frequency for the volume algorithm), the parameter is not yet implemented
61      for the solver or simply the value of the parameter is out of the range
62      the solver accepts. If a parameter setting call returns false check the
63      details of your solver.
64 
65      The get methods return true if the given parameter is applicable for the
66      solver and is implemented. In this case the value of the parameter is
67      returned in the second argument. Otherwise they return false.
68   */
69   //@{
70   // Set an integer parameter
71   bool setIntParam(OsiIntParam key, int value);
72   // Set an double parameter
73   bool setDblParam(OsiDblParam key, double value);
74   // Get an integer parameter
75   bool getIntParam(OsiIntParam key, int &value) const;
76   // Get an double parameter
77   bool getDblParam(OsiDblParam key, double &value) const;
78   // Get a string parameter
79   bool getStrParam(OsiStrParam key, std::string &value) const;
80   // Set timelimit
81   void setTimeLimit(double value);
82   // Get timelimit
83   double getTimeLimit() const;
84   //@}
85 
86   //---------------------------------------------------------------------------
87   ///@name Methods returning info on how the solution process terminated
88   //@{
89   /// Are there a numerical difficulties?
90   virtual bool isAbandoned() const;
91   /// Is optimality proven?
92   virtual bool isProvenOptimal() const;
93   /// Is primal infeasiblity proven?
94   virtual bool isProvenPrimalInfeasible() const;
95   /// Is dual infeasiblity proven?
96   virtual bool isProvenDualInfeasible() const;
97   // Is the given primal objective limit reached? - use implementation from OsiSolverInterface
98   /// Is the given dual objective limit reached?
99   virtual bool isDualObjectiveLimitReached() const;
100   /// Iteration limit reached?
101   virtual bool isIterationLimitReached() const;
102   /// Time limit reached?
103   virtual bool isTimeLimitReached() const;
104   //@}
105 
106   //---------------------------------------------------------------------------
107   /**@name WarmStart related methods */
108   //@{
109   /// Get empty warm start object
getEmptyWarmStart() const110   inline CoinWarmStart *getEmptyWarmStart() const
111   {
112     return (dynamic_cast< CoinWarmStart * >(new CoinWarmStartBasis()));
113   }
114   /// Get warmstarting information
115   virtual CoinWarmStart *getWarmStart() const;
116   /** Set warmstarting information. Return true/false depending on whether
117 	the warmstart information was accepted or not. */
118   virtual bool setWarmStart(const CoinWarmStart *warmstart);
119   //@}
120 
121   //---------------------------------------------------------------------------
122   /**@name Hotstart related methods (primarily used in strong branching). <br>
123      The user can create a hotstart (a snapshot) of the optimization process
124      then reoptimize over and over again always starting from there.<br>
125      <strong>NOTE</strong>: between hotstarted optimizations only
126      bound changes are allowed. */
127   //@{
128   /// Create a hotstart point of the optimization process
129   virtual void markHotStart();
130   /// Optimize starting from the hotstart
131   virtual void solveFromHotStart();
132   /// Delete the snapshot
133   virtual void unmarkHotStart();
134   //@}
135 
136   //---------------------------------------------------------------------------
137   /**@name Problem information methods
138 
139      These methods call the solver's query routines to return
140      information about the problem referred to by the current object.
141      Querying a problem that has no data associated with it result in
142      zeros for the number of rows and columns, and NULL pointers from
143      the methods that return vectors.
144 
145      Const pointers returned from any data-query method are valid as
146      long as the data is unchanged and the solver is not called.
147   */
148   //@{
149   /**@name Methods related to querying the input data */
150   //@{
151   /// Get number of columns
152   virtual int getNumCols() const;
153 
154   /// Get number of rows
155   virtual int getNumRows() const;
156 
157   /// Get number of nonzero elements
158   virtual int getNumElements() const;
159 
160   /// Get pointer to array[getNumCols()] of column lower bounds
161   virtual const double *getColLower() const;
162 
163   /// Get pointer to array[getNumCols()] of column upper bounds
164   virtual const double *getColUpper() const;
165 
166   /** Get pointer to array[getNumRows()] of row constraint senses.
167   	<ul>
168   	<li>'L': <= constraint
169   	<li>'E': =  constraint
170   	<li>'G': >= constraint
171   	<li>'R': ranged constraint
172   	<li>'N': free constraint
173   	</ul>
174       */
175   virtual const char *getRowSense() const;
176 
177   /** Get pointer to array[getNumRows()] of rows right-hand sides
178   	<ul>
179   	  <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i]
180   	  <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i]
181   	  <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i]
182   	  <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0
183   	</ul>
184       */
185   virtual const double *getRightHandSide() const;
186 
187   /** Get pointer to array[getNumRows()] of row ranges.
188   	<ul>
189             <li> if rowsense()[i] == 'R' then
190                     rowrange()[i] == rowupper()[i] - rowlower()[i]
191             <li> if rowsense()[i] != 'R' then
192                     rowrange()[i] is 0.0
193           </ul>
194       */
195   virtual const double *getRowRange() const;
196 
197   /// Get pointer to array[getNumRows()] of row lower bounds
198   virtual const double *getRowLower() const;
199 
200   /// Get pointer to array[getNumRows()] of row upper bounds
201   virtual const double *getRowUpper() const;
202 
203   /// Get pointer to array[getNumCols()] of objective function coefficients
204   virtual const double *getObjCoefficients() const;
205 
206   /// Get objective function sense (1 for min (default), -1 for max)
207   virtual double getObjSense() const;
208 
209   /// Return true if column is continuous
210   virtual bool isContinuous(int colNumber) const;
211 
212 #if 0
213       /// Return true if column is binary
214       virtual bool isBinary(int columnNumber) const;
215 
216       /** Return true if column is integer.
217           Note: This function returns true if the the column
218           is binary or a general integer.
219       */
220       virtual bool isInteger(int columnNumber) const;
221 
222       /// Return true if column is general integer
223       virtual bool isIntegerNonBinary(int columnNumber) const;
224 
225       /// Return true if column is binary and not fixed at either bound
226       virtual bool isFreeBinary(int columnNumber) const;
227 #endif
228 
229   /// Get pointer to row-wise copy of matrix
230   virtual const CoinPackedMatrix *getMatrixByRow() const;
231 
232   /// Get pointer to column-wise copy of matrix
233   virtual const CoinPackedMatrix *getMatrixByCol() const;
234 
235   /// Get solver's value for infinity
236   virtual double getInfinity() const;
237   //@}
238 
239   /**@name Methods related to querying the solution */
240   //@{
241   /// Get pointer to array[getNumCols()] of primal solution vector
242   virtual const double *getColSolution() const;
243 
244   /// Get pointer to array[getNumRows()] of dual prices
245   virtual const double *getRowPrice() const;
246 
247   /// Get a pointer to array[getNumCols()] of reduced costs
248   virtual const double *getReducedCost() const;
249 
250   /** Get pointer to array[getNumRows()] of row activity levels (constraint
251   	matrix times the solution vector */
252   virtual const double *getRowActivity() const;
253 
254   /// Get objective function value
255   virtual double getObjValue() const;
256 
257   /** Get how many iterations it took to solve the problem (whatever
258 	  "iteration" mean to the solver. */
259   virtual int getIterationCount() const;
260 
261   /** Get as many dual rays as the solver can provide. (In case of proven
262           primal infeasibility there should be at least one.)
263 
264 	  The first getNumRows() ray components will always be associated with
265 	  the row duals (as returned by getRowPrice()). If \c fullRay is true,
266 	  the final getNumCols() entries will correspond to the ray components
267 	  associated with the nonbasic variables. If the full ray is requested
268 	  and the method cannot provide it, it will throw an exception.
269 
270           <strong>NOTE for implementers of solver interfaces:</strong> <br>
271           The double pointers in the vector should point to arrays of length
272           getNumRows() and they should be allocated via new[]. <br>
273 
274           <strong>NOTE for users of solver interfaces:</strong> <br>
275           It is the user's responsibility to free the double pointers in the
276           vector using delete[].
277       */
278   virtual std::vector< double * > getDualRays(int maxNumRays,
279     bool fullRay = false) const;
280   /** Get as many primal rays as the solver can provide. (In case of proven
281           dual infeasibility there should be at least one.)
282 
283           <strong>NOTE for implementers of solver interfaces:</strong> <br>
284           The double pointers in the vector should point to arrays of length
285           getNumCols() and they should be allocated via new[]. <br>
286 
287           <strong>NOTE for users of solver interfaces:</strong> <br>
288           It is the user's responsibility to free the double pointers in the
289           vector using delete[].
290       */
291   virtual std::vector< double * > getPrimalRays(int maxNumRays) const;
292 
293 #if 0
294       /** Get vector of indices of solution which are integer variables
295   	presently at fractional values */
296       virtual OsiVectorInt getFractionalIndices(const double etol=1.e-05)
297 	const;
298 #endif
299   //@}
300   //@}
301 
302   //---------------------------------------------------------------------------
303 
304   /**@name Problem modifying methods */
305   //@{
306   //-------------------------------------------------------------------------
307   /**@name Changing bounds on variables and constraints */
308   //@{
309   /** Set an objective function coefficient */
310   virtual void setObjCoeff(int elementIndex, double elementValue);
311 
312   /** Set a single column lower bound<br>
313     	  Use -COIN_DBL_MAX for -infinity. */
314   virtual void setColLower(int elementIndex, double elementValue);
315 
316   /** Set a single column upper bound<br>
317     	  Use COIN_DBL_MAX for infinity. */
318   virtual void setColUpper(int elementIndex, double elementValue);
319 
320   /** Set a single column lower and upper bound<br>
321     	  The default implementation just invokes <code>setColLower</code> and
322     	  <code>setColUpper</code> */
323   virtual void setColBounds(int elementIndex,
324     double lower, double upper);
325 
326 #if 0 // we are using the default implementation of OsiSolverInterface
327       /** Set the bounds on a number of columns simultaneously<br>
328     	  The default implementation just invokes <code>setCollower</code> and
329     	  <code>setColupper</code> over and over again.
330     	  @param <code>[indexfirst,indexLast)</code> contains the indices of
331     	         the constraints whose </em>either</em> bound changes
332     	  @param indexList the indices of those variables
333     	  @param boundList the new lower/upper bound pairs for the variables
334       */
335       virtual void setColSetBounds(const int* indexFirst,
336 				   const int* indexLast,
337 				   const double* boundList);
338 #endif
339 
340   /** Set a single row lower bound<br>
341     	  Use -COIN_DBL_MAX for -infinity. */
342   virtual void setRowLower(int elementIndex, double elementValue);
343 
344   /** Set a single row upper bound<br>
345     	  Use COIN_DBL_MAX for infinity. */
346   virtual void setRowUpper(int elementIndex, double elementValue);
347 
348   /** Set a single row lower and upper bound<br>
349     	  The default implementation just invokes <code>setRowUower</code> and
350     	  <code>setRowUpper</code> */
351   virtual void setRowBounds(int elementIndex,
352     double lower, double upper);
353 
354   /** Set the type of a single row<br> */
355   virtual void setRowType(int index, char sense, double rightHandSide,
356     double range);
357 
358 #if 0 // we are using the default implementation of OsiSolverInterface
359       /** Set the bounds on a number of rows simultaneously<br>
360     	  The default implementation just invokes <code>setRowlower</code> and
361     	  <code>setRowupper</code> over and over again.
362     	  @param <code>[indexfirst,indexLast)</code> contains the indices of
363     	         the constraints whose </em>either</em> bound changes
364     	  @param boundList the new lower/upper bound pairs for the constraints
365       */
366       virtual void setRowSetBounds(const int* indexFirst,
367     				   const int* indexLast,
368     				   const double* boundList);
369 
370       /** Set the type of a number of rows simultaneously<br>
371     	  The default implementation just invokes <code>setRowtype</code> and
372     	  over and over again.
373     	  @param <code>[indexfirst,indexLast)</code> contains the indices of
374     	         the constraints whose type changes
375     	  @param senseList the new senses
376     	  @param rhsList   the new right hand sides
377     	  @param rangeList the new ranges
378       */
379       virtual void setRowSetTypes(const int* indexFirst,
380 				  const int* indexLast,
381 				  const char* senseList,
382 				  const double* rhsList,
383 				  const double* rangeList);
384 #endif
385   //@}
386 
387   //-------------------------------------------------------------------------
388   /**@name Integrality related changing methods */
389   //@{
390   /** Set the index-th variable to be a continuous variable */
391   virtual void setContinuous(int index);
392   /** Set the index-th variable to be an integer variable */
393   virtual void setInteger(int index);
394 #if 0 // we are using the default implementation of OsiSolverInterface
395       /** Set the variables listed in indices (which is of length len) to be
396 	  continuous variables */
397       virtual void setContinuous(const int* indices, int len);
398       /** Set the variables listed in indices (which is of length len) to be
399 	  integer variables */
400       virtual void setInteger(const int* indices, int len);
401 #endif
402   //@}
403 
404   //-------------------------------------------------------------------------
405   /// Set objective function sense (1 for min (default), -1 for max,)
406   virtual void setObjSense(double s);
407 
408   /** Set the primal solution column values
409 
410     	colsol[numcols()] is an array of values of the problem column
411     	variables. These values are copied to memory owned by the
412     	solver object or the solver.  They will be returned as the
413     	result of colsol() until changed by another call to
414     	setColsol() or by a call to any solver routine.  Whether the
415     	solver makes use of the solution in any way is
416     	solver-dependent.
417     */
418   virtual void setColSolution(const double *colsol);
419 
420   /** Set dual solution vector
421 
422     	rowprice[numrows()] is an array of values of the problem row
423     	dual variables. These values are copied to memory owned by the
424     	solver object or the solver.  They will be returned as the
425     	result of rowprice() until changed by another call to
426     	setRowprice() or by a call to any solver routine.  Whether the
427     	solver makes use of the solution in any way is
428     	solver-dependent.
429     */
430   virtual void setRowPrice(const double *rowprice);
431 
432   //-------------------------------------------------------------------------
433   /**@name Methods to expand a problem.<br>
434        Note that if a column is added then by default it will correspond to a
435        continuous variable. */
436   //@{
437   /** */
438   virtual void addCol(const CoinPackedVectorBase &vec,
439     const double collb, const double colub,
440     const double obj);
441 
442 #if 0 // we are using the default implementation of OsiSolverInterface
443       /** */
444       virtual void addCols(const int numcols,
445 			   const CoinPackedVectorBase * const * cols,
446 			   const double* collb, const double* colub,
447 			   const double* obj);
448 #endif
449 
450   /** */
451   virtual void deleteCols(const int num, const int *colIndices);
452 
453   /** */
454   virtual void addRow(const CoinPackedVectorBase &vec,
455     const double rowlb, const double rowub);
456   /** */
457   virtual void addRow(const CoinPackedVectorBase &vec,
458     const char rowsen, const double rowrhs,
459     const double rowrng);
460 
461 #if 0 // we are using the default implementation of OsiSolverInterface
462       /** */
463       virtual void addRows(const int numrows,
464 			   const CoinPackedVectorBase * const * rows,
465 			   const double* rowlb, const double* rowub);
466       /** */
467       virtual void addRows(const int numrows,
468 			   const CoinPackedVectorBase * const * rows,
469     			   const char* rowsen, const double* rowrhs,
470     			   const double* rowrng);
471 #endif
472 
473   /** */
474   virtual void deleteRows(const int num, const int *rowIndices);
475 
476 #if 0 // we are using the default implementation of OsiSolverInterface \
477   //-----------------------------------------------------------------------
478       /** Apply a collection of cuts.<br>
479     	  Only cuts which have an <code>effectiveness >= effectivenessLb</code>
480     	  are applied.
481     	  <ul>
482     	    <li> ReturnCode.numberIneffective() -- number of cuts which were
483                  not applied because they had an
484     	         <code>effectiveness < effectivenessLb</code>
485     	    <li> ReturnCode.numberInconsistent() -- number of invalid cuts
486     	    <li> ReturnCode.numberInconsistentWrtIntegerModel() -- number of
487                  cuts that are invalid with respect to this integer model
488             <li> ReturnCode.numberInfeasible() -- number of cuts that would
489     	         make this integer model infeasible
490             <li> ReturnCode.numberApplied() -- number of integer cuts which
491     	         were applied to the integer model
492             <li> cs.size() == numberIneffective() +
493                               numberInconsistent() +
494     			      numberInconsistentWrtIntegerModel() +
495     			      numberInfeasible() +
496     			      nubmerApplied()
497           </ul>
498       */
499       virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs,
500     					    double effectivenessLb = 0.0);
501 #endif
502   //@}
503   //@}
504 
505   //---------------------------------------------------------------------------
506 
507   /**@name Methods to input a problem */
508   //@{
509   /** Load in an problem by copying the arguments (the constraints on the
510         rows are given by lower and upper bounds). If a pointer is 0 then the
511         following values are the default:
512         <ul>
513           <li> <code>colub</code>: all columns have upper bound infinity
514           <li> <code>collb</code>: all columns have lower bound 0
515           <li> <code>rowub</code>: all rows have upper bound infinity
516           <li> <code>rowlb</code>: all rows have lower bound -infinity
517 	  <li> <code>obj</code>: all variables have 0 objective coefficient
518         </ul>
519     */
520   virtual void loadProblem(const CoinPackedMatrix &matrix,
521     const double *collb, const double *colub,
522     const double *obj,
523     const double *rowlb, const double *rowub);
524 
525   /** Load in an problem by assuming ownership of the arguments (the
526         constraints on the rows are given by lower and upper bounds). For
527         default values see the previous method. <br>
528 	<strong>WARNING</strong>: The arguments passed to this method will be
529 	freed using the C++ <code>delete</code> and <code>delete[]</code>
530 	functions.
531     */
532   virtual void assignProblem(CoinPackedMatrix *&matrix,
533     double *&collb, double *&colub, double *&obj,
534     double *&rowlb, double *&rowub);
535 
536   /** Load in an problem by copying the arguments (the constraints on the
537 	rows are given by sense/rhs/range triplets). If a pointer is 0 then the
538 	following values are the default:
539 	<ul>
540           <li> <code>colub</code>: all columns have upper bound infinity
541           <li> <code>collb</code>: all columns have lower bound 0
542 	  <li> <code>obj</code>: all variables have 0 objective coefficient
543           <li> <code>rowsen</code>: all rows are >=
544           <li> <code>rowrhs</code>: all right hand sides are 0
545           <li> <code>rowrng</code>: 0 for the ranged rows
546         </ul>
547     */
548   virtual void loadProblem(const CoinPackedMatrix &matrix,
549     const double *collb, const double *colub,
550     const double *obj,
551     const char *rowsen, const double *rowrhs,
552     const double *rowrng);
553 
554   /** Load in an problem by assuming ownership of the arguments (the
555         constraints on the rows are given by sense/rhs/range triplets). For
556         default values see the previous method. <br>
557 	<strong>WARNING</strong>: The arguments passed to this method will be
558 	freed using the C++ <code>delete</code> and <code>delete[]</code>
559 	functions.
560     */
561   virtual void assignProblem(CoinPackedMatrix *&matrix,
562     double *&collb, double *&colub, double *&obj,
563     char *&rowsen, double *&rowrhs,
564     double *&rowrng);
565 
566   /** Just like the other loadProblem() methods except that the matrix is
567 	given in a standard column major ordered format (without gaps). */
568   virtual void loadProblem(const int numcols, const int numrows,
569     const int *start, const int *index,
570     const double *value,
571     const double *collb, const double *colub,
572     const double *obj,
573     const double *rowlb, const double *rowub);
574 
575   /** Just like the other loadProblem() methods except that the matrix is
576 	given in a standard column major ordered format (without gaps). */
577   virtual void loadProblem(const int numcols, const int numrows,
578     const int *start, const int *index,
579     const double *value,
580     const double *collb, const double *colub,
581     const double *obj,
582     const char *rowsen, const double *rowrhs,
583     const double *rowrng);
584 
585   /** Read an mps file from the given filename */
586   virtual int readMps(const char *filename,
587     const char *extension = "mps");
588 
589   /** Write the problem into an mps file of the given filename.
590      If objSense is non zero then -1.0 forces the code to write a
591     maximization objective and +1.0 to write a minimization one.
592     If 0.0 then solver can do what it wants */
593   virtual void writeMps(const char *filename,
594     const char *extension = "mps",
595     double objSense = 0.0) const;
596   //@}
597 
598   //---------------------------------------------------------------------------
599 
600   /**@name Constructors and destructor */
601   //@{
602   /// Default Constructor
603   OsiSpxSolverInterface();
604 
605   /// Clone
606   virtual OsiSolverInterface *clone(bool copyData = true) const;
607 
608   /// Copy constructor
609   OsiSpxSolverInterface(const OsiSpxSolverInterface &);
610 
611   /// Assignment operator
612   OsiSpxSolverInterface &operator=(const OsiSpxSolverInterface &rhs);
613 
614   /// Destructor
615   virtual ~OsiSpxSolverInterface();
616   //@}
617 
618   enum keepCachedFlag {
619     /// discard all cached data (default)
620     KEEPCACHED_NONE = 0,
621     /// column information: objective values, lower and upper bounds, variable types
622     KEEPCACHED_COLUMN = 1,
623     /// row information: right hand sides, ranges and senses, lower and upper bounds for row
624     KEEPCACHED_ROW = 2,
625     /// problem matrix: matrix ordered by column and by row
626     KEEPCACHED_MATRIX = 4,
627     /// LP solution: primal and dual solution, reduced costs, row activities
628     KEEPCACHED_RESULTS = 8,
629     /// only discard cached LP solution
630     KEEPCACHED_PROBLEM = KEEPCACHED_COLUMN | KEEPCACHED_ROW | KEEPCACHED_MATRIX,
631     /// keep all cached data (similar to getMutableLpPtr())
632     KEEPCACHED_ALL = KEEPCACHED_PROBLEM | KEEPCACHED_RESULTS,
633     /// free only cached column and LP solution information
634     FREECACHED_COLUMN = KEEPCACHED_PROBLEM & ~KEEPCACHED_COLUMN,
635     /// free only cached row and LP solution information
636     FREECACHED_ROW = KEEPCACHED_PROBLEM & ~KEEPCACHED_ROW,
637     /// free only cached matrix and LP solution information
638     FREECACHED_MATRIX = KEEPCACHED_PROBLEM & ~KEEPCACHED_MATRIX,
639     /// free only cached LP solution information
640     FREECACHED_RESULTS = KEEPCACHED_ALL & ~KEEPCACHED_RESULTS
641   };
642   soplex::SoPlex *getLpPtr(int keepCached = KEEPCACHED_NONE);
643 
getSPxOut()644   soplex::SPxOut *getSPxOut() { return spxout_; }
645 
646 protected:
647   /**@name Protected methods */
648   //@{
649   /// Apply a row cut. Return true if cut was applied.
650   virtual void applyRowCut(const OsiRowCut &rc);
651 
652   /** Apply a column cut (bound adjustment).
653       Return true if cut was applied.
654   */
655   virtual void applyColCut(const OsiColCut &cc);
656   //@}
657 
658   /**@name Protected member data */
659   //@{
660   /// SoPlex output object
661   soplex::SPxOut *spxout_;
662   /// SoPlex solver object
663   soplex::SoPlex *soplex_;
664   //@}
665 
666 private:
667   /**@name Private methods */
668   //@{
669 
670   /// free cached column rim vectors
671   void freeCachedColRim();
672 
673   /// free cached row rim vectors
674   void freeCachedRowRim();
675 
676   /// free cached result vectors
677   void freeCachedResults();
678 
679   /// free cached matrices
680   void freeCachedMatrix();
681 
682   /// free all cached data (except specified entries, see getLpPtr())
683   void freeCachedData(int keepCached = KEEPCACHED_NONE);
684 
685   /// free all allocated memory
686   void freeAllMemory();
687   //@}
688 
689   /**@name Private member data */
690   //@{
691   /// indices of integer variables
692   soplex::DIdxSet *spxintvars_;
693 
694   /// Hotstart information
695   void *hotStartCStat_;
696   int hotStartCStatSize_;
697   void *hotStartRStat_;
698   int hotStartRStatSize_;
699   int hotStartMaxIteration_;
700 
701   /**@name Cached information derived from the SoPlex model */
702   //@{
703   /// Pointer to objective Vector
704   mutable soplex::DVector *obj_;
705 
706   /// Pointer to dense vector of row sense indicators
707   mutable char *rowsense_;
708 
709   /// Pointer to dense vector of row right-hand side values
710   mutable double *rhs_;
711 
712   /// Pointer to dense vector of slack upper bounds for range constraints (undefined for non-range rows)
713   mutable double *rowrange_;
714 
715   /// Pointer to primal solution vector
716   mutable soplex::DVector *colsol_;
717 
718   /// Pointer to dual solution vector
719   mutable soplex::DVector *rowsol_;
720 
721   /// Pointer to reduced cost vector
722   mutable soplex::DVector *redcost_;
723 
724   /// Pointer to row activity (slack) vector
725   mutable soplex::DVector *rowact_;
726 
727   /// Pointer to row-wise copy of problem matrix coefficients.
728   mutable CoinPackedMatrix *matrixByRow_;
729 
730   /// Pointer to row-wise copy of problem matrix coefficients.
731   mutable CoinPackedMatrix *matrixByCol_;
732   //@}
733   //@}
734 };
735 
736 //#############################################################################
737 /** A function that tests the methods in the OsiSpxSolverInterface class. */
738 void OsiSpxSolverInterfaceUnitTest(const std::string &mpsDir, const std::string &netlibDir);
739 
740 #endif
741 
742 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
743 */
744