1 // $Id$
2 // Copyright (C) 2000, International Business Machines
3 // Corporation and others.  All Rights Reserved.
4 // This code is licensed under the terms of the Eclipse Public License (EPL).
5 
6 
7 #ifndef OsiClpSolverInterface_H
8 #define OsiClpSolverInterface_H
9 
10 #include <string>
11 #include <cfloat>
12 #include <map>
13 
14 #include "ClpSimplex.hpp"
15 #include "ClpLinearObjective.hpp"
16 #include "CoinPackedMatrix.hpp"
17 #include "OsiSolverInterface.hpp"
18 #include "CoinWarmStartBasis.hpp"
19 #include "ClpEventHandler.hpp"
20 #include "ClpNode.hpp"
21 #include "CoinIndexedVector.hpp"
22 #include "CoinFinite.hpp"
23 
24 class OsiRowCut;
25 class OsiClpUserSolver;
26 class OsiClpDisasterHandler;
27 class CoinSet;
28 static const double OsiClpInfinity = COIN_DBL_MAX;
29 
30 //#############################################################################
31 
32 /** Clp Solver Interface
33 
34 Instantiation of OsiClpSolverInterface for the Model Algorithm.
35 
36 */
37 
38 class OsiClpSolverInterface :
39   virtual public OsiSolverInterface {
40   friend void OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir);
41 
42 public:
43   //---------------------------------------------------------------------------
44   /**@name Solve methods */
45   //@{
46   /// Solve initial LP relaxation
47   virtual void initialSolve() override;
48 
49   /// Resolve an LP relaxation after problem modification
50   virtual void resolve() override;
51 
52   /// Resolve an LP relaxation after problem modification (try GUB)
53   virtual void resolveGub(int needed);
54 
55   /// Invoke solver's built-in enumeration algorithm
56   virtual void branchAndBound() override;
57 
58   /** Solve when primal column and dual row solutions are near-optimal
59       options - 0 no presolve (use primal and dual)
60                 1 presolve (just use primal)
61 		2 no presolve (just use primal)
62       basis -   0 use all slack basis
63                 1 try and put some in basis
64   */
65   void crossover(int options,int basis);
66   //@}
67 
68   /*! @name OsiSimplexInterface methods
69       \brief Methods for the Osi Simplex API.
70 
71     The current implementation should work for both minimisation and
72     maximisation in mode 1 (tableau access). In mode 2 (single pivot), only
73     minimisation is supported as of 100907.
74   */
75   //@{
76   /** \brief Simplex API capability.
77 
78     Returns
79      - 0 if no simplex API
80      - 1 if can just do getBInv etc
81      - 2 if has all OsiSimplex methods
82   */
83   virtual int canDoSimplexInterface() const override;
84 
85   /*! \brief Enables simplex mode 1 (tableau access)
86 
87     Tells solver that calls to getBInv etc are about to take place.
88     Underlying code may need mutable as this may be called from
89     CglCut::generateCuts which is const.  If that is too horrific then
90     each solver e.g. BCP or CBC will have to do something outside
91     main loop.
92   */
93   virtual void enableFactorization() const override;
94 
95   /*! \brief Undo any setting changes made by #enableFactorization */
96   virtual void disableFactorization() const override;
97 
98   /** Returns true if a basis is available
99       AND problem is optimal.  This should be used to see if
100       the BInvARow type operations are possible and meaningful.
101   */
102   virtual bool basisIsAvailable() const override;
103 
104   /** The following two methods may be replaced by the
105       methods of OsiSolverInterface using OsiWarmStartBasis if:
106       1. OsiWarmStartBasis resize operation is implemented
107       more efficiently and
108       2. It is ensured that effects on the solver are the same
109 
110       Returns a basis status of the structural/artificial variables
111       At present as warm start i.e 0 free, 1 basic, 2 upper, 3 lower
112 
113       NOTE  artificials are treated as +1 elements so for <= rhs
114       artificial will be at lower bound if constraint is tight
115 
116       This means that Clpsimplex flips artificials as it works
117       in terms of row activities
118   */
119   virtual void getBasisStatus(int* cstat, int* rstat) const override;
120 
121   /** Set the status of structural/artificial variables and
122       factorize, update solution etc
123 
124       NOTE  artificials are treated as +1 elements so for <= rhs
125       artificial will be at lower bound if constraint is tight
126 
127       This means that Clpsimplex flips artificials as it works
128       in terms of row activities
129       Returns 0 if OK, 1 if problem is bad e.g. duplicate elements, too large ...
130   */
131   virtual int setBasisStatus(const int* cstat, const int* rstat) override;
132 
133   ///Get the reduced gradient for the cost vector c
134   virtual void getReducedGradient(double* columnReducedCosts,
135 				  double * duals,
136 				  const double * c) const override ;
137 
138   ///Get a row of the tableau (slack part in slack if not NULL)
139   virtual void getBInvARow(int row, double* z, double * slack=nullptr) const override;
140 
141   /** Get a row of the tableau (slack part in slack if not NULL)
142       If keepScaled is true then scale factors not applied after so
143       user has to use coding similar to what is in this method
144   */
145   virtual void getBInvARow(int row, CoinIndexedVector * z, CoinIndexedVector * slack=nullptr,
146 			   bool keepScaled=false) const;
147 
148   ///Get a row of the basis inverse
149   virtual void getBInvRow(int row, double* z) const override;
150 
151   ///Get a column of the tableau
152   virtual void getBInvACol(int col, double* vec) const override ;
153 
154   ///Get a column of the tableau
155   virtual void getBInvACol(int col, CoinIndexedVector * vec) const ;
156 
157   /** Update (i.e. ftran) the vector passed in.
158       Unscaling is applied after - can't be applied before
159   */
160 
161   virtual void getBInvACol(CoinIndexedVector * vec) const ;
162 
163   ///Get a column of the basis inverse
164   virtual void getBInvCol(int col, double* vec) const override ;
165 
166   /** Get basic indices (order of indices corresponds to the
167       order of elements in a vector retured by getBInvACol() and
168       getBInvCol()).
169   */
170   virtual void getBasics(int* index) const override;
171 
172   /*! \brief Enables simplex mode 2 (individual pivot control)
173 
174      This method is supposed to ensure that all typical things (like
175      reduced costs, etc.) are updated when individual pivots are executed
176      and can be queried by other methods.
177   */
178   virtual void enableSimplexInterface(bool doingPrimal) override;
179 
180   /*! \brief Undo setting changes made by #enableSimplexInterface */
181   virtual void disableSimplexInterface() override;
182 
183   /** Perform a pivot by substituting a colIn for colOut in the basis.
184       The status of the leaving variable is given in statOut. Where
185       1 is to upper bound, -1 to lower bound
186       Return code is 0 for okay,
187       1 if inaccuracy forced re-factorization (should be okay) and
188       -1 for singular factorization
189   */
190   virtual int pivot(int colIn, int colOut, int outStatus) override;
191 
192   /** Obtain a result of the primal pivot
193       Outputs: colOut -- leaving column, outStatus -- its status,
194       t -- step size, and, if dx!=NULL, *dx -- primal ray direction.
195       Inputs: colIn -- entering column, sign -- direction of its change (+/-1).
196       Both for colIn and colOut, artificial variables are index by
197       the negative of the row index minus 1.
198       Return code (for now): 0 -- leaving variable found,
199       -1 -- everything else?
200       Clearly, more informative set of return values is required
201       Primal and dual solutions are updated
202   */
203   virtual int primalPivotResult(int colIn, int sign,
204 				int& colOut, int& outStatus,
205 				double& t, CoinPackedVector* dx) override;
206 
207   /** Obtain a result of the dual pivot (similar to the previous method)
208       Differences: entering variable and a sign of its change are now
209       the outputs, the leaving variable and its statuts -- the inputs
210       If dx!=NULL, then *dx contains dual ray
211       Return code: same
212   */
213   virtual int dualPivotResult(int& colIn, int& sign,
214 			      int colOut, int outStatus,
215 			      double& t, CoinPackedVector* dx) override;
216 
217 
218   //@}
219   //---------------------------------------------------------------------------
220   /**@name Parameter set/get methods
221 
222   The set methods return true if the parameter was set to the given value,
223   false otherwise. There can be various reasons for failure: the given
224   parameter is not applicable for the solver (e.g., refactorization
225   frequency for the clp algorithm), the parameter is not yet implemented
226   for the solver or simply the value of the parameter is out of the range
227   the solver accepts. If a parameter setting call returns false check the
228   details of your solver.
229 
230   The get methods return true if the given parameter is applicable for the
231   solver and is implemented. In this case the value of the parameter is
232   returned in the second argument. Otherwise they return false.
233   */
234   //@{
235   // Set an integer parameter
236   bool setIntParam(OsiIntParam key, int value) override;
237   // Set an double parameter
238   bool setDblParam(OsiDblParam key, double value) override;
239   // Set a string parameter
240   bool setStrParam(OsiStrParam key, const std::string & value) override;
241   // Get an integer parameter
242   bool getIntParam(OsiIntParam key, int& value) const override;
243   // Get an double parameter
244   bool getDblParam(OsiDblParam key, double& value) const override;
245   // Get a string parameter
246   bool getStrParam(OsiStrParam key, std::string& value) const override;
247   // Set a hint parameter - overrides OsiSolverInterface
248   virtual bool setHintParam(OsiHintParam key, bool yesNo=true,
249                             OsiHintStrength strength=OsiHintTry,
250                             void * otherInformation=nullptr) override;
251   //@}
252 
253   //---------------------------------------------------------------------------
254   ///@name Methods returning info on how the solution process terminated
255   //@{
256   /// Are there a numerical difficulties?
257   virtual bool isAbandoned() const override;
258   /// Is optimality proven?
259   virtual bool isProvenOptimal() const override;
260   /// Is primal infeasiblity proven?
261   virtual bool isProvenPrimalInfeasible() const override;
262   /// Is dual infeasiblity proven?
263   virtual bool isProvenDualInfeasible() const override;
264   /// Is the given primal objective limit reached?
265   virtual bool isPrimalObjectiveLimitReached() const override;
266   /// Is the given dual objective limit reached?
267   virtual bool isDualObjectiveLimitReached() const override;
268   /// Iteration limit reached?
269   virtual bool isIterationLimitReached() const override;
270   //@}
271 
272   //---------------------------------------------------------------------------
273   /**@name WarmStart related methods */
274   //@{
275 
276   /*! \brief Get an empty warm start object
277 
278   This routine returns an empty CoinWarmStartBasis object. Its purpose is
279   to provide a way to give a client a warm start basis object of the
280   appropriate type, which can resized and modified as desired.
281   */
282 
283   virtual CoinWarmStart *getEmptyWarmStart () const override;
284 
285   /// Get warmstarting information
286   virtual CoinWarmStart* getWarmStart() const override;
287   /// Get warmstarting information
getPointerToWarmStart()288   inline CoinWarmStartBasis* getPointerToWarmStart()
289   { return &basis_;}
290   /// Get warmstarting information
getConstPointerToWarmStart() const291   inline const CoinWarmStartBasis* getConstPointerToWarmStart() const
292   { return &basis_;}
293   /** Set warmstarting information. Return true/false depending on whether
294       the warmstart information was accepted or not. */
295   virtual bool setWarmStart(const CoinWarmStart* warmstart) override;
296   /** \brief Get warm start information.
297 
298       Return warm start information for the current state of the solver
299       interface. If there is no valid warm start information, an empty warm
300       start object wil be returned.  This does not necessarily create an
301       object - may just point to one.  must Delete set true if user
302       should delete returned object.
303       OsiClp version always returns pointer and false.
304   */
305   virtual CoinWarmStart* getPointerToWarmStart(bool & mustDelete) override ;
306 
307   //@}
308 
309   //---------------------------------------------------------------------------
310   /**@name Hotstart related methods (primarily used in strong branching).
311      The user can create a hotstart (a snapshot) of the optimization process
312      then reoptimize over and over again always starting from there.<br>
313      <strong>NOTE</strong>: between hotstarted optimizations only
314      bound changes are allowed. */
315   //@{
316   /// Create a hotstart point of the optimization process
317   virtual void markHotStart() override;
318   /// Optimize starting from the hotstart
319   virtual void solveFromHotStart() override;
320   /// Delete the snapshot
321   virtual void unmarkHotStart() override;
322   /** Start faster dual - returns negative if problems 1 if infeasible,
323       Options to pass to solver
324       1 - create external reduced costs for columns
325       2 - create external reduced costs for rows
326       4 - create external row activity (columns always done)
327       Above only done if feasible
328       When set resolve does less work
329   */
330   int startFastDual(int options);
331   /// Stop fast dual
332   void stopFastDual();
333   /// Sets integer tolerance and increment
334   void setStuff(double tolerance,double increment);
335   //@}
336 
337   //---------------------------------------------------------------------------
338   /**@name Problem information methods
339 
340   These methods call the solver's query routines to return
341   information about the problem referred to by the current object.
342   Querying a problem that has no data associated with it result in
343   zeros for the number of rows and columns, and NULL pointers from
344   the methods that return vectors.
345 
346   Const pointers returned from any data-query method are valid as
347   long as the data is unchanged and the solver is not called.
348   */
349   //@{
350   /**@name Methods related to querying the input data */
351   //@{
352   /// Get number of columns
getNumCols() const353   virtual int getNumCols() const override {
354     return modelPtr_->numberColumns(); }
355 
356   /// Get number of rows
getNumRows() const357   virtual int getNumRows() const override {
358     return modelPtr_->numberRows(); }
359 
360   /// Get number of nonzero elements
getNumElements() const361   virtual int getNumElements() const override {
362     int retVal = 0;
363     const CoinPackedMatrix * matrix =modelPtr_->matrix();
364     if ( matrix != nullptr ) retVal=matrix->getNumElements();
365     return retVal; }
366 
367     /// Return name of row if one exists or Rnnnnnnn
368     /// maxLen is currently ignored and only there to match the signature from the base class!
369     virtual std::string getRowName(int rowIndex,
370 #pragma warning(suppress: 4309)
371 				   unsigned maxLen = static_cast<unsigned>(std::string::npos)) const override;
372 
373     /// Return name of column if one exists or Cnnnnnnn
374     /// maxLen is currently ignored and only there to match the signature from the base class!
375     virtual std::string getColName(int colIndex,
376 #pragma warning(suppress: 4309)
377 				   unsigned maxLen = static_cast<unsigned>(std::string::npos)) const override;
378 
379 
380   /// Get pointer to array[getNumCols()] of column lower bounds
getColLower() const381   virtual const double * getColLower() const override { return modelPtr_->columnLower(); }
382 
383   /// Get pointer to array[getNumCols()] of column upper bounds
getColUpper() const384   virtual const double * getColUpper() const override { return modelPtr_->columnUpper(); }
385 
386   /** Get pointer to array[getNumRows()] of row constraint senses.
387       <ul>
388       <li>'L' <= constraint
389       <li>'E' =  constraint
390       <li>'G' >= constraint
391       <li>'R' ranged constraint
392       <li>'N' free constraint
393       </ul>
394   */
395   virtual const char * getRowSense() const override;
396 
397   /** Get pointer to array[getNumRows()] of rows right-hand sides
398       <ul>
399       <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i]
400       <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i]
401       <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i]
402       <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0
403       </ul>
404   */
405   virtual const double * getRightHandSide() const override ;
406 
407   /** Get pointer to array[getNumRows()] of row ranges.
408       <ul>
409       <li> if rowsense()[i] == 'R' then
410       rowrange()[i] == rowupper()[i] - rowlower()[i]
411       <li> if rowsense()[i] != 'R' then
412       rowrange()[i] is undefined
413       </ul>
414   */
415   virtual const double * getRowRange() const override ;
416 
417   /// Get pointer to array[getNumRows()] of row lower bounds
getRowLower() const418   virtual const double * getRowLower() const override { return modelPtr_->rowLower(); }
419 
420   /// Get pointer to array[getNumRows()] of row upper bounds
getRowUpper() const421   virtual const double * getRowUpper() const override { return modelPtr_->rowUpper(); }
422 
423   /// Get pointer to array[getNumCols()] of objective function coefficients
getObjCoefficients() const424   virtual const double * getObjCoefficients() const override
425   { if (fakeMinInSimplex_)
426       return linearObjective_ ;
427     else
428       return modelPtr_->objective(); }
429 
430   /// Get objective function sense (1 for min (default), -1 for max)
getObjSense() const431   virtual double getObjSense() const override
432   { return ((fakeMinInSimplex_)?-modelPtr_->optimizationDirection():
433   				 modelPtr_->optimizationDirection()); }
434 
435   /// Return true if column is continuous
436   virtual bool isContinuous(int colNumber) const override;
437   /// Return true if variable is binary
438   virtual bool isBinary(int colIndex) const override;
439 
440   /** Return true if column is integer.
441       Note: This function returns true if the the column
442       is binary or a general integer.
443   */
444   virtual bool isInteger(int colIndex) const override;
445 
446   /// Return true if variable is general integer
447   virtual bool isIntegerNonBinary(int colIndex) const override;
448 
449   /// Return true if variable is binary and not fixed at either bound
450   virtual bool isFreeBinary(int colIndex) const override;
451   /**  Return array of column length
452        0 - continuous
453        1 - binary (may get fixed later)
454        2 - general integer (may get fixed later)
455   */
456   virtual const char * getColType(bool refresh=false) const override;
457 
458   /** Return true if column is integer but does not have to
459       be declared as such.
460       Note: This function returns true if the the column
461       is binary or a general integer.
462   */
463   bool isOptionalInteger(int colIndex) const;
464   /** Set the index-th variable to be an optional integer variable */
465   void setOptionalInteger(int index);
466 
467   /// Get pointer to row-wise copy of matrix
468   virtual const CoinPackedMatrix * getMatrixByRow() const override;
469 
470   /// Get pointer to column-wise copy of matrix
471   virtual const CoinPackedMatrix * getMatrixByCol() const override;
472 
473   /// Get pointer to mutable column-wise copy of matrix
474   virtual CoinPackedMatrix * getMutableMatrixByCol() const override;
475 
476     /// Get solver's value for infinity
getInfinity() const477   virtual double getInfinity() const override { return OsiClpInfinity; }
478   //@}
479 
480   /**@name Methods related to querying the solution */
481   //@{
482   /// Get pointer to array[getNumCols()] of primal solution vector
483   virtual const double * getColSolution() const override;
484 
485   /// Get pointer to array[getNumRows()] of dual prices
486   virtual const double * getRowPrice() const override;
487 
488   /// Get a pointer to array[getNumCols()] of reduced costs
489   virtual const double * getReducedCost() const override;
490 
491   /** Get pointer to array[getNumRows()] of row activity levels (constraint
492       matrix times the solution vector */
493   virtual const double * getRowActivity() const override;
494 
495   /// Get objective function value
496   virtual double getObjValue() const override;
497 
498   /** Get how many iterations it took to solve the problem (whatever
499       "iteration" mean to the solver. */
getIterationCount() const500   virtual int getIterationCount() const override
501   { return modelPtr_->numberIterations(); }
502 
503   /** Get as many dual rays as the solver can provide. (In case of proven
504       primal infeasibility there should be at least one.)
505 
506       The first getNumRows() ray components will always be associated with
507       the row duals (as returned by getRowPrice()). If \c fullRay is true,
508       the final getNumCols() entries will correspond to the ray components
509       associated with the nonbasic variables. If the full ray is requested
510       and the method cannot provide it, it will throw an exception.
511 
512       <strong>NOTE for implementers of solver interfaces:</strong> <br>
513       The double pointers in the vector should point to arrays of length
514       getNumRows() and they should be allocated via new[]. <br>
515 
516       <strong>NOTE for users of solver interfaces:</strong> <br>
517       It is the user's responsibility to free the double pointers in the
518       vector using delete[].
519   */
520   virtual std::vector<double*> getDualRays(int maxNumRays,
521 					   bool fullRay = false) const override;
522   /** Get as many primal rays as the solver can provide. (In case of proven
523       dual infeasibility there should be at least one.)
524 
525       <strong>NOTE for implementers of solver interfaces:</strong> <br>
526       The double pointers in the vector should point to arrays of length
527       getNumCols() and they should be allocated via new[]. <br>
528 
529       <strong>NOTE for users of solver interfaces:</strong> <br>
530       It is the user's responsibility to free the double pointers in the
531       vector using delete[].
532   */
533   virtual std::vector<double*> getPrimalRays(int maxNumRays) const override;
534 
535   //@}
536   //@}
537 
538   //---------------------------------------------------------------------------
539 
540   /**@name Problem modifying methods */
541   //@{
542   //-------------------------------------------------------------------------
543   /**@name Changing bounds on variables and constraints */
544   //@{
545   /** Set an objective function coefficient */
546   virtual void setObjCoeff( int elementIndex, double elementValue ) override;
547 
548   /** Set a single column lower bound<br>
549       Use -DBL_MAX for -infinity. */
550   virtual void setColLower( int elementIndex, double elementValue ) override;
551 
552   /** Set a single column upper bound<br>
553       Use DBL_MAX for infinity. */
554   virtual void setColUpper( int elementIndex, double elementValue ) override;
555 
556   /** Set a single column lower and upper bound */
557   virtual void setColBounds( int elementIndex,
558                              double lower, double upper ) override;
559 
560   /** Set the bounds on a number of columns simultaneously<br>
561       The default implementation just invokes setColLower() and
562       setColUpper() over and over again.
563       @param indexFirst,indexLast pointers to the beginning and after the
564       end of the array of the indices of the variables whose
565       <em>either</em> bound changes
566       @param boundList the new lower/upper bound pairs for the variables
567   */
568   virtual void setColSetBounds(const int* indexFirst,
569                                const int* indexLast,
570                                const double* boundList) override;
571 
572   /** Set a single row lower bound<br>
573       Use -DBL_MAX for -infinity. */
574   virtual void setRowLower( int elementIndex, double elementValue ) override;
575 
576   /** Set a single row upper bound<br>
577       Use DBL_MAX for infinity. */
578   virtual void setRowUpper( int elementIndex, double elementValue ) override ;
579 
580   /** Set a single row lower and upper bound */
581   virtual void setRowBounds( int elementIndex,
582                              double lower, double upper ) override ;
583 
584   /** Set the type of a single row<br> */
585   virtual void setRowType(int index, char sense, double rightHandSide,
586                           double range) override;
587 
588   /** Set the bounds on a number of rows simultaneously<br>
589       The default implementation just invokes setRowLower() and
590       setRowUpper() over and over again.
591       @param indexFirst,indexLast pointers to the beginning and after the
592       end of the array of the indices of the constraints whose
593       <em>either</em> bound changes
594       @param boundList the new lower/upper bound pairs for the constraints
595   */
596   virtual void setRowSetBounds(const int* indexFirst,
597                                const int* indexLast,
598                                const double* boundList) override;
599 
600   /** Set the type of a number of rows simultaneously<br>
601       The default implementation just invokes setRowType()
602       over and over again.
603       @param indexFirst,indexLast pointers to the beginning and after the
604       end of the array of the indices of the constraints whose
605       <em>any</em> characteristics changes
606       @param senseList the new senses
607       @param rhsList   the new right hand sides
608       @param rangeList the new ranges
609   */
610   virtual void setRowSetTypes(const int* indexFirst,
611                               const int* indexLast,
612                               const char* senseList,
613                               const double* rhsList,
614                               const double* rangeList) override;
615     /** Set the objective coefficients for all columns
616 	array [getNumCols()] is an array of values for the objective.
617         This defaults to a series of set operations and is here for speed.
618     */
619     virtual void setObjective(const double * array) override;
620 
621     /** Set the lower bounds for all columns
622 	array [getNumCols()] is an array of values for the objective.
623         This defaults to a series of set operations and is here for speed.
624     */
625     virtual void setColLower(const double * array) override;
626 
627     /** Set the upper bounds for all columns
628 	array [getNumCols()] is an array of values for the objective.
629         This defaults to a series of set operations and is here for speed.
630     */
631     virtual void setColUpper(const double * array) override;
632 
633 //    using OsiSolverInterface::setRowName ;
634     /// Set name of row
635 //    virtual void setRowName(int rowIndex, std::string & name) ;
636     virtual void setRowName(int rowIndex, std::string  name) override ;
637 
638 //    using OsiSolverInterface::setColName ;
639     /// Set name of column
640 //    virtual void setColName(int colIndex, std::string & name) ;
641     virtual void setColName(int colIndex, std::string  name) override ;
642 
643   //@}
644 
645   //-------------------------------------------------------------------------
646   /**@name Integrality related changing methods */
647   //@{
648   /** Set the index-th variable to be a continuous variable */
649   virtual void setContinuous(int index) override;
650   /** Set the index-th variable to be an integer variable */
651   virtual void setInteger(int index) override;
652   /** Set the variables listed in indices (which is of length len) to be
653       continuous variables */
654   virtual void setContinuous(const int* indices, int len) override;
655   /** Set the variables listed in indices (which is of length len) to be
656       integer variables */
657   virtual void setInteger(const int* indices, int len) override;
658   /// Number of SOS sets
numberSOS() const659   inline int numberSOS() const
660   { return numberSOS_;}
661   /// SOS set info
setInfo() const662   inline const CoinSet * setInfo() const
663   { return setInfo_;}
664   /** \brief Identify integer variables and SOS and create corresponding objects.
665 
666     Record integer variables and create an OsiSimpleInteger object for each
667     one.  All existing OsiSimpleInteger objects will be destroyed.
668     If the solver supports SOS then do the same for SOS.
669      If justCount then no objects created and we just store numberIntegers_
670     Returns number of SOS
671   */
672 
673   virtual int findIntegersAndSOS(bool justCount) override;
674   //@}
675 
676   //-------------------------------------------------------------------------
677   /// Set objective function sense (1 for min (default), -1 for max,)
setObjSense(double s)678   virtual void setObjSense(double s ) override
679   { modelPtr_->setOptimizationDirection( s < 0 ? -1 : 1); }
680 
681   /** Set the primal solution column values
682 
683   colsol[numcols()] is an array of values of the problem column
684   variables. These values are copied to memory owned by the
685   solver object or the solver.  They will be returned as the
686   result of colsol() until changed by another call to
687   setColsol() or by a call to any solver routine.  Whether the
688   solver makes use of the solution in any way is
689   solver-dependent.
690   */
691   virtual void setColSolution(const double * colsol) override;
692 
693   /** Set dual solution vector
694 
695   rowprice[numrows()] is an array of values of the problem row
696   dual variables. These values are copied to memory owned by the
697   solver object or the solver.  They will be returned as the
698   result of rowprice() until changed by another call to
699   setRowprice() or by a call to any solver routine.  Whether the
700   solver makes use of the solution in any way is
701   solver-dependent.
702   */
703   virtual void setRowPrice(const double * rowprice) override;
704 
705   //-------------------------------------------------------------------------
706   /**@name Methods to expand a problem.<br>
707      Note that if a column is added then by default it will correspond to a
708      continuous variable. */
709   //@{
710 
711   //using OsiSolverInterface::addCol ;
712   /** */
713   virtual void addCol(const CoinPackedVectorBase& vec,
714                       const double collb, const double colub,
715                       const double obj) override;
716   /*! \brief Add a named column (primal variable) to the problem.
717   */
718   virtual void addCol(const CoinPackedVectorBase& vec,
719 		      const double collb, const double colub,
720 		      const double obj, std::string name) override ;
721   /** Add a column (primal variable) to the problem. */
722   virtual void addCol(int numberElements, const int * rows, const double * elements,
723                       const double collb, const double colub,
724                       const double obj) override ;
725   /*! \brief Add a named column (primal variable) to the problem.
726    */
727   virtual void addCol(int numberElements,
728 		      const int* rows, const double* elements,
729 		      const double collb, const double colub,
730 		      const double obj, std::string name) override ;
731   /** */
732   virtual void addCols(const int numcols,
733                        const CoinPackedVectorBase * const * cols,
734                        const double* collb, const double* colub,
735                        const double* obj) override;
736   /**  */
737   virtual void addCols(const int numcols,
738 		       const int * columnStarts, const int * rows, const double * elements,
739 		       const double* collb, const double* colub,
740 		       const double* obj) override;
741   /** */
742   virtual void deleteCols(const int num, const int * colIndices) override;
743 
744   /** */
745   virtual void addRow(const CoinPackedVectorBase& vec,
746                       const double rowlb, const double rowub) override;
747   /** */
748     /*! \brief Add a named row (constraint) to the problem.
749 
750       The default implementation adds the row, then changes the name. This
751       can surely be made more efficient within an OsiXXX class.
752     */
753     virtual void addRow(const CoinPackedVectorBase& vec,
754 			const double rowlb, const double rowub,
755 			std::string name) override ;
756   virtual void addRow(const CoinPackedVectorBase& vec,
757                       const char rowsen, const double rowrhs,
758                       const double rowrng) override;
759   /** Add a row (constraint) to the problem. */
760   virtual void addRow(int numberElements, const int * columns, const double * element,
761 		      const double rowlb, const double rowub) override ;
762     /*! \brief Add a named row (constraint) to the problem.
763     */
764     virtual void addRow(const CoinPackedVectorBase& vec,
765 			const char rowsen, const double rowrhs,
766 			const double rowrng, std::string name) override ;
767   /** */
768   virtual void addRows(const int numrows,
769                        const CoinPackedVectorBase * const * rows,
770                        const double* rowlb, const double* rowub) override;
771   /** */
772   virtual void addRows(const int numrows,
773                        const CoinPackedVectorBase * const * rows,
774                        const char* rowsen, const double* rowrhs,
775                        const double* rowrng) override;
776 
777   /** */
778   virtual void addRows(const int numrows,
779 		       const int * rowStarts, const int * columns, const double * element,
780 		       const double* rowlb, const double* rowub) override;
781   ///
modifyCoefficient(int row,int column,double newElement,bool keepZero=false)782   void modifyCoefficient(int row, int column, double newElement,
783 			bool keepZero=false)
784 	{modelPtr_->modifyCoefficient(row,column,newElement, keepZero);}
785 
786   /** */
787   virtual void deleteRows(const int num, const int * rowIndices) override;
788   /**  If solver wants it can save a copy of "base" (continuous) model here
789    */
790   virtual void saveBaseModel() override ;
791   /**  Strip off rows to get to this number of rows.
792        If solver wants it can restore a copy of "base" (continuous) model here
793   */
794   virtual void restoreBaseModel(int numberRows) override;
795 
796   //-----------------------------------------------------------------------
797   /** Apply a collection of row cuts which are all effective.
798       applyCuts seems to do one at a time which seems inefficient.
799   */
800   virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts) override;
801   /** Apply a collection of row cuts which are all effective.
802       applyCuts seems to do one at a time which seems inefficient.
803       This uses array of pointers
804   */
805   virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts) override;
806     /** Apply a collection of cuts.
807 
808 	Only cuts which have an <code>effectiveness >= effectivenessLb</code>
809 	are applied.
810 	<ul>
811 	  <li> ReturnCode.getNumineffective() -- number of cuts which were
812 	       not applied because they had an
813 	       <code>effectiveness < effectivenessLb</code>
814 	  <li> ReturnCode.getNuminconsistent() -- number of invalid cuts
815 	  <li> ReturnCode.getNuminconsistentWrtIntegerModel() -- number of
816 	       cuts that are invalid with respect to this integer model
817 	  <li> ReturnCode.getNuminfeasible() -- number of cuts that would
818 	       make this integer model infeasible
819 	  <li> ReturnCode.getNumApplied() -- number of integer cuts which
820 	       were applied to the integer model
821 	  <li> cs.size() == getNumineffective() +
822 			    getNuminconsistent() +
823 			    getNuminconsistentWrtIntegerModel() +
824 			    getNuminfeasible() +
825 			    getNumApplied()
826 	</ul>
827     */
828     virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs,
829 					  double effectivenessLb = 0.0) override;
830 
831   //@}
832   //@}
833 
834   //---------------------------------------------------------------------------
835 
836 public:
837 
838   /**@name Methods to input a problem */
839   //@{
840   /** Load in an problem by copying the arguments (the constraints on the
841       rows are given by lower and upper bounds). If a pointer is NULL then the
842       following values are the default:
843       <ul>
844       <li> <code>colub</code>: all columns have upper bound infinity
845       <li> <code>collb</code>: all columns have lower bound 0
846       <li> <code>rowub</code>: all rows have upper bound infinity
847       <li> <code>rowlb</code>: all rows have lower bound -infinity
848       <li> <code>obj</code>: all variables have 0 objective coefficient
849       </ul>
850   */
851   virtual void loadProblem(const CoinPackedMatrix& matrix,
852                            const double* collb, const double* colub,
853                            const double* obj,
854                            const double* rowlb, const double* rowub) override;
855 
856   /** Load in an problem by assuming ownership of the arguments (the
857       constraints on the rows are given by lower and upper bounds). For
858       default values see the previous method.  <br>
859       <strong>WARNING</strong>: The arguments passed to this method will be
860       freed using the C++ <code>delete</code> and <code>delete[]</code>
861       functions.
862   */
863   virtual void assignProblem(CoinPackedMatrix*& matrix,
864     			     double*& collb, double*& colub, double*& obj,
865 			     double*& rowlb, double*& rowub) override;
866 
867   /** Load in an problem by copying the arguments (the constraints on the
868       rows are given by sense/rhs/range triplets). If a pointer is NULL then the
869       following values are the default:
870       <ul>
871       <li> <code>colub</code>: all columns have upper bound infinity
872       <li> <code>collb</code>: all columns have lower bound 0
873       <li> <code>obj</code>: all variables have 0 objective coefficient
874       <li> <code>rowsen</code>: all rows are >=
875       <li> <code>rowrhs</code>: all right hand sides are 0
876       <li> <code>rowrng</code>: 0 for the ranged rows
877       </ul>
878   */
879   virtual void loadProblem(const CoinPackedMatrix& matrix,
880     			   const double* collb, const double* colub,
881     			   const double* obj,
882     			   const char* rowsen, const double* rowrhs,
883 			   const double* rowrng) override;
884 
885   /** Load in an problem by assuming ownership of the arguments (the
886       constraints on the rows are given by sense/rhs/range triplets). For
887       default values see the previous method. <br>
888       <strong>WARNING</strong>: The arguments passed to this method will be
889       freed using the C++ <code>delete</code> and <code>delete[]</code>
890       functions.
891   */
892   virtual void assignProblem(CoinPackedMatrix*& matrix,
893     			     double*& collb, double*& colub, double*& obj,
894     			     char*& rowsen, double*& rowrhs,
895 			     double*& rowrng) override;
896 
897   /** Just like the other loadProblem() methods except that the matrix is
898       given as a ClpMatrixBase. */
899   virtual void loadProblem(const ClpMatrixBase& matrix,
900 			   const double* collb, const double* colub,
901 			   const double* obj,
902 			   const double* rowlb, const double* rowub) ;
903 
904   /** Just like the other loadProblem() methods except that the matrix is
905       given in a standard column major ordered format (without gaps). */
906   virtual void loadProblem(const int numcols, const int numrows,
907                            const CoinBigIndex * start, const int* index,
908                            const double* value,
909                            const double* collb, const double* colub,
910                            const double* obj,
911                            const double* rowlb, const double* rowub) override;
912 
913   /** Just like the other loadProblem() methods except that the matrix is
914       given in a standard column major ordered format (without gaps). */
915   virtual void loadProblem(const int numcols, const int numrows,
916                            const CoinBigIndex * start, const int* index,
917                            const double* value,
918                            const double* collb, const double* colub,
919                            const double* obj,
920                            const char* rowsen, const double* rowrhs,
921                            const double* rowrng) override;
922   /// This loads a model from a coinModel object - returns number of errors
923   virtual int loadFromCoinModel (  CoinModel & modelObject, bool keepSolution=false) override;
924 
925   using OsiSolverInterface::readMps ;
926   /** Read an mps file from the given filename (defaults to Osi reader) - returns
927       number of errors (see OsiMpsReader class) */
928   virtual int readMps(const char *filename,
929                       const char *extension = "mps") override ;
930   /** Read an mps file from the given filename returns
931       number of errors (see OsiMpsReader class) */
932   int readMps(const char *filename,bool keepNames,bool allowErrors);
933   /// Read an mps file
934   virtual int readMps (const char *filename, const char*extension,
935 			int & numberSets, CoinSet ** & sets) override;
936 
937   /** Write the problem into an mps file of the given filename.
938       If objSense is non zero then -1.0 forces the code to write a
939       maximization objective and +1.0 to write a minimization one.
940       If 0.0 then solver can do what it wants */
941   virtual void writeMps(const char *filename,
942                         const char *extension = "mps",
943                         double objSense=0.0) const override;
944   /** Write the problem into an mps file of the given filename,
945       names may be null.  formatType is
946       0 - normal
947       1 - extra accuracy
948       2 - IEEE hex (later)
949 
950       Returns non-zero on I/O error
951   */
952   virtual int writeMpsNative(const char *filename,
953                              const char ** rowNames, const char ** columnNames,
954                              int formatType=0,int numberAcross=2,
955                              double objSense=0.0) const ;
956   /// Read file in LP format (with names)
957   virtual int readLp(const char *filename, const double epsilon = 1e-5) override;
958   /** Write the problem into an Lp file of the given filename.
959       If objSense is non zero then -1.0 forces the code to write a
960       maximization objective and +1.0 to write a minimization one.
961       If 0.0 then solver can do what it wants.
962       This version calls writeLpNative with names */
963   virtual void writeLp(const char *filename,
964                        const char *extension = "lp",
965                        double epsilon = 1e-5,
966                        int numberAcross = 10,
967                        int decimals = 5,
968                        double objSense = 0.0,
969                        bool useRowNames = true) const override;
970   /** Write the problem into the file pointed to by the parameter fp.
971       Other parameters are similar to
972       those of writeLp() with first parameter filename.
973   */
974   virtual void writeLp(FILE *fp,
975                double epsilon = 1e-5,
976                int numberAcross = 10,
977                int decimals = 5,
978                double objSense = 0.0,
979 	       bool useRowNames = true) const override;
980   /**
981      I (JJF) am getting annoyed because I can't just replace a matrix.
982      The default behavior of this is do nothing so only use where that would not matter
983      e.g. strengthening a matrix for MIP
984   */
985   virtual void replaceMatrixOptional(const CoinPackedMatrix & matrix) override;
986   /// And if it does matter (not used at present)
987   virtual void replaceMatrix(const CoinPackedMatrix & matrix) override ;
988   //@}
989 
990   /**@name Message handling (extra for Clp messages).
991      Normally I presume you would want the same language.
992      If not then you could use underlying model pointer */
993   //@{
994   /** Pass in a message handler
995 
996       It is the client's responsibility to destroy a message handler installed
997       by this routine; it will not be destroyed when the solver interface is
998       destroyed.
999   */
1000   virtual void passInMessageHandler(CoinMessageHandler * handler) override;
1001   /// Set language
1002   void newLanguage(CoinMessages::Language language);
setLanguage(CoinMessages::Language language)1003   void setLanguage(CoinMessages::Language language)
1004   {newLanguage(language);}
1005   /// Set log level (will also set underlying solver's log level)
1006   void setLogLevel(int value);
1007   /// Create C++ lines to get to current state
1008   void generateCpp( FILE * fp);
1009   //@}
1010   //---------------------------------------------------------------------------
1011 
1012   /**@name Clp specific public interfaces */
1013   //@{
1014   /// Get pointer to Clp model
1015   ClpSimplex * getModelPtr() const ;
1016   /// Set pointer to Clp model and return old
swapModelPtr(ClpSimplex * newModel)1017   inline ClpSimplex * swapModelPtr(ClpSimplex * newModel)
1018   { ClpSimplex * model = modelPtr_; modelPtr_=newModel;return model;}
1019   /// Get special options
specialOptions() const1020   inline unsigned int specialOptions() const
1021   { return specialOptions_;}
1022   void setSpecialOptions(unsigned int value);
1023   /// Last algorithm used , 1 = primal, 2 = dual other unknown
lastAlgorithm() const1024   inline int lastAlgorithm() const
1025   { return lastAlgorithm_;}
1026   /// Set last algorithm used , 1 = primal, 2 = dual other unknown
setLastAlgorithm(int value)1027   inline void setLastAlgorithm(int value)
1028   { lastAlgorithm_ = value;}
1029   /// Get scaling action option
cleanupScaling() const1030   inline int cleanupScaling() const
1031   { return cleanupScaling_;}
1032   /** Set Scaling option
1033       When scaling is on it is possible that the scaled problem
1034       is feasible but the unscaled is not.  Clp returns a secondary
1035       status code to that effect.  This option allows for a cleanup.
1036       If you use it I would suggest 1.
1037       This only affects actions when scaled optimal
1038       0 - no action
1039       1 - clean up using dual if primal infeasibility
1040       2 - clean up using dual if dual infeasibility
1041       3 - clean up using dual if primal or dual infeasibility
1042       11,12,13 - as 1,2,3 but use primal
1043   */
setCleanupScaling(int value)1044   inline void setCleanupScaling(int value)
1045   { cleanupScaling_=value;}
1046   /** Get smallest allowed element in cut.
1047       If smaller than this then ignored */
smallestElementInCut() const1048   inline double smallestElementInCut() const
1049   { return smallestElementInCut_;}
1050   /** Set smallest allowed element in cut.
1051       If smaller than this then ignored */
setSmallestElementInCut(double value)1052   inline void setSmallestElementInCut(double value)
1053   { smallestElementInCut_=value;}
1054   /** Get smallest change in cut.
1055       If (upper-lower)*element < this then element is
1056       taken out and cut relaxed.
1057       (upper-lower) is taken to be at least 1.0 and
1058       this is assumed >= smallestElementInCut_
1059   */
smallestChangeInCut() const1060   inline double smallestChangeInCut() const
1061   { return smallestChangeInCut_;}
1062   /** Set smallest change in cut.
1063       If (upper-lower)*element < this then element is
1064       taken out and cut relaxed.
1065       (upper-lower) is taken to be at least 1.0 and
1066       this is assumed >= smallestElementInCut_
1067   */
setSmallestChangeInCut(double value)1068   inline void setSmallestChangeInCut(double value)
1069   { smallestChangeInCut_=value;}
1070   /// Pass in initial solve options
setSolveOptions(const ClpSolve & options)1071   inline void setSolveOptions(const ClpSolve & options)
1072   { solveOptions_ = options;}
1073   /** Tighten bounds - lightweight or very lightweight
1074       0 - normal, 1 lightweight but just integers, 2 lightweight and all
1075   */
1076   virtual int tightenBounds(int lightweight=0);
1077   /// Return number of entries in L part of current factorization
1078   virtual CoinBigIndex getSizeL() const;
1079   /// Return number of entries in U part of current factorization
1080   virtual CoinBigIndex getSizeU() const;
1081   /// Get disaster handler
disasterHandler() const1082   const OsiClpDisasterHandler * disasterHandler() const
1083   { return disasterHandler_;}
1084   /// Pass in disaster handler
1085   void passInDisasterHandler(OsiClpDisasterHandler * handler);
1086   /// Get fake objective
fakeObjective() const1087   ClpLinearObjective * fakeObjective() const
1088   { return fakeObjective_;}
1089   /// Set fake objective (and take ownership)
1090   void setFakeObjective(ClpLinearObjective * fakeObjective);
1091   /// Set fake objective
1092   void setFakeObjective(double * fakeObjective);
1093   /*! \brief Set up solver for repeated use by Osi interface.
1094 
1095     The normal usage does things like keeping factorization around so can be
1096     used.  Will also do things like keep scaling and row copy of matrix if
1097     matrix does not change.
1098 
1099     \p senseOfAdventure:
1100     - 0 - safe stuff as above
1101     - 1 - will take more risks - if it does not work then bug which will be
1102           fixed
1103     - 2 - don't bother doing most extreme termination checks e.g. don't bother
1104 	  re-factorizing if less than 20 iterations.
1105     - 3 - Actually safer than 1 (mainly just keeps factorization)
1106 
1107     \p printOut
1108     - -1 always skip round common messages instead of doing some work
1109     -  0 skip if normal defaults
1110     -  1 leaves
1111   */
1112   void setupForRepeatedUse(int senseOfAdventure=0, int printOut=0);
1113   /// Synchronize model (really if no cuts in tree)
1114   virtual void synchronizeModel();
1115   /*! \brief Set special options in underlying clp solver.
1116 
1117     Safe as const because #modelPtr_ is mutable.
1118   */
1119   void setSpecialOptionsMutable(unsigned int value) const;
1120 
1121   //@}
1122 
1123   //---------------------------------------------------------------------------
1124 
1125   /**@name Constructors and destructors */
1126   //@{
1127   /// Default Constructor
1128   OsiClpSolverInterface ();
1129 
1130   /// Clone
1131   virtual OsiSolverInterface * clone(bool copyData = true) const override;
1132 
1133   /// Copy constructor
1134   OsiClpSolverInterface (const OsiClpSolverInterface &);
1135 
1136   /// Borrow constructor - only delete one copy
1137   OsiClpSolverInterface (ClpSimplex * rhs, bool reallyOwn=false);
1138 
1139   /// Releases so won't error
1140   void releaseClp();
1141 
1142   /// Assignment operator
1143   OsiClpSolverInterface & operator=(const OsiClpSolverInterface& rhs);
1144 
1145   /// Destructor
1146   virtual ~OsiClpSolverInterface ();
1147 
1148   /// Resets as if default constructor
1149   virtual void reset() override;
1150   //@}
1151 
1152   //---------------------------------------------------------------------------
1153 
1154 protected:
1155   ///@name Protected methods
1156   //@{
1157   /** Apply a row cut (append to constraint matrix). */
1158   virtual void applyRowCut(const OsiRowCut& rc) override;
1159 
1160   /** Apply a column cut (adjust one or more bounds). */
1161   virtual void applyColCut(const OsiColCut& cc) override;
1162   //@}
1163 
1164   //---------------------------------------------------------------------------
1165 
1166 protected:
1167   /**@name Protected methods */
1168   //@{
1169   /// The real work of a copy constructor (used by copy and assignment)
1170   void gutsOfDestructor();
1171 
1172   /// Deletes all mutable stuff
1173   void freeCachedResults() const;
1174 
1175   /// Deletes all mutable stuff for row ranges etc
1176   void freeCachedResults0() const;
1177 
1178   /// Deletes all mutable stuff for matrix etc
1179   void freeCachedResults1() const;
1180 
1181   /// A method that fills up the rowsense_, rhs_ and rowrange_ arrays
1182   void extractSenseRhsRange() const;
1183 
1184   ///
1185   void fillParamMaps();
1186   /** Warm start
1187 
1188   NOTE  artificials are treated as +1 elements so for <= rhs
1189   artificial will be at lower bound if constraint is tight
1190 
1191   This means that Clpsimplex flips artificials as it works
1192   in terms of row activities
1193   */
1194   CoinWarmStartBasis getBasis(ClpSimplex * model) const;
1195   /** Sets up working basis as a copy of input
1196 
1197   NOTE  artificials are treated as +1 elements so for <= rhs
1198   artificial will be at lower bound if constraint is tight
1199 
1200   This means that Clpsimplex flips artificials as it works
1201   in terms of row activities
1202   */
1203   void setBasis( const CoinWarmStartBasis & basis, ClpSimplex * model);
1204   /// Crunch down problem a bit
1205   void crunch();
1206   /// Extend scale factors
1207   void redoScaleFactors(int numberRows,const CoinBigIndex * starts,
1208 			const int * indices, const double * elements);
1209 public:
1210   /** Sets up working basis as a copy of input and puts in as basis
1211   */
1212   void setBasis( const CoinWarmStartBasis & basis);
1213   /// Just puts current basis_ into ClpSimplex model
setBasis()1214   inline void setBasis( )
1215   { setBasis(basis_,modelPtr_);}
1216   /// Warm start difference from basis_ to statusArray
1217   CoinWarmStartDiff * getBasisDiff(const unsigned char * statusArray) const ;
1218   /// Warm start from statusArray
1219   CoinWarmStartBasis * getBasis(const unsigned char * statusArray) const ;
1220   /// Delete all scale factor stuff and reset option
1221   void deleteScaleFactors();
1222   /// If doing fast hot start then ranges are computed
upRange() const1223   inline const double * upRange() const
1224   { return rowActivity_;}
downRange() const1225   inline const double * downRange() const
1226   { return columnActivity_;}
1227   /// Pass in range array
passInRanges(int * array)1228   inline void passInRanges(int * array)
1229   { whichRange_=array;}
1230   /// Pass in sos stuff from AMPl
1231   void setSOSData(int numberSOS,const char * type,
1232 		  const int * start,const int * indices, const double * weights=nullptr);
1233   /// Compute largest amount any at continuous away from bound
1234   void computeLargestAway();
1235   /// Get largest amount continuous away from bound
largestAway() const1236   inline double largestAway() const
1237   { return largestAway_;}
1238   /// Set largest amount continuous away from bound
setLargestAway(double value)1239   inline void setLargestAway(double value)
1240   { largestAway_ = value;}
1241   /// Sort of lexicographic resolve
1242   void lexSolve();
1243   //@}
1244 
1245 protected:
1246   /**@name Protected member data */
1247   //@{
1248   /// Clp model represented by this class instance
1249   mutable ClpSimplex * modelPtr_;
1250   //@}
1251   /**@name Cached information derived from the OSL model */
1252   //@{
1253   /// Pointer to dense vector of row sense indicators
1254   mutable char    *rowsense_;
1255 
1256   /// Pointer to dense vector of row right-hand side values
1257   mutable double  *rhs_;
1258 
1259   /** Pointer to dense vector of slack upper bounds for range
1260       constraints (undefined for non-range rows)
1261   */
1262   mutable double  *rowrange_;
1263 
1264   /** A pointer to the warmstart information to be used in the hotstarts.
1265       This is NOT efficient and more thought should be given to it... */
1266   mutable CoinWarmStartBasis* ws_;
1267   /** also save row and column information for hot starts
1268       only used in hotstarts so can be casual */
1269   mutable double * rowActivity_;
1270   mutable double * columnActivity_;
1271   /// Stuff for fast dual
1272   ClpNodeStuff stuff_;
1273   /// Number of SOS sets
1274   int numberSOS_;
1275   /// SOS set info
1276   CoinSet * setInfo_;
1277   /// Alternate model (hot starts) - but also could be permanent and used for crunch
1278   ClpSimplex * smallModel_;
1279   /// factorization for hot starts
1280   ClpFactorization * factorization_;
1281   /** Smallest allowed element in cut.
1282       If smaller than this then ignored */
1283   double smallestElementInCut_;
1284   /** Smallest change in cut.
1285       If (upper-lower)*element < this then element is
1286       taken out and cut relaxed. */
1287   double smallestChangeInCut_;
1288   /// Largest amount continuous away from bound
1289   double largestAway_;
1290   /// Arrays for hot starts
1291   char * spareArrays_;
1292   /** Warmstart information to be used in resolves. */
1293   CoinWarmStartBasis basis_;
1294   /** The original iteration limit before hotstarts started. */
1295   int itlimOrig_;
1296 
1297   /*! \brief Last algorithm used
1298 
1299     Coded as
1300     -    0 invalid
1301     -    1 primal
1302     -    2 dual
1303     - -911 disaster in the algorithm that was attempted
1304     -  999 current solution no longer optimal due to change in problem or
1305            basis
1306   */
1307   mutable int lastAlgorithm_;
1308 
1309   /// To say if destructor should delete underlying model
1310   bool notOwned_;
1311 
1312   /// Pointer to row-wise copy of problem matrix coefficients.
1313   mutable CoinPackedMatrix *matrixByRow_;
1314 
1315   /// Pointer to row-wise copy of continuous problem matrix coefficients.
1316   CoinPackedMatrix *matrixByRowAtContinuous_;
1317 
1318   /// Pointer to integer information
1319   char * integerInformation_;
1320 
1321   /** Pointer to variables for which we want range information
1322       The number is in [0]
1323       memory is not owned by OsiClp
1324   */
1325   int * whichRange_;
1326 
1327   //std::map<OsiIntParam, ClpIntParam> intParamMap_;
1328   //std::map<OsiDblParam, ClpDblParam> dblParamMap_;
1329   //std::map<OsiStrParam, ClpStrParam> strParamMap_;
1330 
1331   /*! \brief Faking min to get proper dual solution signs in simplex API */
1332   mutable bool fakeMinInSimplex_ ;
1333   /*! \brief Linear objective
1334 
1335     Normally a pointer to the linear coefficient array in the clp objective.
1336     An independent copy when #fakeMinInSimplex_ is true, because we need
1337     something permanent to point to when #getObjCoefficients is called.
1338   */
1339   mutable double *linearObjective_;
1340 
1341   /// To save data in OsiSimplex stuff
1342   mutable ClpDataSave saveData_;
1343   /// Options for initialSolve
1344   ClpSolve solveOptions_;
1345   /** Scaling option
1346       When scaling is on it is possible that the scaled problem
1347       is feasible but the unscaled is not.  Clp returns a secondary
1348       status code to that effect.  This option allows for a cleanup.
1349       If you use it I would suggest 1.
1350       This only affects actions when scaled optimal
1351       0 - no action
1352       1 - clean up using dual if primal infeasibility
1353       2 - clean up using dual if dual infeasibility
1354       3 - clean up using dual if primal or dual infeasibility
1355       11,12,13 - as 1,2,3 but use primal
1356   */
1357   int cleanupScaling_;
1358   /** Special options
1359       0x80000000 off
1360       0 simple stuff for branch and bound
1361       1 try and keep work regions as much as possible
1362       2 do not use any perturbation
1363       4 allow exit before re-factorization
1364       8 try and re-use factorization if no cuts
1365       16 use standard strong branching rather than clp's
1366       32 Just go to first factorization in fast dual
1367       64 try and tighten bounds in crunch
1368       128 Model will only change in column bounds
1369       256 Clean up model before hot start
1370       512 Give user direct access to Clp regions in getBInvARow etc (i.e.,
1371           do not unscale, and do not return result in getBInv parameters;
1372 	  you have to know where to look for the answer)
1373       1024 Don't "borrow" model in initialSolve
1374       2048 Don't crunch
1375       4096 quick check for optimality
1376       Bits above 8192 give where called from in Cbc
1377       At present 0 is normal, 1 doing fast hotstarts, 2 is can do quick check
1378       65536 Keep simple i.e. no  crunch etc
1379       131072 Try and keep scaling factors around
1380       262144 Don't try and tighten bounds (funny global cuts)
1381       524288 Fake objective and 0-1
1382       1048576 Don't recompute ray after crunch
1383       2097152
1384   */
1385   mutable unsigned int specialOptions_;
1386   /// Copy of model when option 131072 set
1387   ClpSimplex * baseModel_;
1388   /// Number of rows when last "scaled"
1389   int lastNumberRows_;
1390   /// Continuous model
1391   ClpSimplex * continuousModel_;
1392   /// Possible disaster handler
1393   OsiClpDisasterHandler * disasterHandler_ ;
1394   /// Fake objective
1395   ClpLinearObjective * fakeObjective_;
1396   /// Row scale factors (has inverse at end)
1397   CoinDoubleArrayWithLength rowScale_;
1398   /// Column scale factors (has inverse at end)
1399   CoinDoubleArrayWithLength columnScale_;
1400   //@}
1401 };
1402 
1403 class OsiClpDisasterHandler : public ClpDisasterHandler {
1404 public:
1405   /**@name Virtual methods that the derived classe should provide.
1406   */
1407   //@{
1408   /// Into simplex
1409   virtual void intoSimplex() override;
1410   /// Checks if disaster
1411   virtual bool check() const override ;
1412   /// saves information for next attempt
1413   virtual void saveInfo() override;
1414   /// Type of disaster 0 can fix, 1 abort
1415   virtual int typeOfDisaster() override;
1416   //@}
1417 
1418 
1419   /**@name Constructors, destructor */
1420 
1421   //@{
1422   /** Default constructor. */
1423   OsiClpDisasterHandler(OsiClpSolverInterface * model = nullptr);
1424   /** Destructor */
1425   virtual ~OsiClpDisasterHandler();
1426   // Copy
1427   OsiClpDisasterHandler(const OsiClpDisasterHandler&);
1428   // Assignment
1429   OsiClpDisasterHandler& operator=(const OsiClpDisasterHandler&);
1430   /// Clone
1431   virtual ClpDisasterHandler * clone() const override;
1432 
1433   //@}
1434 
1435   /**@name Sets/gets */
1436 
1437   //@{
1438   /** set model. */
1439   void setOsiModel(OsiClpSolverInterface * model);
1440   /// Get model
osiModel() const1441   inline OsiClpSolverInterface * osiModel() const
1442   { return osiModel_;}
1443   /// Set where from
setWhereFrom(int value)1444   inline void setWhereFrom(int value)
1445   { whereFrom_=value;}
1446   /// Get where from
whereFrom() const1447   inline int whereFrom() const
1448   { return whereFrom_;}
1449   /// Set phase
setPhase(int value)1450   inline void setPhase(int value)
1451   { phase_=value;}
1452   /// Get phase
phase() const1453   inline int phase() const
1454   { return phase_;}
1455   /// are we in trouble
inTrouble() const1456   inline bool inTrouble() const
1457   { return inTrouble_;}
1458 
1459   //@}
1460 
1461 
1462 protected:
1463   /**@name Data members
1464      The data members are protected to allow access for derived classes. */
1465   //@{
1466   /// Pointer to model
1467   OsiClpSolverInterface * osiModel_;
1468   /** Where from
1469       0 dual (resolve)
1470       1 crunch
1471       2 primal (resolve)
1472       4 dual (initialSolve)
1473       6 primal (initialSolve)
1474   */
1475   int whereFrom_;
1476   /** phase
1477       0 initial
1478       1 trying continuing with back in and maybe different perturb
1479       2 trying continuing with back in and different scaling
1480       3 trying dual from all slack
1481       4 trying primal from previous stored basis
1482   */
1483   int phase_;
1484   /// Are we in trouble
1485   bool inTrouble_;
1486   //@}
1487 };
1488 // So unit test can find out if NDEBUG set
1489 bool OsiClpHasNDEBUG();
1490 //#############################################################################
1491 /** A function that tests the methods in the OsiClpSolverInterface class. */
1492 void OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir);
1493 #endif
1494