1 // Copyright (C) 2000, International Business Machines
2 // Corporation and others.  All Rights Reserved.
3 // This code is licensed under the terms of the Eclipse Public License (EPL).
4 
5 #ifndef OsiSolverInterface_H
6 #define OsiSolverInterface_H
7 
8 #include <cstdlib>
9 #include <string>
10 #include <vector>
11 
12 #include "CoinMessageHandler.hpp"
13 #include "CoinPackedVectorBase.hpp"
14 #include "CoinTypes.hpp"
15 
16 #include "OsiCollections.hpp"
17 #include "OsiSolverParameters.hpp"
18 
19 class CoinPackedMatrix;
20 class CoinWarmStart;
21 class CoinSnapshot;
22 class CoinLpIO;
23 class CoinMpsIO;
24 
25 class OsiCuts;
26 class OsiAuxInfo;
27 class OsiRowCut;
28 class OsiRowCutDebugger;
29 class CoinSet;
30 class CoinBuild;
31 class CoinModel;
32 class OsiSolverBranch;
33 class OsiSolverResult;
34 class OsiObject;
35 
36 
37 //#############################################################################
38 
39 /*! \brief Abstract Base Class for describing an interface to a solver.
40 
41   Many OsiSolverInterface query methods return a const pointer to the
42   requested read-only data. If the model data is changed or the solver
43   is called, these pointers may no longer be valid and should be
44   refreshed by invoking the member function to obtain an updated copy
45   of the pointer.
46   For example:
47   \code
48       OsiSolverInterface solverInterfacePtr ;
49       const double * ruBnds = solverInterfacePtr->getRowUpper();
50       solverInterfacePtr->applyCuts(someSetOfCuts);
51       // ruBnds is no longer a valid pointer and must be refreshed
52       ruBnds = solverInterfacePtr->getRowUpper();
53   \endcode
54 
55   Querying a problem that has no data associated with it will result in
56   zeros for the number of rows and columns, and NULL pointers from
57   the methods that return vectors.
58 */
59 
60 class OsiSolverInterface  {
61    friend void OsiSolverInterfaceCommonUnitTest(
62       const OsiSolverInterface* emptySi,
63       const std::string & mpsDir,
64       const std::string & netlibDir);
65    friend void OsiSolverInterfaceMpsUnitTest(
66       const std::vector<OsiSolverInterface*> & vecSiP,
67       const std::string & mpsDir);
68 
69 public:
70 
71   /// Internal class for obtaining status from the applyCuts method
72   class ApplyCutsReturnCode {
73     friend class OsiSolverInterface;
74     friend class OsiOslSolverInterface;
75     friend class OsiClpSolverInterface;
76 
77   public:
78     ///@name Constructors and desctructors
79     //@{
80       /// Default constructor
ApplyCutsReturnCode()81       ApplyCutsReturnCode():
82 	 intInconsistent_(0),
83 	 extInconsistent_(0),
84 	 infeasible_(0),
85 	 ineffective_(0),
86 	 applied_(0) {}
87       /// Copy constructor
ApplyCutsReturnCode(const ApplyCutsReturnCode & rhs)88       ApplyCutsReturnCode(const ApplyCutsReturnCode & rhs):
89 	 intInconsistent_(rhs.intInconsistent_),
90 	 extInconsistent_(rhs.extInconsistent_),
91 	 infeasible_(rhs.infeasible_),
92 	 ineffective_(rhs.ineffective_),
93 	 applied_(rhs.applied_) {}
94       /// Assignment operator
operator =(const ApplyCutsReturnCode & rhs)95       ApplyCutsReturnCode & operator=(const ApplyCutsReturnCode& rhs)
96       {
97 	if (this != &rhs) {
98 	  intInconsistent_ = rhs.intInconsistent_;
99 	  extInconsistent_ = rhs.extInconsistent_;
100 	  infeasible_      = rhs.infeasible_;
101 	  ineffective_     = rhs.ineffective_;
102 	  applied_         = rhs.applied_;
103 	}
104 	return *this;
105       }
106       /// Destructor
~ApplyCutsReturnCode()107       ~ApplyCutsReturnCode(){}
108     //@}
109 
110     /**@name Accessing return code attributes */
111     //@{
112       /// Number of logically inconsistent cuts
getNumInconsistent()113       inline int getNumInconsistent(){return intInconsistent_;}
114       /// Number of cuts inconsistent with the current model
getNumInconsistentWrtIntegerModel()115       inline int getNumInconsistentWrtIntegerModel(){return extInconsistent_;}
116       /// Number of cuts that cause obvious infeasibility
getNumInfeasible()117       inline int getNumInfeasible(){return infeasible_;}
118       /// Number of redundant or ineffective cuts
getNumIneffective()119       inline int getNumIneffective(){return ineffective_;}
120       /// Number of cuts applied
getNumApplied()121       inline int getNumApplied(){return applied_;}
122     //@}
123 
124   private:
125     /**@name Private methods */
126     //@{
127       /// Increment logically inconsistent cut counter
incrementInternallyInconsistent()128       inline void incrementInternallyInconsistent(){intInconsistent_++;}
129       /// Increment model-inconsistent counter
incrementExternallyInconsistent()130       inline void incrementExternallyInconsistent(){extInconsistent_++;}
131       /// Increment infeasible cut counter
incrementInfeasible()132       inline void incrementInfeasible(){infeasible_++;}
133       /// Increment ineffective cut counter
incrementIneffective()134       inline void incrementIneffective(){ineffective_++;}
135       /// Increment applied cut counter
incrementApplied()136       inline void incrementApplied(){applied_++;}
137     //@}
138 
139     ///@name Private member data
140     //@{
141       /// Counter for logically inconsistent cuts
142       int intInconsistent_;
143       /// Counter for model-inconsistent cuts
144       int extInconsistent_;
145       /// Counter for infeasible cuts
146       int infeasible_;
147       /// Counter for ineffective cuts
148       int ineffective_;
149       /// Counter for applied cuts
150       int applied_;
151     //@}
152   };
153 
154   //---------------------------------------------------------------------------
155 
156   ///@name Solve methods
157   //@{
158     /// Solve initial LP relaxation
159     virtual void initialSolve() = 0;
160 
161     /*! \brief Resolve an LP relaxation after problem modification
162 
163       Note the `re-' in `resolve'. initialSolve() should be used to solve the
164       problem for the first time.
165     */
166     virtual void resolve() = 0;
167 
168     /// Invoke solver's built-in enumeration algorithm
169     virtual void branchAndBound() = 0;
170 
171 #ifdef CBC_NEXT_VERSION
172     /*
173       Would it make sense to collect all of these routines in a `MIP Helper'
174       section? It'd make it easier for users and implementors to find them.
175     */
176     /**
177        Solve 2**N (N==depth) problems and return solutions and bases.
178        There are N branches each of which changes bounds on both sides
179        as given by branch.  The user should provide an array of (empty)
180        results which will be filled in.  See OsiSolveResult for more details
181        (in OsiSolveBranch.?pp) but it will include a basis and primal solution.
182 
183        The order of results is left to right at feasible leaf nodes so first one
184        is down, down, .....
185 
186        Returns number of feasible leaves.  Also sets number of solves done and number
187        of iterations.
188 
189        This is provided so a solver can do faster.
190 
191        If forceBranch true then branch done even if satisfied
192     */
193     virtual int solveBranches(int depth,const OsiSolverBranch * branch,
194 			      OsiSolverResult * result,
195 			      int & numberSolves, int & numberIterations,
196 			      bool forceBranch=false);
197 #endif
198   //@}
199 
200   //---------------------------------------------------------------------------
201   /**@name Parameter set/get methods
202 
203      The set methods return true if the parameter was set to the given value,
204      false otherwise. When a set method returns false, the original value (if
205      any) should be unchanged.  There can be various reasons for failure: the
206      given parameter is not applicable for the solver (e.g., refactorization
207      frequency for the volume algorithm), the parameter is not yet
208      implemented for the solver or simply the value of the parameter is out
209      of the range the solver accepts. If a parameter setting call returns
210      false check the details of your solver.
211 
212      The get methods return true if the given parameter is applicable for the
213      solver and is implemented. In this case the value of the parameter is
214      returned in the second argument. Otherwise they return false.
215 
216      \note
217      There is a default implementation of the set/get
218      methods, namely to store/retrieve the given value using an array in the
219      base class. A specific solver implementation can use this feature, for
220      example, to store parameters that should be used later on. Implementors
221      of a solver interface should overload these functions to provide the
222      proper interface to and accurately reflect the capabilities of a
223      specific solver.
224 
225      The format for hints is slightly different in that a boolean specifies
226      the sense of the hint and an enum specifies the strength of the hint.
227      Hints should be initialised when a solver is instantiated.
228      (See OsiSolverParameters.hpp for defined hint parameters and strength.)
229      When specifying the sense of the hint, a value of true means to work with
230      the hint, false to work against it.  For example,
231      <ul>
232        <li> \code setHintParam(OsiDoScale,true,OsiHintTry) \endcode
233 	    is a mild suggestion to the solver to scale the constraint
234 	    system.
235        <li> \code setHintParam(OsiDoScale,false,OsiForceDo) \endcode
236 	    tells the solver to disable scaling, or throw an exception if
237 	    it cannot comply.
238      </ul>
239      As another example, a solver interface could use the value and strength
240      of the \c OsiDoReducePrint hint to adjust the amount of information
241      printed by the interface and/or solver.  The extent to which a solver
242      obeys hints is left to the solver.  The value and strength returned by
243      \c getHintParam will match the most recent call to \c setHintParam,
244      and will not necessarily reflect the solver's ability to comply with the
245      hint.  If the hint strength is \c OsiForceDo, the solver is required to
246      throw an exception if it cannot perform the specified action.
247 
248      \note
249      As with the other set/get methods, there is a default implementation
250      which maintains arrays in the base class for hint sense and strength.
251      The default implementation does not store the \c otherInformation
252      pointer, and always throws an exception for strength \c OsiForceDo.
253      Implementors of a solver interface should override these functions to
254      provide the proper interface to and accurately reflect the capabilities
255      of a specific solver.
256   */
257   //@{
258     //! Set an integer parameter
setIntParam(OsiIntParam key,int value)259     virtual bool setIntParam(OsiIntParam key, int value) {
260       if (key == OsiLastIntParam) return (false) ;
261       intParam_[key] = value;
262       return true;
263     }
264     //! Set a double parameter
setDblParam(OsiDblParam key,double value)265     virtual bool setDblParam(OsiDblParam key, double value) {
266       if (key == OsiLastDblParam) return (false) ;
267       dblParam_[key] = value;
268       return true;
269     }
270     //! Set a string parameter
setStrParam(OsiStrParam key,const std::string & value)271     virtual bool setStrParam(OsiStrParam key, const std::string & value) {
272       if (key == OsiLastStrParam) return (false) ;
273       strParam_[key] = value;
274       return true;
275     }
276     /*! \brief Set a hint parameter
277 
278       The \c otherInformation parameter can be used to pass in an arbitrary
279       block of information which is interpreted by the OSI and the underlying
280       solver.  Users are cautioned that this hook is solver-specific.
281 
282       Implementors:
283       The default implementation completely ignores \c otherInformation and
284       always throws an exception for OsiForceDo. This is almost certainly not
285       the behaviour you want; you really should override this method.
286     */
setHintParam(OsiHintParam key,bool yesNo=true,OsiHintStrength strength=OsiHintTry,void * =nullptr)287     virtual bool setHintParam(OsiHintParam key, bool yesNo=true,
288 			      OsiHintStrength strength=OsiHintTry,
289 			      void * /*otherInformation*/ = nullptr) {
290       if (key==OsiLastHintParam)
291 	return false;
292       hintParam_[key] = yesNo;
293       hintStrength_[key] = strength;
294       if (strength == OsiForceDo)
295 	throw CoinError("OsiForceDo illegal",
296 			"setHintParam", "OsiSolverInterface");
297       return true;
298     }
299     //! Get an integer parameter
getIntParam(OsiIntParam key,int & value) const300     virtual bool getIntParam(OsiIntParam key, int& value) const {
301       if (key == OsiLastIntParam) return (false) ;
302       value = intParam_[key];
303       return true;
304     }
305     //! Get a double parameter
getDblParam(OsiDblParam key,double & value) const306     virtual bool getDblParam(OsiDblParam key, double& value) const {
307       if (key == OsiLastDblParam) return (false) ;
308       value = dblParam_[key];
309       return true;
310     }
311     //! Get a string parameter
getStrParam(OsiStrParam key,std::string & value) const312     virtual bool getStrParam(OsiStrParam key, std::string& value) const {
313       if (key == OsiLastStrParam) return (false) ;
314       value = strParam_[key];
315       return true;
316     }
317     /*! \brief Get a hint parameter (all information)
318 
319 	Return all available information for the hint: sense, strength,
320 	and any extra information associated with the hint.
321 
322 	Implementors: The default implementation will always set
323 	\c otherInformation to NULL. This is almost certainly not the
324 	behaviour you want; you really should override this method.
325     */
getHintParam(OsiHintParam key,bool & yesNo,OsiHintStrength & strength,void * & otherInformation) const326     virtual bool getHintParam(OsiHintParam key, bool& yesNo,
327 			      OsiHintStrength& strength,
328 			      void *& otherInformation) const {
329       if (key==OsiLastHintParam)
330 	return false;
331       yesNo = hintParam_[key];
332       strength = hintStrength_[key];
333       otherInformation=nullptr;
334       return true;
335     }
336     /*! \brief Get a hint parameter (sense and strength only)
337 
338 	Return only the sense and strength of the hint.
339     */
getHintParam(OsiHintParam key,bool & yesNo,OsiHintStrength & strength) const340     virtual bool getHintParam(OsiHintParam key, bool& yesNo,
341 			      OsiHintStrength& strength) const {
342       if (key==OsiLastHintParam)
343 	return false;
344       yesNo = hintParam_[key];
345       strength = hintStrength_[key];
346       return true;
347     }
348     /*! \brief Get a hint parameter (sense only)
349 
350 	Return only the sense (true/false) of the hint.
351     */
getHintParam(OsiHintParam key,bool & yesNo) const352     virtual bool getHintParam(OsiHintParam key, bool& yesNo) const {
353       if (key==OsiLastHintParam)
354 	return false;
355       yesNo = hintParam_[key];
356       return true;
357     }
358     /*! \brief Copy all parameters in this section from one solver to another
359 
360       Note that the current implementation also copies the appData block,
361       message handler, and rowCutDebugger. Arguably these should have
362       independent copy methods.
363     */
364     void copyParameters(OsiSolverInterface & rhs);
365 
366     /** \brief Return the integrality tolerance of the underlying solver.
367 
368 	We should be able to get an integrality tolerance, but
369         until that time just use the primal tolerance
370 
371 	\todo
372 	This method should be replaced; it's architecturally wrong.  This
373 	should be an honest dblParam with a keyword. Underlying solvers
374 	that do not support integer variables should return false for set and
375 	get on this parameter.  Underlying solvers that support integrality
376 	should add this to the parameters they support, using whatever
377 	tolerance is appropriate.  -lh, 091021-
378     */
getIntegerTolerance() const379     inline double getIntegerTolerance() const
380     { return dblParam_[OsiPrimalTolerance];}
381   //@}
382 
383   //---------------------------------------------------------------------------
384   ///@name Methods returning info on how the solution process terminated
385   //@{
386     /// Are there numerical difficulties?
387     virtual bool isAbandoned() const = 0;
388     /// Is optimality proven?
389     virtual bool isProvenOptimal() const = 0;
390     /// Is primal infeasibility proven?
391     virtual bool isProvenPrimalInfeasible() const = 0;
392     /// Is dual infeasibility proven?
393     virtual bool isProvenDualInfeasible() const = 0;
394     /// Is the given primal objective limit reached?
395     virtual bool isPrimalObjectiveLimitReached() const;
396     /// Is the given dual objective limit reached?
397     virtual bool isDualObjectiveLimitReached() const;
398     /// Iteration limit reached?
399     virtual bool isIterationLimitReached() const = 0;
400   //@}
401 
402   //---------------------------------------------------------------------------
403   /** \name Warm start methods
404 
405     Note that the warm start methods return a generic CoinWarmStart object.
406     The precise characteristics of this object are solver-dependent. Clients
407     who wish to maintain a maximum degree of solver independence should take
408     care to avoid unnecessary assumptions about the properties of a warm start
409     object.
410   */
411   //@{
412     /*! \brief Get an empty warm start object
413 
414       This routine returns an empty warm start object. Its purpose is
415       to provide a way for a client to acquire a warm start object of the
416       appropriate type for the solver, which can then be resized and modified
417       as desired.
418     */
419 
420     virtual CoinWarmStart *getEmptyWarmStart () const = 0 ;
421 
422     /** \brief Get warm start information.
423 
424       Return warm start information for the current state of the solver
425       interface. If there is no valid warm start information, an empty warm
426       start object wil be returned.
427     */
428     virtual CoinWarmStart* getWarmStart() const = 0;
429     /** \brief Get warm start information.
430 
431       Return warm start information for the current state of the solver
432       interface. If there is no valid warm start information, an empty warm
433       start object wil be returned.  This does not necessarily create an
434       object - may just point to one.  must Delete set true if user
435       should delete returned object.
436     */
437     virtual CoinWarmStart* getPointerToWarmStart(bool & mustDelete) ;
438 
439     /** \brief Set warm start information.
440 
441       Return true or false depending on whether the warm start information was
442       accepted or not.
443       By definition, a call to setWarmStart with a null parameter should
444       cause the solver interface to refresh its warm start information
445       from the underlying solver.
446    */
447     virtual bool setWarmStart(const CoinWarmStart* warmstart) = 0;
448   //@}
449 
450   //---------------------------------------------------------------------------
451   /**@name Hot start methods
452 
453      Primarily used in strong branching. The user can create a hot start
454      object --- a snapshot of the optimization process --- then reoptimize
455      over and over again, starting from the same point.
456 
457      \note
458      <ul>
459      <li> Between hot started optimizations only bound changes are allowed.
460      <li> The copy constructor and assignment operator should NOT copy any
461           hot start information.
462      <li> The default implementation simply extracts a warm start object in
463           \c markHotStart, resets to the warm start object in
464 	  \c solveFromHotStart, and deletes the warm start object in
465 	  \c unmarkHotStart.
466 	  <em>Actual solver implementations are encouraged to do better.</em>
467      </ul>
468 
469   */
470   //@{
471     /// Create a hot start snapshot of the optimization process.
472     virtual void markHotStart();
473     /// Optimize starting from the hot start snapshot.
474     virtual void solveFromHotStart();
475     /// Delete the hot start snapshot.
476     virtual void unmarkHotStart();
477   //@}
478 
479   //---------------------------------------------------------------------------
480   /**@name Problem query methods
481 
482    Querying a problem that has no data associated with it will result in
483    zeros for the number of rows and columns, and NULL pointers from the
484    methods that return vectors.
485 
486    Const pointers returned from any data-query method are valid as long as
487    the data is unchanged and the solver is not called.
488   */
489   //@{
490     /// Get the number of columns
491     virtual int getNumCols() const = 0;
492 
493     /// Get the number of rows
494     virtual int getNumRows() const = 0;
495 
496     /// Get the number of nonzero elements
497     virtual int getNumElements() const = 0;
498 
499     /// Get the number of integer variables
500     virtual int getNumIntegers() const ;
501 
502     /// Get a pointer to an array[getNumCols()] of column lower bounds
503     virtual const double * getColLower() const = 0;
504 
505     /// Get a pointer to an array[getNumCols()] of column upper bounds
506     virtual const double * getColUpper() const = 0;
507 
508     /*! \brief Get a pointer to an array[getNumRows()] of row constraint senses.
509 
510       <ul>
511       <li>'L': <= constraint
512       <li>'E': =  constraint
513       <li>'G': >= constraint
514       <li>'R': ranged constraint
515       <li>'N': free constraint
516       </ul>
517     */
518     virtual const char * getRowSense() const = 0;
519 
520     /*! \brief Get a pointer to an array[getNumRows()] of row right-hand sides
521 
522       <ul>
523 	<li> if getRowSense()[i] == 'L' then
524 	     getRightHandSide()[i] == getRowUpper()[i]
525 	<li> if getRowSense()[i] == 'G' then
526 	     getRightHandSide()[i] == getRowLower()[i]
527 	<li> if getRowSense()[i] == 'R' then
528 	     getRightHandSide()[i] == getRowUpper()[i]
529 	<li> if getRowSense()[i] == 'N' then
530 	     getRightHandSide()[i] == 0.0
531       </ul>
532     */
533     virtual const double * getRightHandSide() const = 0;
534 
535     /*! \brief Get a pointer to an array[getNumRows()] of row ranges.
536 
537       <ul>
538 	  <li> if getRowSense()[i] == 'R' then
539 		  getRowRange()[i] == getRowUpper()[i] - getRowLower()[i]
540 	  <li> if getRowSense()[i] != 'R' then
541 		  getRowRange()[i] is 0.0
542 	</ul>
543     */
544     virtual const double * getRowRange() const = 0;
545 
546     /// Get a pointer to an array[getNumRows()] of row lower bounds
547     virtual const double * getRowLower() const = 0;
548 
549     /// Get a pointer to an array[getNumRows()] of row upper bounds
550     virtual const double * getRowUpper() const = 0;
551 
552     /*! \brief Get a pointer to an array[getNumCols()] of objective
553 	       function coefficients.
554     */
555     virtual const double * getObjCoefficients() const = 0;
556 
557     /*! \brief Get the objective function sense
558 
559       -  1 for minimisation (default)
560       - -1 for maximisation
561     */
562     virtual double getObjSense() const = 0;
563 
564     /// Return true if the variable is continuous
565     virtual bool isContinuous(int colIndex) const = 0;
566 
567     /// Return true if the variable is binary
568     virtual bool isBinary(int colIndex) const;
569 
570     /*! \brief Return true if the variable is integer.
571 
572       This method returns true if the variable is binary or general integer.
573     */
574     virtual bool isInteger(int colIndex) const;
575 
576     /// Return true if the variable is general integer
577     virtual bool isIntegerNonBinary(int colIndex) const;
578 
579     /// Return true if the variable is binary and not fixed
580     virtual bool isFreeBinary(int colIndex) const;
581 
582     /*! \brief Return an array[getNumCols()] of column types
583 
584       \deprecated See #getColType
585     */
columnType(bool refresh=false) const586     inline const char *columnType(bool refresh=false) const
587     { return getColType(refresh); }
588 
589     /*! \brief Return an array[getNumCols()] of column types
590 
591        - 0 - continuous
592        - 1 - binary
593        - 2 - general integer
594 
595       If \p refresh is true, the classification of integer variables as
596       binary or general integer will be reevaluated. If the current bounds
597       are [0,1], or if the variable is fixed at 0 or 1, it will be classified
598       as binary, otherwise it will be classified as general integer.
599     */
600     virtual const char * getColType(bool refresh=false) const;
601 
602     /// Get a pointer to a row-wise copy of the matrix
603     virtual const CoinPackedMatrix * getMatrixByRow() const = 0;
604 
605     /// Get a pointer to a column-wise copy of the matrix
606     virtual const CoinPackedMatrix * getMatrixByCol() const = 0;
607 
608     /*! \brief Get a pointer to a mutable row-wise copy of the matrix.
609 
610       Returns NULL if the request is not meaningful (i.e., the OSI will not
611       recognise any modifications to the matrix).
612     */
getMutableMatrixByRow() const613     virtual CoinPackedMatrix * getMutableMatrixByRow() const {return nullptr;}
614 
615     /*! \brief Get a pointer to a mutable column-wise copy of the matrix
616 
617       Returns NULL if the request is not meaningful (i.e., the OSI will not
618       recognise any modifications to the matrix).
619     */
getMutableMatrixByCol() const620     virtual CoinPackedMatrix * getMutableMatrixByCol() const {return nullptr;}
621 
622     /// Get the solver's value for infinity
623     virtual double getInfinity() const = 0;
624   //@}
625 
626   /**@name Solution query methods */
627   //@{
628     /// Get a pointer to an array[getNumCols()] of primal variable values
629     virtual const double * getColSolution() const = 0;
630 
631     /** Get a pointer to an array[getNumCols()] of primal variable values
632 	guaranteed to be between the column lower and upper bounds.
633     */
634     virtual const double * getStrictColSolution();
635 
636     /// Get pointer to array[getNumRows()] of dual variable values
637     virtual const double * getRowPrice() const = 0;
638 
639     /// Get a pointer to an array[getNumCols()] of reduced costs
640     virtual const double * getReducedCost() const = 0;
641 
642     /** Get a pointer to array[getNumRows()] of row activity levels.
643 
644       The row activity for a row is the left-hand side evaluated at the
645       current solution.
646     */
647     virtual const double * getRowActivity() const = 0;
648 
649     /// Get the objective function value.
650     virtual double getObjValue() const = 0;
651 
652     /** Get the number of iterations it took to solve the problem (whatever
653 	`iteration' means to the solver).
654     */
655     virtual int getIterationCount() const = 0;
656 
657     /** Get as many dual rays as the solver can provide. In case of proven
658 	primal infeasibility there should (with high probability) be at least
659 	one.
660 
661 	The first getNumRows() ray components will always be associated with
662 	the row duals (as returned by getRowPrice()). If \c fullRay is true,
663 	the final getNumCols() entries will correspond to the ray components
664 	associated with the nonbasic variables. If the full ray is requested
665 	and the method cannot provide it, it will throw an exception.
666 
667 	\note
668 	Implementors of solver interfaces note that the double pointers in
669 	the vector should point to arrays of length getNumRows() (fullRay =
670 	false) or (getNumRows()+getNumCols()) (fullRay = true) and they should
671 	be allocated with new[].
672 
673 	\note
674 	Clients of solver interfaces note that it is the client's
675 	responsibility to free the double pointers in the vector using
676 	delete[]. Clients are reminded that a problem can be dual and primal
677 	infeasible.
678     */
679     virtual std::vector<double*> getDualRays(int maxNumRays,
680 					     bool fullRay = false) const = 0;
681 
682     /** Get as many primal rays as the solver can provide. In case of proven
683 	dual infeasibility there should (with high probability) be at least
684 	one.
685 
686 	\note
687 	Implementors of solver interfaces note that the double pointers in
688 	the vector should point to arrays of length getNumCols() and they
689 	should be allocated with new[].
690 
691 	\note
692 	Clients of solver interfaces note that it is the client's
693 	responsibility to free the double pointers in the vector using
694 	delete[]. Clients are reminded that a problem can be dual and primal
695 	infeasible.
696     */
697     virtual std::vector<double*> getPrimalRays(int maxNumRays) const = 0;
698 
699     /** Get vector of indices of primal variables which are integer variables
700 	but have fractional values in the current solution. */
701     virtual OsiVectorInt getFractionalIndices(const double etol=1.e-05)
702       const;
703   //@}
704 
705   //-------------------------------------------------------------------------
706   /**@name Methods to modify the objective, bounds, and solution
707 
708      For functions which take a set of indices as parameters
709      (\c setObjCoeffSet(), \c setColSetBounds(), \c setRowSetBounds(),
710      \c setRowSetTypes()), the parameters follow the C++ STL iterator
711      convention: \c indexFirst points to the first index in the
712      set, and \c indexLast points to a position one past the last index
713      in the set.
714 
715   */
716   //@{
717     /** Set an objective function coefficient */
718     virtual void setObjCoeff( int elementIndex, double elementValue ) = 0;
719 
720     /** Set a set of objective function coefficients */
721     virtual void setObjCoeffSet(const int* indexFirst,
722 				const int* indexLast,
723 				const double* coeffList);
724 
725     /** Set the objective coefficients for all columns.
726 
727 	array [getNumCols()] is an array of values for the objective.
728 	This defaults to a series of set operations and is here for speed.
729     */
730     virtual void setObjective(const double * array);
731 
732     /** Set the objective function sense.
733 
734         Use 1 for minimisation (default), -1 for maximisation.
735 
736 	\note
737 	Implementors note that objective function sense is a parameter of
738 	the OSI, not a property of the problem. Objective sense can be
739 	set prior to problem load and should not be affected by loading a
740 	new problem.
741     */
742     virtual void setObjSense(double s) = 0;
743 
744 
745     /** Set a single column lower bound.
746 	Use -getInfinity() for -infinity. */
747     virtual void setColLower( int elementIndex, double elementValue ) = 0;
748 
749     /** Set the lower bounds for all columns.
750 
751 	array [getNumCols()] is an array of values for the lower bounds.
752 	This defaults to a series of set operations and is here for speed.
753     */
754     virtual void setColLower(const double * array);
755 
756     /** Set a single column upper bound.
757 	Use getInfinity() for infinity. */
758     virtual void setColUpper( int elementIndex, double elementValue ) = 0;
759 
760     /** Set the upper bounds for all columns.
761 
762 	array [getNumCols()] is an array of values for the upper bounds.
763 	This defaults to a series of set operations and is here for speed.
764     */
765     virtual void setColUpper(const double * array);
766 
767 
768     /** Set a single column lower and upper bound.
769 	The default implementation just invokes setColLower() and
770 	setColUpper() */
setColBounds(int elementIndex,double lower,double upper)771     virtual void setColBounds( int elementIndex,
772 			       double lower, double upper ) {
773        setColLower(elementIndex, lower);
774        setColUpper(elementIndex, upper);
775     }
776 
777     /** Set the upper and lower bounds of a set of columns.
778 
779 	The default implementation just invokes setColBounds() over and over
780 	again.  For each column, boundList must contain both a lower and
781 	upper bound, in that order.
782     */
783     virtual void setColSetBounds(const int* indexFirst,
784 				 const int* indexLast,
785 				 const double* boundList);
786 
787     /** Set a single row lower bound.
788 	Use -getInfinity() for -infinity. */
789     virtual void setRowLower( int elementIndex, double elementValue ) = 0;
790 
791     /** Set a single row upper bound.
792 	Use getInfinity() for infinity. */
793     virtual void setRowUpper( int elementIndex, double elementValue ) = 0;
794 
795     /** Set a single row lower and upper bound.
796 	The default implementation just invokes setRowLower() and
797 	setRowUpper() */
setRowBounds(int elementIndex,double lower,double upper)798     virtual void setRowBounds( int elementIndex,
799 			       double lower, double upper ) {
800        setRowLower(elementIndex, lower);
801        setRowUpper(elementIndex, upper);
802     }
803 
804     /** Set the bounds on a set of rows.
805 
806 	The default implementation just invokes setRowBounds() over and over
807 	again.  For each row, boundList must contain both a lower and
808 	upper bound, in that order.
809     */
810     virtual void setRowSetBounds(const int* indexFirst,
811 				 const int* indexLast,
812 				 const double* boundList);
813 
814 
815     /** Set the type of a single row */
816     virtual void setRowType(int index, char sense, double rightHandSide,
817 			    double range) = 0;
818 
819     /** Set the type of a set of rows.
820 	The default implementation just invokes setRowType()
821 	over and over again.
822     */
823     virtual void setRowSetTypes(const int* indexFirst,
824 				const int* indexLast,
825 				const char* senseList,
826 				const double* rhsList,
827 				const double* rangeList);
828 
829     /** Set the primal solution variable values
830 
831 	colsol[getNumCols()] is an array of values for the primal variables.
832 	These values are copied to memory owned by the solver interface
833 	object or the solver.  They will be returned as the result of
834 	getColSolution() until changed by another call to setColSolution() or
835 	by a call to any solver routine.  Whether the solver makes use of the
836 	solution in any way is solver-dependent.
837     */
838     virtual void setColSolution(const double *colsol) = 0;
839 
840     /** Set dual solution variable values
841 
842 	rowprice[getNumRows()] is an array of values for the dual variables.
843 	These values are copied to memory owned by the solver interface
844 	object or the solver.  They will be returned as the result of
845 	getRowPrice() until changed by another call to setRowPrice() or by a
846 	call to any solver routine.  Whether the solver makes use of the
847 	solution in any way is solver-dependent.
848     */
849     virtual void setRowPrice(const double * rowprice) = 0;
850 
851     /** Fix variables at bound based on reduced cost
852 
853 	For variables currently at bound, fix the variable at bound if the
854 	reduced cost exceeds the gap. Return the number of variables fixed.
855 
856 	If justInteger is set to false, the routine will also fix continuous
857 	variables, but the test still assumes a delta of 1.0.
858     */
859     virtual int reducedCostFix(double gap, bool justInteger=true);
860   //@}
861 
862   //-------------------------------------------------------------------------
863   /**@name Methods to set variable type */
864   //@{
865     /** Set the index-th variable to be a continuous variable */
866     virtual void setContinuous(int index) = 0;
867     /** Set the index-th variable to be an integer variable */
868     virtual void setInteger(int index) = 0;
869     /** Set the variables listed in indices (which is of length len) to be
870 	continuous variables */
871     virtual void setContinuous(const int* indices, int len);
872     /** Set the variables listed in indices (which is of length len) to be
873 	integer variables */
874     virtual void setInteger(const int* indices, int len);
875   //@}
876   //-------------------------------------------------------------------------
877 
878   //-------------------------------------------------------------------------
879 
880     /*! \brief Data type for name vectors. */
881     typedef std::vector<std::string> OsiNameVec ;
882 
883   /*! \name Methods for row and column names
884 
885     Osi defines three name management disciplines: `auto names' (0), `lazy
886     names' (1), and `full names' (2). See the description of
887     #OsiNameDiscipline for details. Changing the name discipline (via
888     setIntParam()) will not automatically add or remove name information,
889     but setting the discipline to auto will make existing information
890     inaccessible until the discipline is reset to lazy or full.
891 
892     By definition, a row index of getNumRows() (<i>i.e.</i>, one larger than
893     the largest valid row index) refers to the objective function.
894 
895     OSI users and implementors: While the OSI base class can define an
896     interface and provide rudimentary support, use of names really depends
897     on support by the OsiXXX class to ensure that names are managed
898     correctly.  If an OsiXXX class does not support names, it should return
899     false for calls to getIntParam() or setIntParam() that reference
900     OsiNameDiscipline.
901   */
902   //@{
903 
904     /*! \brief Generate a standard name of the form Rnnnnnnn or Cnnnnnnn
905 
906       Set \p rc to 'r' for a row name, 'c' for a column name.
907       The `nnnnnnn' part is generated from ndx and will contain 7 digits
908       by default, padded with zeros if necessary. As a special case,
909       ndx = getNumRows() is interpreted as a request for the name of the
910       objective function. OBJECTIVE is returned, truncated to digits+1
911       characters to match the row and column names.
912     */
913     virtual std::string dfltRowColName(char rc,
914 				 int ndx, unsigned digits = 7) const ;
915 
916     /*! \brief Return the name of the objective function */
917 #pragma warning(suppress: 4309)
918   virtual std::string getObjName (unsigned maxLen = static_cast<unsigned>(std::string::npos)) const ;
919 
920     /*! \brief Set the name of the objective function */
921 
setObjName(std::string name)922     virtual inline void setObjName (std::string name)
923     { objName_ = name ; }
924 
925     /*! \brief Return the name of the row.
926 
927       The routine will <i>always</i> return some name, regardless of the name
928       discipline or the level of support by an OsiXXX derived class. Use
929       maxLen to limit the length.
930     */
931     virtual std::string getRowName(int rowIndex,
932 #pragma warning(suppress: 4309)
933 				   unsigned maxLen = static_cast<unsigned>(std::string::npos)) const ;
934 
935     /*! \brief Return a pointer to a vector of row names
936 
937       If the name discipline (#OsiNameDiscipline) is auto, the return value
938       will be a vector of length zero. If the name discipline is lazy, the
939       vector will contain only names supplied by the client and will be no
940       larger than needed to hold those names; entries not supplied will be
941       null strings. In particular, the objective name is <i>not</i>
942       included in the vector for lazy names. If the name discipline is
943       full, the vector will have getNumRows() names, either supplied or
944       generated, plus one additional entry for the objective name.
945     */
946     virtual const OsiNameVec &getRowNames() ;
947 
948     /*! \brief Set a row name
949 
950       Quietly does nothing if the name discipline (#OsiNameDiscipline) is
951       auto. Quietly fails if the row index is invalid.
952     */
953     virtual void setRowName(int ndx, std::string name) ;
954 
955     /*! \brief Set multiple row names
956 
957       The run of len entries starting at srcNames[srcStart] are installed as
958       row names starting at row index tgtStart. The base class implementation
959       makes repeated calls to setRowName.
960     */
961     virtual void setRowNames(OsiNameVec &srcNames,
962 		     int srcStart, int len, int tgtStart) ;
963 
964     /*! \brief Delete len row names starting at index tgtStart
965 
966       The specified row names are removed and the remaining row names are
967       copied down to close the gap.
968     */
969     virtual void deleteRowNames(int tgtStart, int len) ;
970 
971     /*! \brief Return the name of the column
972 
973       The routine will <i>always</i> return some name, regardless of the name
974       discipline or the level of support by an OsiXXX derived class. Use
975       maxLen to limit the length.
976     */
977     virtual std::string getColName(int colIndex,
978 #pragma warning(suppress: 4309)
979 				   unsigned maxLen = static_cast<unsigned>(std::string::npos)) const ;
980 
981     /*! \brief Return a pointer to a vector of column names
982 
983       If the name discipline (#OsiNameDiscipline) is auto, the return value
984       will be a vector of length zero. If the name discipline is lazy, the
985       vector will contain only names supplied by the client and will be no
986       larger than needed to hold those names; entries not supplied will be
987       null strings. If the name discipline is full, the vector will have
988       getNumCols() names, either supplied or generated.
989     */
990     virtual const OsiNameVec &getColNames() ;
991 
992     /*! \brief Set a column name
993 
994       Quietly does nothing if the name discipline (#OsiNameDiscipline) is
995       auto. Quietly fails if the column index is invalid.
996     */
997     virtual void setColName(int ndx, std::string name) ;
998 
999     /*! \brief Set multiple column names
1000 
1001       The run of len entries starting at srcNames[srcStart] are installed as
1002       column names starting at column index tgtStart. The base class
1003       implementation makes repeated calls to setColName.
1004     */
1005     virtual void setColNames(OsiNameVec &srcNames,
1006 		     int srcStart, int len, int tgtStart) ;
1007 
1008     /*! \brief Delete len column names starting at index tgtStart
1009 
1010       The specified column names are removed and the remaining column names
1011       are copied down to close the gap.
1012     */
1013     virtual void deleteColNames(int tgtStart, int len) ;
1014 
1015 
1016     /*! \brief Set row and column names from a CoinMpsIO object.
1017 
1018       Also sets the name of the objective function. If the name discipline
1019       is auto, you get what you asked for. This routine does not use
1020       setRowName or setColName.
1021     */
1022     void setRowColNames(const CoinMpsIO &mps) ;
1023 
1024     /*! \brief Set row and column names from a CoinModel object.
1025 
1026       If the name discipline is auto, you get what you asked for.
1027       This routine does not use setRowName or setColName.
1028     */
1029     void setRowColNames(CoinModel &mod) ;
1030 
1031     /*! \brief Set row and column names from a CoinLpIO object.
1032 
1033       Also sets the name of the objective function. If the name discipline is
1034       auto, you get what you asked for. This routine does not use setRowName
1035       or setColName.
1036     */
1037     void setRowColNames(CoinLpIO &mod) ;
1038 
1039   //@}
1040   //-------------------------------------------------------------------------
1041 
1042   //-------------------------------------------------------------------------
1043   /**@name Methods to modify the constraint system.
1044 
1045      Note that new columns are added as continuous variables.
1046   */
1047   //@{
1048 
1049     /** Add a column (primal variable) to the problem. */
1050     virtual void addCol(const CoinPackedVectorBase& vec,
1051 			const double collb, const double colub,
1052 			const double obj) = 0;
1053 
1054     /*! \brief Add a named column (primal variable) to the problem.
1055 
1056       The default implementation adds the column, then changes the name. This
1057       can surely be made more efficient within an OsiXXX class.
1058     */
1059     virtual void addCol(const CoinPackedVectorBase& vec,
1060 			const double collb, const double colub,
1061 			const double obj, std::string name) ;
1062 
1063     /** Add a column (primal variable) to the problem. */
1064     virtual void addCol(int numberElements,
1065 			const int* rows, const double* elements,
1066 			const double collb, const double colub,
1067 			const double obj) ;
1068 
1069     /*! \brief Add a named column (primal variable) to the problem.
1070 
1071       The default implementation adds the column, then changes the name. This
1072       can surely be made more efficient within an OsiXXX class.
1073     */
1074     virtual void addCol(int numberElements,
1075 			const int* rows, const double* elements,
1076 			const double collb, const double colub,
1077 			const double obj, std::string name) ;
1078 
1079     /** Add a set of columns (primal variables) to the problem.
1080 
1081       The default implementation simply makes repeated calls to
1082       addCol().
1083     */
1084     virtual void addCols(const int numcols,
1085 			 const CoinPackedVectorBase * const * cols,
1086 			 const double* collb, const double* colub,
1087 			 const double* obj);
1088 
1089     /** Add a set of columns (primal variables) to the problem.
1090 
1091       The default implementation simply makes repeated calls to
1092       addCol().
1093     */
1094     virtual void addCols(const int numcols, const int* columnStarts,
1095 			 const int* rows, const double* elements,
1096 			 const double* collb, const double* colub,
1097 			 const double* obj);
1098 
1099     /// Add columns using a CoinBuild object
1100     void addCols(const CoinBuild & buildObject);
1101 
1102     /** Add columns from a model object.  returns
1103        -1 if object in bad state (i.e. has row information)
1104        otherwise number of errors
1105        modelObject non const as can be regularized as part of build
1106     */
1107     int addCols(CoinModel & modelObject);
1108 
1109 #if 0
1110     /** */
1111     virtual void addCols(const CoinPackedMatrix& matrix,
1112 			 const double* collb, const double* colub,
1113 			 const double* obj);
1114 #endif
1115 
1116     /** \brief Remove a set of columns (primal variables) from the
1117 	       problem.
1118 
1119       The solver interface for a basis-oriented solver will maintain valid
1120       warm start information if all deleted variables are nonbasic.
1121     */
1122     virtual void deleteCols(const int num, const int * colIndices) = 0;
1123 
1124     /*! \brief Add a row (constraint) to the problem. */
1125     virtual void addRow(const CoinPackedVectorBase& vec,
1126 			const double rowlb, const double rowub) = 0;
1127 
1128     /*! \brief Add a named row (constraint) to the problem.
1129 
1130       The default implementation adds the row, then changes the name. This
1131       can surely be made more efficient within an OsiXXX class.
1132     */
1133     virtual void addRow(const CoinPackedVectorBase& vec,
1134 			const double rowlb, const double rowub,
1135 			std::string name) ;
1136 
1137     /*! \brief Add a row (constraint) to the problem. */
1138     virtual void addRow(const CoinPackedVectorBase& vec,
1139 			const char rowsen, const double rowrhs,
1140 			const double rowrng) = 0;
1141 
1142     /*! \brief Add a named row (constraint) to the problem.
1143 
1144       The default implementation adds the row, then changes the name. This
1145       can surely be made more efficient within an OsiXXX class.
1146     */
1147     virtual void addRow(const CoinPackedVectorBase& vec,
1148 			const char rowsen, const double rowrhs,
1149 			const double rowrng, std::string name) ;
1150 
1151     /*! Add a row (constraint) to the problem.
1152 
1153       Converts to addRow(CoinPackedVectorBase&,const double,const double).
1154     */
1155     virtual void addRow(int numberElements,
1156 			const int *columns, const double *element,
1157 			const double rowlb, const double rowub) ;
1158 
1159     /*! Add a set of rows (constraints) to the problem.
1160 
1161       The default implementation simply makes repeated calls to
1162       addRow().
1163     */
1164     virtual void addRows(const int numrows,
1165 			 const CoinPackedVectorBase * const * rows,
1166 			 const double* rowlb, const double* rowub);
1167 
1168     /** Add a set of rows (constraints) to the problem.
1169 
1170       The default implementation simply makes repeated calls to
1171       addRow().
1172     */
1173     virtual void addRows(const int numrows,
1174 			 const CoinPackedVectorBase * const * rows,
1175 			 const char* rowsen, const double* rowrhs,
1176 			 const double* rowrng);
1177 
1178     /** Add a set of rows (constraints) to the problem.
1179 
1180       The default implementation simply makes repeated calls to
1181       addRow().
1182     */
1183     virtual void addRows(const int numrows, const int *rowStarts,
1184 			 const int *columns, const double *element,
1185 			 const double *rowlb, const double *rowub);
1186 
1187     /// Add rows using a CoinBuild object
1188     void addRows(const CoinBuild &buildObject);
1189 
1190     /*! Add rows from a CoinModel object.
1191 
1192       Returns -1 if the object is in the wrong state (<i>i.e.</i>, has
1193       column-major information), otherwise the number of errors.
1194 
1195       The modelObject is not const as it can be regularized as part of
1196       the build.
1197     */
1198     int addRows(CoinModel &modelObject);
1199 
1200 #if 0
1201     /** */
1202     virtual void addRows(const CoinPackedMatrix& matrix,
1203 			 const double* rowlb, const double* rowub);
1204     /** */
1205     virtual void addRows(const CoinPackedMatrix& matrix,
1206 			 const char* rowsen, const double* rowrhs,
1207 			 const double* rowrng);
1208 #endif
1209 
1210     /** \brief Delete a set of rows (constraints) from the problem.
1211 
1212       The solver interface for a basis-oriented solver will maintain valid
1213       warm start information if all deleted rows are loose.
1214     */
1215     virtual void deleteRows(const int num, const int * rowIndices) = 0;
1216 
1217     /** \brief Replace the constraint matrix
1218 
1219       I (JJF) am getting annoyed because I can't just replace a matrix.
1220       The default behavior of this is do nothing so only use where that would
1221       not matter, e.g. strengthening a matrix for MIP.
1222     */
replaceMatrixOptional(const CoinPackedMatrix &)1223     virtual void replaceMatrixOptional(const CoinPackedMatrix & ) {}
1224 
1225     /** \brief Replace the constraint matrix
1226 
1227       And if it does matter (not used at present)
1228     */
replaceMatrix(const CoinPackedMatrix &)1229     virtual void replaceMatrix(const CoinPackedMatrix & ) {abort();}
1230 
1231     /** \brief Save a copy of the base model
1232 
1233       If solver wants it can save a copy of "base" (continuous) model here.
1234     */
saveBaseModel()1235     virtual void saveBaseModel() {}
1236 
1237     /** \brief Reduce the constraint system to the specified number of
1238     	       constraints.
1239 
1240        If solver wants it can restore a copy of "base" (continuous) model
1241        here.
1242 
1243        \note
1244        The name is somewhat misleading. Implementors should consider
1245        the opportunity to optimise behaviour in the common case where
1246        \p numberRows is exactly the number of original constraints. Do not,
1247        however, neglect the possibility that \p numberRows does not equal
1248        the number of original constraints.
1249      */
1250     virtual void restoreBaseModel(int numberRows);
1251     //-----------------------------------------------------------------------
1252     /** Apply a collection of cuts.
1253 
1254 	Only cuts which have an <code>effectiveness >= effectivenessLb</code>
1255 	are applied.
1256 	<ul>
1257 	  <li> ReturnCode.getNumineffective() -- number of cuts which were
1258 	       not applied because they had an
1259 	       <code>effectiveness < effectivenessLb</code>
1260 	  <li> ReturnCode.getNuminconsistent() -- number of invalid cuts
1261 	  <li> ReturnCode.getNuminconsistentWrtIntegerModel() -- number of
1262 	       cuts that are invalid with respect to this integer model
1263 	  <li> ReturnCode.getNuminfeasible() -- number of cuts that would
1264 	       make this integer model infeasible
1265 	  <li> ReturnCode.getNumApplied() -- number of integer cuts which
1266 	       were applied to the integer model
1267 	  <li> cs.size() == getNumineffective() +
1268 			    getNuminconsistent() +
1269 			    getNuminconsistentWrtIntegerModel() +
1270 			    getNuminfeasible() +
1271 			    getNumApplied()
1272 	</ul>
1273     */
1274     virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs,
1275 					  double effectivenessLb = 0.0);
1276 
1277     /** Apply a collection of row cuts which are all effective.
1278 	applyCuts seems to do one at a time which seems inefficient.
1279 	Would be even more efficient to pass an array of pointers.
1280     */
1281     virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts);
1282 
1283     /** Apply a collection of row cuts which are all effective.
1284 	This is passed in as an array of pointers.
1285     */
1286     virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts);
1287 
1288     /// Deletes branching information before columns deleted
1289     void deleteBranchingInfo(int numberDeleted, const int * which);
1290 
1291   //@}
1292 
1293   //---------------------------------------------------------------------------
1294 
1295   /**@name Methods for problem input and output */
1296   //@{
1297     /*! \brief Load in a problem by copying the arguments. The constraints on
1298 	    the rows are given by lower and upper bounds.
1299 
1300 	If a pointer is 0 then the following values are the default:
1301         <ul>
1302           <li> <code>colub</code>: all columns have upper bound infinity
1303           <li> <code>collb</code>: all columns have lower bound 0
1304           <li> <code>rowub</code>: all rows have upper bound infinity
1305           <li> <code>rowlb</code>: all rows have lower bound -infinity
1306 	  <li> <code>obj</code>: all variables have 0 objective coefficient
1307         </ul>
1308 
1309 	Note that the default values for rowub and rowlb produce the
1310 	constraint -infty <= ax <= infty. This is probably not what you want.
1311     */
1312     virtual void loadProblem (const CoinPackedMatrix& matrix,
1313 			      const double* collb, const double* colub,
1314 			      const double* obj,
1315 			      const double* rowlb, const double* rowub) = 0;
1316 
1317     /*! \brief Load in a problem by assuming ownership of the arguments.
1318 	    The constraints on the rows are given by lower and upper bounds.
1319 
1320 	For default argument values see the matching loadProblem method.
1321 
1322 	\warning
1323 	The arguments passed to this method will be freed using the
1324 	C++ <code>delete</code> and <code>delete[]</code> functions.
1325     */
1326     virtual void assignProblem (CoinPackedMatrix*& matrix,
1327 			        double*& collb, double*& colub, double*& obj,
1328 			        double*& rowlb, double*& rowub) = 0;
1329 
1330     /*! \brief Load in a problem by copying the arguments.
1331 	    The constraints on the rows are given by sense/rhs/range triplets.
1332 
1333 	If a pointer is 0 then the following values are the default:
1334 	<ul>
1335           <li> <code>colub</code>: all columns have upper bound infinity
1336           <li> <code>collb</code>: all columns have lower bound 0
1337 	  <li> <code>obj</code>: all variables have 0 objective coefficient
1338           <li> <code>rowsen</code>: all rows are >=
1339           <li> <code>rowrhs</code>: all right hand sides are 0
1340           <li> <code>rowrng</code>: 0 for the ranged rows
1341         </ul>
1342 
1343 	Note that the default values for rowsen, rowrhs, and rowrng produce the
1344 	constraint ax >= 0.
1345     */
1346     virtual void loadProblem (const CoinPackedMatrix& matrix,
1347 			      const double* collb, const double* colub,
1348 			      const double* obj,
1349 			      const char* rowsen, const double* rowrhs,
1350 			      const double* rowrng) = 0;
1351 
1352     /*! \brief Load in a problem by assuming ownership of the arguments.
1353 	    The constraints on the rows are given by sense/rhs/range triplets.
1354 
1355 	For default argument values see the matching loadProblem method.
1356 
1357 	\warning
1358 	The arguments passed to this method will be freed using the
1359 	C++ <code>delete</code> and <code>delete[]</code> functions.
1360     */
1361     virtual void assignProblem (CoinPackedMatrix*& matrix,
1362 			        double*& collb, double*& colub, double*& obj,
1363 			        char*& rowsen, double*& rowrhs,
1364 			        double*& rowrng) = 0;
1365 
1366     /*! \brief Load in a problem by copying the arguments. The constraint
1367 	    matrix is is specified with standard column-major
1368 	    column starts / row indices / coefficients vectors.
1369 	    The constraints on the rows are given by lower and upper bounds.
1370 
1371       The matrix vectors must be gap-free. Note that <code>start</code> must
1372       have <code>numcols+1</code> entries so that the length of the last column
1373       can be calculated as <code>start[numcols]-start[numcols-1]</code>.
1374 
1375       See the previous loadProblem method using rowlb and rowub for default
1376       argument values.
1377     */
1378     virtual void loadProblem (const int numcols, const int numrows,
1379 			      const CoinBigIndex * start, const int* index,
1380 			      const double* value,
1381 			      const double* collb, const double* colub,
1382 			      const double* obj,
1383 			      const double* rowlb, const double* rowub) = 0;
1384 
1385     /*! \brief Load in a problem by copying the arguments. The constraint
1386 	    matrix is is specified with standard column-major
1387 	    column starts / row indices / coefficients vectors.
1388 	    The constraints on the rows are given by sense/rhs/range triplets.
1389 
1390       The matrix vectors must be gap-free. Note that <code>start</code> must
1391       have <code>numcols+1</code> entries so that the length of the last column
1392       can be calculated as <code>start[numcols]-start[numcols-1]</code>.
1393 
1394       See the previous loadProblem method using sense/rhs/range for default
1395       argument values.
1396     */
1397     virtual void loadProblem (const int numcols, const int numrows,
1398 			      const CoinBigIndex * start, const int* index,
1399 			      const double* value,
1400 			      const double* collb, const double* colub,
1401 			      const double* obj,
1402 			      const char* rowsen, const double* rowrhs,
1403   			      const double* rowrng) = 0;
1404 
1405     /*! \brief Load a model from a CoinModel object. Return the number of
1406 	    errors encountered.
1407 
1408       The modelObject parameter cannot be const as it may be changed as part
1409       of process. If keepSolution is true will try and keep warmStart.
1410     */
1411     virtual int loadFromCoinModel (CoinModel & modelObject,
1412 				   bool keepSolution=false);
1413 
1414     /*! \brief Read a problem in MPS format from the given filename.
1415 
1416       The default implementation uses CoinMpsIO::readMps() to read
1417       the MPS file and returns the number of errors encountered.
1418     */
1419     virtual int readMps (const char *filename,
1420 			 const char *extension = "mps") ;
1421 
1422     /*! \brief Read a problem in MPS format from the given full filename.
1423 
1424       This uses CoinMpsIO::readMps() to read the MPS file and returns the
1425       number of errors encountered. It also may return an array of set
1426       information
1427     */
1428     virtual int readMps (const char *filename, const char*extension,
1429 			int & numberSets, CoinSet ** & sets);
1430 
1431     /*! \brief Read a problem in GMPL format from the given filenames.
1432 
1433       The default implementation uses CoinMpsIO::readGMPL(). This capability
1434       is available only if the third-party package Glpk is installed.
1435     */
1436     virtual int readGMPL (const char *filename, const char *dataname=nullptr);
1437 
1438     /*! \brief Write the problem in MPS format to the specified file.
1439 
1440       If objSense is non-zero, a value of -1.0 causes the problem to be
1441       written with a maximization objective; +1.0 forces a minimization
1442       objective. If objSense is zero, the choice is left to the implementation.
1443     */
1444     virtual void writeMps (const char *filename,
1445 			   const char *extension = "mps",
1446 			   double objSense=0.0) const = 0;
1447 
1448     /*! \brief Write the problem in MPS format to the specified file with
1449 	    more control over the output.
1450 
1451 	Row and column names may be null.
1452 	formatType is
1453 	<ul>
1454 	  <li> 0 - normal
1455 	  <li> 1 - extra accuracy
1456 	  <li> 2 - IEEE hex
1457 	</ul>
1458 
1459 	Returns non-zero on I/O error
1460     */
1461     int writeMpsNative (const char *filename,
1462 		        const char ** rowNames, const char ** columnNames,
1463 		        int formatType=0,int numberAcross=2,
1464 		        double objSense=0.0, int numberSOS=0,
1465 		        const CoinSet * setInfo=nullptr) const ;
1466 
1467 /***********************************************************************/
1468 // Lp files
1469 
1470   /** Write the problem into an Lp file of the given filename with the
1471       specified extension.
1472       Coefficients with value less than epsilon away from an integer value
1473       are written as integers.
1474       Write at most numberAcross monomials on a line.
1475       Write non integer numbers with decimals digits after the decimal point.
1476 
1477       The written problem is always a minimization problem.
1478       If the current problem is a maximization problem, the
1479       intended objective function for the written problem is the current
1480       objective function multiplied by -1. If the current problem is a
1481       minimization problem, the intended objective function for the
1482       written problem is the current objective function.
1483       If objSense < 0, the intended objective function is multiplied by -1
1484       before writing the problem. It is left unchanged otherwise.
1485 
1486       Write objective function name and constraint names if useRowNames is
1487       true. This version calls writeLpNative().
1488   */
1489   virtual void writeLp(const char *filename,
1490                const char *extension = "lp",
1491                 double epsilon = 1e-5,
1492                 int numberAcross = 10,
1493                 int decimals = 5,
1494                 double objSense = 0.0,
1495 	        bool useRowNames = true) const;
1496 
1497   /** Write the problem into the file pointed to by the parameter fp.
1498       Other parameters are similar to
1499       those of writeLp() with first parameter filename.
1500   */
1501   virtual void writeLp(FILE *fp,
1502                 double epsilon = 1e-5,
1503                 int numberAcross = 10,
1504                 int decimals = 5,
1505                 double objSense = 0.0,
1506 	        bool useRowNames = true) const;
1507 
1508   /** Write the problem into an Lp file. Parameters are similar to
1509       those of writeLp(), but in addition row names and column names
1510       may be given.
1511 
1512       Parameter rowNames may be NULL, in which case default row names
1513       are used. If rowNames is not NULL, it must have exactly one entry
1514       per row in the problem and one additional
1515       entry (rowNames[getNumRows()] with the objective function name.
1516       These getNumRows()+1 entries must be distinct. If this is not the
1517       case, default row names
1518       are used. In addition, format restrictions are imposed on names
1519       (see CoinLpIO::is_invalid_name() for details).
1520 
1521       Similar remarks can be made for the parameter columnNames which
1522       must either be NULL or have exactly getNumCols() distinct entries.
1523 
1524       Write objective function name and constraint names if
1525       useRowNames is true. */
1526   int writeLpNative(const char *filename,
1527 		    char const * const * const rowNames,
1528 		    char const * const * const columnNames,
1529 		    const double epsilon = 1.0e-5,
1530                     const int numberAcross = 10,
1531                     const int decimals = 5,
1532                     const double objSense = 0.0,
1533 		    const bool useRowNames = true) const;
1534 
1535   /** Write the problem into the file pointed to by the parameter fp.
1536       Other parameters are similar to
1537       those of writeLpNative() with first parameter filename.
1538   */
1539   int writeLpNative(FILE *fp,
1540 		    char const * const * const rowNames,
1541 		    char const * const * const columnNames,
1542 		    const double epsilon = 1.0e-5,
1543                     const int numberAcross = 10,
1544                     const int decimals = 5,
1545                     const double objSense = 0.0,
1546 		    const bool useRowNames = true) const;
1547 
1548   /// Read file in LP format from file with name filename.
1549   /// See class CoinLpIO for description of this format.
1550   virtual int readLp(const char *filename, const double epsilon = 1e-5);
1551 
1552   /// Read file in LP format from the file pointed to by fp.
1553   /// See class CoinLpIO for description of this format.
1554   int readLp(FILE *fp, const double epsilon = 1e-5);
1555 
1556   //@}
1557 
1558   //---------------------------------------------------------------------------
1559 
1560   /**@name Miscellaneous */
1561   //@{
1562 #ifdef COIN_SNAPSHOT
1563   /// Return a CoinSnapshot
1564   virtual CoinSnapshot * snapshot(bool createArrays=true) const;
1565 #endif
1566 #ifdef COIN_FACTORIZATION_INFO
1567   /// Return number of entries in L part of current factorization
1568   virtual CoinBigIndex getSizeL() const;
1569   /// Return number of entries in U part of current factorization
1570   virtual CoinBigIndex getSizeU() const;
1571 #endif
1572   //@}
1573 
1574   //---------------------------------------------------------------------------
1575 
1576   /**@name Setting/Accessing application data */
1577   //@{
1578     /** Set application data.
1579 
1580 	This is a pointer that the application can store into and
1581 	retrieve from the solver interface.
1582 	This field is available for the application to optionally
1583 	define and use.
1584     */
1585     void setApplicationData (void * appData);
1586     /** Create a clone of an Auxiliary Information object.
1587         The base class just stores an application data pointer
1588         but can be more general.  Application data pointer is
1589         designed for one user while this can be extended to cope
1590         with more general extensions.
1591     */
1592     void setAuxiliaryInfo(OsiAuxInfo * auxiliaryInfo);
1593 
1594     /// Get application data
1595     void * getApplicationData() const;
1596     /// Get pointer to auxiliary info object
1597     OsiAuxInfo * getAuxiliaryInfo() const;
1598   //@}
1599   //---------------------------------------------------------------------------
1600 
1601   /**@name Message handling
1602 
1603     See the COIN library documentation for additional information about
1604     COIN message facilities.
1605 
1606   */
1607   //@{
1608   /** Pass in a message handler
1609 
1610     It is the client's responsibility to destroy a message handler installed
1611     by this routine; it will not be destroyed when the solver interface is
1612     destroyed.
1613   */
1614   virtual void passInMessageHandler(CoinMessageHandler * handler);
1615   /// Set language
1616   void newLanguage(CoinMessages::Language language);
setLanguage(CoinMessages::Language language)1617   inline void setLanguage(CoinMessages::Language language)
1618   {newLanguage(language);}
1619   /// Return a pointer to the current message handler
messageHandler() const1620   inline CoinMessageHandler * messageHandler() const
1621   {return handler_;}
1622   /// Return the current set of messages
messages()1623   inline CoinMessages messages()
1624   {return messages_;}
1625   /// Return a pointer to the current set of messages
messagesPointer()1626   inline CoinMessages * messagesPointer()
1627   {return &messages_;}
1628   /// Return true if default handler
defaultHandler() const1629   inline bool defaultHandler() const
1630   { return defaultHandler_;}
1631   //@}
1632   //---------------------------------------------------------------------------
1633   /**@name Methods for dealing with discontinuities other than integers.
1634 
1635      Osi should be able to know about SOS and other types.  This is an optional
1636      section where such information can be stored.
1637 
1638   */
1639   //@{
1640     /** \brief Identify integer variables and create corresponding objects.
1641 
1642       Record integer variables and create an OsiSimpleInteger object for each
1643       one.  All existing OsiSimpleInteger objects will be destroyed.
1644       If justCount then no objects created and we just store numberIntegers_
1645     */
1646 
1647     void findIntegers(bool justCount);
1648     /** \brief Identify integer variables and SOS and create corresponding objects.
1649 
1650       Record integer variables and create an OsiSimpleInteger object for each
1651       one.  All existing OsiSimpleInteger objects will be destroyed.
1652       If the solver supports SOS then do the same for SOS.
1653 
1654       If justCount then no objects created and we just store numberIntegers_
1655       Returns number of SOS
1656     */
1657 
1658     virtual int findIntegersAndSOS(bool justCount);
1659     /// Get the number of objects
numberObjects() const1660     inline int numberObjects() const { return numberObjects_;}
1661     /// Set the number of objects
setNumberObjects(int number)1662     inline void setNumberObjects(int number)
1663     {  numberObjects_=number;}
1664 
1665     /// Get the array of objects
objects() const1666     inline OsiObject ** objects() const { return object_;}
1667 
1668     /// Get the specified object
object(int which) const1669     const inline OsiObject * object(int which) const { return object_[which];}
1670     /// Get the specified object
modifiableObject(int which) const1671     inline OsiObject * modifiableObject(int which) const { return object_[which];}
1672 
1673     /// Delete all object information
1674     void deleteObjects();
1675 
1676     /** Add in object information.
1677 
1678       Objects are cloned; the owner can delete the originals.
1679     */
1680     void addObjects(int numberObjects, OsiObject ** objects);
1681     /** Use current solution to set bounds so current integer feasible solution will stay feasible.
1682         Only feasible bounds will be used, even if current solution outside bounds.  The amount of
1683         such violation will be returned (and if small can be ignored)
1684     */
1685     double forceFeasible();
1686   //@}
1687   //---------------------------------------------------------------------------
1688 
1689   /*! @name Methods related to testing generated cuts
1690 
1691     See the documentation for OsiRowCutDebugger for additional details.
1692   */
1693   //@{
1694     /*! \brief Activate the row cut debugger.
1695 
1696       If \p modelName is in the set of known models then all cuts are
1697       checked to see that they do NOT cut off the optimal solution known
1698       to the debugger.
1699     */
1700     virtual void activateRowCutDebugger (const char *modelName);
1701 
1702     /*! \brief Activate the row cut debugger using a full solution array.
1703 
1704 
1705       Activate the debugger for a model not included in the debugger's
1706       internal database.  Cuts will be checked to see that they do NOT
1707       cut off the given solution.
1708 
1709       \p solution must be a full solution vector, but only the integer
1710       variables need to be correct. The debugger will fill in the continuous
1711       variables by solving an lp relaxation with the integer variables
1712       fixed as specified. If the given values for the continuous variables
1713       should be preserved, set \p keepContinuous to true.
1714     */
1715     virtual void activateRowCutDebugger(const double *solution,
1716     					bool enforceOptimality = true);
1717 
1718     /*! \brief Get the row cut debugger provided the solution known to the
1719     	       debugger is within the feasible region held in the solver.
1720 
1721       If there is a row cut debugger object associated with model AND if
1722       the solution known to the debugger is within the solver's current
1723       feasible region (i.e., the column bounds held in the solver are
1724       compatible with the known solution) then a pointer to the debugger
1725       is returned which may be used to test validity of cuts.
1726 
1727       Otherwise NULL is returned
1728     */
1729     const OsiRowCutDebugger *getRowCutDebugger() const;
1730 
1731     /*! \brief Get the row cut debugger object
1732 
1733       Return the row cut debugger object if it exists. One common usage of
1734       this method is to obtain a debugger object in order to execute
1735       OsiRowCutDebugger::redoSolution (so that the stored solution is again
1736       compatible with the problem held in the solver).
1737     */
1738     OsiRowCutDebugger * getRowCutDebuggerAlways() const;
1739   //@}
1740 
1741   /*! \name OsiSimplexInterface
1742       \brief Simplex Interface
1743 
1744     Methods for an advanced interface to a simplex solver. The interface
1745     comprises two groups of methods. Group 1 contains methods for tableau
1746     access. Group 2 contains methods for dictating individual simplex pivots.
1747   */
1748   //@{
1749 
1750   /*! \brief Return the simplex implementation level.
1751 
1752       The return codes are:
1753       - 0: the simplex interface is not implemented.
1754       - 1: the Group 1 (tableau access) methods are implemented.
1755       - 2: the Group 2 (pivoting) methods are implemented
1756 
1757       The codes are cumulative - a solver which implements Group 2 also
1758       implements Group 1.
1759   */
1760   virtual int canDoSimplexInterface() const ;
1761   //@}
1762 
1763   /*! \name OsiSimplex Group 1
1764       \brief Tableau access methods.
1765 
1766       This group of methods provides access to rows and columns of the basis
1767       inverse and to rows and columns of the tableau.
1768   */
1769   //@{
1770 
1771   /*! \brief Prepare the solver for the use of tableau access methods.
1772 
1773     Prepares the solver for the use of the tableau access methods, if
1774     any such preparation is required.
1775 
1776     The \c const attribute is required due to the places this method
1777     may be called (e.g., within CglCutGenerator::generateCuts()).
1778   */
1779   virtual void enableFactorization() const ;
1780 
1781   /*! \brief Undo the effects of #enableFactorization. */
1782   virtual void disableFactorization() const ;
1783 
1784   /*! \brief Check if an optimal basis is available.
1785 
1786     Returns true if the problem has been solved to optimality and a
1787     basis is available. This should be used to see if the tableau access
1788     operations are possible and meaningful.
1789 
1790     \note
1791     Implementors please note that this method may be called
1792     before #enableFactorization.
1793   */
1794   virtual bool basisIsAvailable() const ;
1795 
1796   /// Synonym for #basisIsAvailable
optimalBasisIsAvailable() const1797   inline bool optimalBasisIsAvailable() const { return basisIsAvailable() ; }
1798 
1799   /*! \brief Retrieve status information for column and row variables.
1800 
1801     This method returns status as integer codes:
1802     <ul>
1803       <li> 0: free
1804       <li> 1: basic
1805       <li> 2: nonbasic at upper bound
1806       <li> 3: nonbasic at lower bound
1807     </ul>
1808 
1809     The #getWarmStart method provides essentially the same functionality
1810     for a simplex-oriented solver, but the implementation details are very
1811     different.
1812 
1813     \note
1814     Logical variables associated with rows are all assumed to have +1
1815     coefficients, so for a <= constraint the logical will be at lower
1816     bound if the constraint is tight.
1817 
1818     \note
1819     Implementors may choose to implement this method as a wrapper which
1820     converts a CoinWarmStartBasis to the requested representation.
1821   */
1822   virtual void getBasisStatus(int* cstat, int* rstat) const ;
1823 
1824   /*! \brief Set the status of column and row variables and update
1825              the basis factorization and solution.
1826 
1827     Status information should be coded as documented for #getBasisStatus.
1828     Returns 0 if all goes well, 1 if something goes wrong.
1829 
1830     This method differs from #setWarmStart in the format of the input
1831     and in its immediate effect. Think of it as #setWarmStart immediately
1832     followed by #resolve, but no pivots are allowed.
1833 
1834     \note
1835     Implementors may choose to implement this method as a wrapper that calls
1836     #setWarmStart and #resolve if the no pivot requirement can be satisfied.
1837   */
1838   virtual int setBasisStatus(const int* cstat, const int* rstat) ;
1839 
1840   /*! \brief Calculate duals and reduced costs for the given objective
1841 	     coefficients.
1842 
1843     The solver's objective coefficient vector is not changed.
1844   */
1845   virtual void getReducedGradient(double* columnReducedCosts,
1846 				  double* duals, const double* c) const ;
1847 
1848   /*! \brief Get a row of the tableau
1849 
1850     If \p slack is not null, it will be loaded with the coefficients for
1851     the artificial (logical) variables (i.e., the row of the basis inverse).
1852   */
1853   virtual void getBInvARow(int row, double* z, double* slack = nullptr) const ;
1854 
1855   /*! \brief Get a row of the basis inverse */
1856   virtual void getBInvRow(int row, double* z) const ;
1857 
1858   /*! \brief Get a column of the tableau */
1859   virtual void getBInvACol(int col, double* vec) const ;
1860 
1861   /*! \brief Get a column of the basis inverse */
1862   virtual void getBInvCol(int col, double* vec) const ;
1863 
1864   /*! \brief Get indices of basic variables
1865 
1866     If the logical (artificial) for row i is basic, the index should be coded
1867     as (#getNumCols + i).
1868     The order of indices must match the order of elements in the vectors
1869     returned by #getBInvACol and #getBInvCol.
1870   */
1871   virtual void getBasics(int* index) const ;
1872 
1873   //@}
1874 
1875   /*! \name OsiSimplex Group 2
1876       \brief Pivoting methods
1877 
1878       This group of methods provides for control of individual pivots by a
1879       simplex solver.
1880   */
1881   //@{
1882 
1883   /**Enables normal operation of subsequent functions.
1884      This method is supposed to ensure that all typical things (like
1885      reduced costs, etc.) are updated when individual pivots are executed
1886      and can be queried by other methods.  says whether will be
1887      doing primal or dual
1888   */
1889   virtual void enableSimplexInterface(bool doingPrimal) ;
1890 
1891   ///Undo whatever setting changes the above method had to make
1892   virtual void disableSimplexInterface() ;
1893   /** Perform a pivot by substituting a colIn for colOut in the basis.
1894      The status of the leaving variable is given in outStatus. Where
1895      1 is to upper bound, -1 to lower bound
1896      Return code was undefined - now for OsiClp is 0 for okay,
1897      1 if inaccuracy forced re-factorization (should be okay) and
1898      -1 for singular factorization
1899   */
1900   virtual int pivot(int colIn, int colOut, int outStatus) ;
1901 
1902   /** Obtain a result of the primal pivot
1903       Outputs: colOut -- leaving column, outStatus -- its status,
1904       t -- step size, and, if dx!=NULL, *dx -- primal ray direction.
1905       Inputs: colIn -- entering column, sign -- direction of its change (+/-1).
1906       Both for colIn and colOut, artificial variables are index by
1907       the negative of the row index minus 1.
1908       Return code (for now): 0 -- leaving variable found,
1909       -1 -- everything else?
1910       Clearly, more informative set of return values is required
1911       Primal and dual solutions are updated
1912   */
1913   virtual int primalPivotResult(int colIn, int sign,
1914 				int& colOut, int& outStatus,
1915 				double& t, CoinPackedVector* dx);
1916 
1917   /** Obtain a result of the dual pivot (similar to the previous method)
1918       Differences: entering variable and a sign of its change are now
1919       the outputs, the leaving variable and its statuts -- the inputs
1920       If dx!=NULL, then *dx contains dual ray
1921       Return code: same
1922   */
1923   virtual int dualPivotResult(int& colIn, int& sign,
1924 			      int colOut, int outStatus,
1925 			      double& t, CoinPackedVector* dx) ;
1926   //@}
1927 
1928   //---------------------------------------------------------------------------
1929 
1930   ///@name Constructors and destructors
1931   //@{
1932     /// Default Constructor
1933     OsiSolverInterface();
1934 
1935     /** Clone
1936 
1937       The result of calling clone(false) is defined to be equivalent to
1938       calling the default constructor OsiSolverInterface().
1939     */
1940     virtual OsiSolverInterface * clone(bool copyData = true) const = 0;
1941 
1942     /// Copy constructor
1943     OsiSolverInterface(const OsiSolverInterface &);
1944 
1945     /// Assignment operator
1946     OsiSolverInterface & operator=(const OsiSolverInterface& rhs);
1947 
1948     /// Destructor
1949     virtual ~OsiSolverInterface ();
1950 
1951     /** Reset the solver interface.
1952 
1953     A call to reset() returns the solver interface to the same state as
1954     it would have if it had just been constructed by calling the default
1955     constructor OsiSolverInterface().
1956     */
1957     virtual void reset();
1958   //@}
1959 
1960   //---------------------------------------------------------------------------
1961 
1962 protected:
1963   ///@name Protected methods
1964   //@{
1965     /** Apply a row cut (append to the constraint matrix). */
1966     virtual void applyRowCut( const OsiRowCut & rc ) = 0;
1967 
1968     /** Apply a column cut (adjust the bounds of one or more variables). */
1969     virtual void applyColCut( const OsiColCut & cc ) = 0;
1970 
1971     /** A quick inlined function to convert from the lb/ub style of
1972 	constraint definition to the sense/rhs/range style */
1973     inline void
1974     convertBoundToSense(const double lower, const double upper,
1975 			char& sense, double& right, double& range) const;
1976     /** A quick inlined function to convert from the sense/rhs/range style
1977 	of constraint definition to the lb/ub style */
1978     inline void
1979     convertSenseToBound(const char sense, const double right,
1980 			const double range,
1981 			double& lower, double& upper) const;
1982     /** A quick inlined function to force a value to be between a minimum and
1983 	a maximum value */
1984     template <class T> inline T
forceIntoRange(const T value,const T lower,const T upper) const1985     forceIntoRange(const T value, const T lower, const T upper) const {
1986       return value < lower ? lower : (value > upper ? upper : value);
1987     }
1988     /** Set OsiSolverInterface object state for default constructor
1989 
1990       This routine establishes the initial values of data fields in the
1991       OsiSolverInterface object when the object is created using the
1992       default constructor.
1993     */
1994     void setInitialData();
1995   //@}
1996 
1997   ///@name Protected member data
1998   //@{
1999     /*! \brief Pointer to row cut debugger object
2000 
2001       Mutable so that we can update the solution held in the debugger while
2002       maintaining const'ness for the Osi object.
2003     */
2004     mutable OsiRowCutDebugger * rowCutDebugger_;
2005    // Why not just make useful stuff protected?
2006    /// Message handler
2007   CoinMessageHandler * handler_;
2008   /** Flag to say if the currrent handler is the default handler.
2009       Indicates if the solver interface object is responsible
2010       for destruction of the handler (true) or if the client is
2011       responsible (false).
2012   */
2013   bool defaultHandler_;
2014   /// Messages
2015   CoinMessages messages_;
2016   /// Number of integers
2017   int numberIntegers_;
2018   /// Total number of objects
2019   int numberObjects_;
2020 
2021   /// Integer and ... information (integer info normally at beginning)
2022   OsiObject ** object_;
2023   /** Column type
2024       0 - continuous
2025       1 - binary (may get fixed later)
2026       2 - general integer (may get fixed later)
2027   */
2028   mutable char * columnType_;
2029 
2030   //@}
2031 
2032   //---------------------------------------------------------------------------
2033 
2034 private:
2035   ///@name Private member data
2036   //@{
2037     /// Pointer to user-defined data structure - and more if user wants
2038     OsiAuxInfo * appDataEtc_;
2039     /// Array of integer parameters
2040     int intParam_[OsiLastIntParam];
2041     /// Array of double parameters
2042     double dblParam_[OsiLastDblParam];
2043     /// Array of string parameters
2044     std::string strParam_[OsiLastStrParam];
2045     /// Array of hint parameters
2046     bool hintParam_[OsiLastHintParam];
2047     /// Array of hint strengths
2048     OsiHintStrength hintStrength_[OsiLastHintParam];
2049     /** Warm start information used for hot starts when the default
2050        hot start implementation is used. */
2051     CoinWarmStart* ws_;
2052     /// Column solution satisfying lower and upper column bounds
2053     std::vector<double> strictColSolution_;
2054 
2055     /// Row names
2056     OsiNameVec rowNames_ ;
2057     /// Column names
2058     OsiNameVec colNames_ ;
2059     /// Objective name
2060     std::string objName_ ;
2061 
2062  //@}
2063 };
2064 
2065 //#############################################################################
2066 /** A quick inlined function to convert from the lb/ub style of constraint
2067     definition to the sense/rhs/range style */
2068 inline void
convertBoundToSense(const double lower,const double upper,char & sense,double & right,double & range) const2069 OsiSolverInterface::convertBoundToSense(const double lower, const double upper,
2070 					char& sense, double& right,
2071 					double& range) const
2072 {
2073   double inf = getInfinity();
2074   range = 0.0;
2075   if (lower > -inf) {
2076     if (upper < inf) {
2077       right = upper;
2078       if (upper==lower) {
2079         sense = 'E';
2080       } else {
2081         sense = 'R';
2082         range = upper - lower;
2083       }
2084     } else {
2085       sense = 'G';
2086       right = lower;
2087     }
2088   } else {
2089     if (upper < inf) {
2090       sense = 'L';
2091       right = upper;
2092     } else {
2093       sense = 'N';
2094       right = 0.0;
2095     }
2096   }
2097 }
2098 
2099 //-----------------------------------------------------------------------------
2100 /** A quick inlined function to convert from the sense/rhs/range style of
2101     constraint definition to the lb/ub style */
2102 inline void
convertSenseToBound(const char sense,const double right,const double range,double & lower,double & upper) const2103 OsiSolverInterface::convertSenseToBound(const char sense, const double right,
2104 					const double range,
2105 					double& lower, double& upper) const
2106 {
2107   double inf=getInfinity();
2108   switch (sense) {
2109   case 'E':
2110     lower = upper = right;
2111     break;
2112   case 'L':
2113     lower = -inf;
2114     upper = right;
2115     break;
2116   case 'G':
2117     lower = right;
2118     upper = inf;
2119     break;
2120   case 'R':
2121     lower = right - range;
2122     upper = right;
2123     break;
2124   case 'N':
2125     lower = -inf;
2126     upper = inf;
2127     break;
2128   }
2129 }
2130 
2131 #endif
2132