summaryrefslogtreecommitdiff
path: root/thirdparty/windows/include/coin/OsiClpSolverInterface.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/windows/include/coin/OsiClpSolverInterface.hpp')
-rw-r--r--thirdparty/windows/include/coin/OsiClpSolverInterface.hpp1509
1 files changed, 1509 insertions, 0 deletions
diff --git a/thirdparty/windows/include/coin/OsiClpSolverInterface.hpp b/thirdparty/windows/include/coin/OsiClpSolverInterface.hpp
new file mode 100644
index 0000000..ebc7e64
--- /dev/null
+++ b/thirdparty/windows/include/coin/OsiClpSolverInterface.hpp
@@ -0,0 +1,1509 @@
+// $Id$
+// Copyright (C) 2000, International Business Machines
+// Corporation and others. All Rights Reserved.
+// This code is licensed under the terms of the Eclipse Public License (EPL).
+
+
+#ifndef OsiClpSolverInterface_H
+#define OsiClpSolverInterface_H
+
+#include <string>
+#include <cfloat>
+#include <map>
+
+#include "ClpSimplex.hpp"
+#include "ClpLinearObjective.hpp"
+#include "CoinPackedMatrix.hpp"
+#include "OsiSolverInterface.hpp"
+#include "CoinWarmStartBasis.hpp"
+#include "ClpEventHandler.hpp"
+#include "ClpNode.hpp"
+#include "CoinIndexedVector.hpp"
+#include "CoinFinite.hpp"
+
+class OsiRowCut;
+class OsiClpUserSolver;
+class OsiClpDisasterHandler;
+class CoinSet;
+static const double OsiClpInfinity = COIN_DBL_MAX;
+
+//#############################################################################
+
+/** Clp Solver Interface
+
+Instantiation of OsiClpSolverInterface for the Model Algorithm.
+
+*/
+
+class OsiClpSolverInterface :
+ virtual public OsiSolverInterface {
+ friend void OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir);
+
+public:
+ //---------------------------------------------------------------------------
+ /**@name Solve methods */
+ //@{
+ /// Solve initial LP relaxation
+ virtual void initialSolve();
+
+ /// Resolve an LP relaxation after problem modification
+ virtual void resolve();
+
+ /// Resolve an LP relaxation after problem modification (try GUB)
+ virtual void resolveGub(int needed);
+
+ /// Invoke solver's built-in enumeration algorithm
+ virtual void branchAndBound();
+
+ /** Solve when primal column and dual row solutions are near-optimal
+ options - 0 no presolve (use primal and dual)
+ 1 presolve (just use primal)
+ 2 no presolve (just use primal)
+ basis - 0 use all slack basis
+ 1 try and put some in basis
+ */
+ void crossover(int options,int basis);
+ //@}
+
+ /*! @name OsiSimplexInterface methods
+ \brief Methods for the Osi Simplex API.
+
+ The current implementation should work for both minimisation and
+ maximisation in mode 1 (tableau access). In mode 2 (single pivot), only
+ minimisation is supported as of 100907.
+ */
+ //@{
+ /** \brief Simplex API capability.
+
+ Returns
+ - 0 if no simplex API
+ - 1 if can just do getBInv etc
+ - 2 if has all OsiSimplex methods
+ */
+ virtual int canDoSimplexInterface() const;
+
+ /*! \brief Enables simplex mode 1 (tableau access)
+
+ Tells solver that calls to getBInv etc are about to take place.
+ Underlying code may need mutable as this may be called from
+ CglCut::generateCuts which is const. If that is too horrific then
+ each solver e.g. BCP or CBC will have to do something outside
+ main loop.
+ */
+ virtual void enableFactorization() const;
+
+ /*! \brief Undo any setting changes made by #enableFactorization */
+ virtual void disableFactorization() const;
+
+ /** Returns true if a basis is available
+ AND problem is optimal. This should be used to see if
+ the BInvARow type operations are possible and meaningful.
+ */
+ virtual bool basisIsAvailable() const;
+
+ /** The following two methods may be replaced by the
+ methods of OsiSolverInterface using OsiWarmStartBasis if:
+ 1. OsiWarmStartBasis resize operation is implemented
+ more efficiently and
+ 2. It is ensured that effects on the solver are the same
+
+ Returns a basis status of the structural/artificial variables
+ At present as warm start i.e 0 free, 1 basic, 2 upper, 3 lower
+
+ NOTE artificials are treated as +1 elements so for <= rhs
+ artificial will be at lower bound if constraint is tight
+
+ This means that Clpsimplex flips artificials as it works
+ in terms of row activities
+ */
+ virtual void getBasisStatus(int* cstat, int* rstat) const;
+
+ /** Set the status of structural/artificial variables and
+ factorize, update solution etc
+
+ NOTE artificials are treated as +1 elements so for <= rhs
+ artificial will be at lower bound if constraint is tight
+
+ This means that Clpsimplex flips artificials as it works
+ in terms of row activities
+ Returns 0 if OK, 1 if problem is bad e.g. duplicate elements, too large ...
+ */
+ virtual int setBasisStatus(const int* cstat, const int* rstat);
+
+ ///Get the reduced gradient for the cost vector c
+ virtual void getReducedGradient(double* columnReducedCosts,
+ double * duals,
+ const double * c) const ;
+
+ ///Get a row of the tableau (slack part in slack if not NULL)
+ virtual void getBInvARow(int row, double* z, double * slack=NULL) const;
+
+ /** Get a row of the tableau (slack part in slack if not NULL)
+ If keepScaled is true then scale factors not applied after so
+ user has to use coding similar to what is in this method
+ */
+ virtual void getBInvARow(int row, CoinIndexedVector * z, CoinIndexedVector * slack=NULL,
+ bool keepScaled=false) const;
+
+ ///Get a row of the basis inverse
+ virtual void getBInvRow(int row, double* z) const;
+
+ ///Get a column of the tableau
+ virtual void getBInvACol(int col, double* vec) const ;
+
+ ///Get a column of the tableau
+ virtual void getBInvACol(int col, CoinIndexedVector * vec) const ;
+
+ /** Update (i.e. ftran) the vector passed in.
+ Unscaling is applied after - can't be applied before
+ */
+
+ virtual void getBInvACol(CoinIndexedVector * vec) const ;
+
+ ///Get a column of the basis inverse
+ virtual void getBInvCol(int col, double* vec) const ;
+
+ /** Get basic indices (order of indices corresponds to the
+ order of elements in a vector retured by getBInvACol() and
+ getBInvCol()).
+ */
+ virtual void getBasics(int* index) const;
+
+ /*! \brief Enables simplex mode 2 (individual pivot control)
+
+ This method is supposed to ensure that all typical things (like
+ reduced costs, etc.) are updated when individual pivots are executed
+ and can be queried by other methods.
+ */
+ virtual void enableSimplexInterface(bool doingPrimal);
+ /// Copy across enabled stuff from one solver to another
+ void copyEnabledSuff(OsiClpSolverInterface & rhs);
+
+ /*! \brief Undo setting changes made by #enableSimplexInterface */
+ virtual void disableSimplexInterface();
+ /// Copy across enabled stuff from one solver to another
+ void copyEnabledStuff(ClpSimplex & rhs);
+
+ /** Perform a pivot by substituting a colIn for colOut in the basis.
+ The status of the leaving variable is given in statOut. Where
+ 1 is to upper bound, -1 to lower bound
+ Return code is 0 for okay,
+ 1 if inaccuracy forced re-factorization (should be okay) and
+ -1 for singular factorization
+ */
+ virtual int pivot(int colIn, int colOut, int outStatus);
+
+ /** Obtain a result of the primal pivot
+ Outputs: colOut -- leaving column, outStatus -- its status,
+ t -- step size, and, if dx!=NULL, *dx -- primal ray direction.
+ Inputs: colIn -- entering column, sign -- direction of its change (+/-1).
+ Both for colIn and colOut, artificial variables are index by
+ the negative of the row index minus 1.
+ Return code (for now): 0 -- leaving variable found,
+ -1 -- everything else?
+ Clearly, more informative set of return values is required
+ Primal and dual solutions are updated
+ */
+ virtual int primalPivotResult(int colIn, int sign,
+ int& colOut, int& outStatus,
+ double& t, CoinPackedVector* dx);
+
+ /** Obtain a result of the dual pivot (similar to the previous method)
+ Differences: entering variable and a sign of its change are now
+ the outputs, the leaving variable and its statuts -- the inputs
+ If dx!=NULL, then *dx contains dual ray
+ Return code: same
+ */
+ virtual int dualPivotResult(int& colIn, int& sign,
+ int colOut, int outStatus,
+ double& t, CoinPackedVector* dx);
+
+
+ //@}
+ //---------------------------------------------------------------------------
+ /**@name Parameter set/get methods
+
+ The set methods return true if the parameter was set to the given value,
+ false otherwise. There can be various reasons for failure: the given
+ parameter is not applicable for the solver (e.g., refactorization
+ frequency for the clp algorithm), the parameter is not yet implemented
+ for the solver or simply the value of the parameter is out of the range
+ the solver accepts. If a parameter setting call returns false check the
+ details of your solver.
+
+ The get methods return true if the given parameter is applicable for the
+ solver and is implemented. In this case the value of the parameter is
+ returned in the second argument. Otherwise they return false.
+ */
+ //@{
+ // Set an integer parameter
+ bool setIntParam(OsiIntParam key, int value);
+ // Set an double parameter
+ bool setDblParam(OsiDblParam key, double value);
+ // Set a string parameter
+ bool setStrParam(OsiStrParam key, const std::string & value);
+ // Get an integer parameter
+ bool getIntParam(OsiIntParam key, int& value) const;
+ // Get an double parameter
+ bool getDblParam(OsiDblParam key, double& value) const;
+ // Get a string parameter
+ bool getStrParam(OsiStrParam key, std::string& value) const;
+ // Set a hint parameter - overrides OsiSolverInterface
+ virtual bool setHintParam(OsiHintParam key, bool yesNo=true,
+ OsiHintStrength strength=OsiHintTry,
+ void * otherInformation=NULL);
+ //@}
+
+ //---------------------------------------------------------------------------
+ ///@name Methods returning info on how the solution process terminated
+ //@{
+ /// Are there a numerical difficulties?
+ virtual bool isAbandoned() const;
+ /// Is optimality proven?
+ virtual bool isProvenOptimal() const;
+ /// Is primal infeasiblity proven?
+ virtual bool isProvenPrimalInfeasible() const;
+ /// Is dual infeasiblity proven?
+ virtual bool isProvenDualInfeasible() const;
+ /// Is the given primal objective limit reached?
+ virtual bool isPrimalObjectiveLimitReached() const;
+ /// Is the given dual objective limit reached?
+ virtual bool isDualObjectiveLimitReached() const;
+ /// Iteration limit reached?
+ virtual bool isIterationLimitReached() const;
+ //@}
+
+ //---------------------------------------------------------------------------
+ /**@name WarmStart related methods */
+ //@{
+
+ /*! \brief Get an empty warm start object
+
+ This routine returns an empty CoinWarmStartBasis object. Its purpose is
+ to provide a way to give a client a warm start basis object of the
+ appropriate type, which can resized and modified as desired.
+ */
+
+ virtual CoinWarmStart *getEmptyWarmStart () const;
+
+ /// Get warmstarting information
+ virtual CoinWarmStart* getWarmStart() const;
+ /// Get warmstarting information
+ inline CoinWarmStartBasis* getPointerToWarmStart()
+ { return &basis_;}
+ /// Get warmstarting information
+ inline const CoinWarmStartBasis* getConstPointerToWarmStart() const
+ { return &basis_;}
+ /** Set warmstarting information. Return true/false depending on whether
+ the warmstart information was accepted or not. */
+ virtual bool setWarmStart(const CoinWarmStart* warmstart);
+ /** \brief Get warm start information.
+
+ Return warm start information for the current state of the solver
+ interface. If there is no valid warm start information, an empty warm
+ start object wil be returned. This does not necessarily create an
+ object - may just point to one. must Delete set true if user
+ should delete returned object.
+ OsiClp version always returns pointer and false.
+ */
+ virtual CoinWarmStart* getPointerToWarmStart(bool & mustDelete) ;
+
+ /// Set column status in ClpSimplex and warmStart
+ void setColumnStatus(int iColumn, ClpSimplex::Status status);
+
+ //@}
+
+ //---------------------------------------------------------------------------
+ /**@name Hotstart related methods (primarily used in strong branching).
+ The user can create a hotstart (a snapshot) of the optimization process
+ then reoptimize over and over again always starting from there.<br>
+ <strong>NOTE</strong>: between hotstarted optimizations only
+ bound changes are allowed. */
+ //@{
+ /// Create a hotstart point of the optimization process
+ virtual void markHotStart();
+ /// Optimize starting from the hotstart
+ virtual void solveFromHotStart();
+ /// Delete the snapshot
+ virtual void unmarkHotStart();
+ /** Start faster dual - returns negative if problems 1 if infeasible,
+ Options to pass to solver
+ 1 - create external reduced costs for columns
+ 2 - create external reduced costs for rows
+ 4 - create external row activity (columns always done)
+ Above only done if feasible
+ When set resolve does less work
+ */
+ int startFastDual(int options);
+ /// Stop fast dual
+ void stopFastDual();
+ /// Sets integer tolerance and increment
+ void setStuff(double tolerance,double increment);
+ /// Return a conflict analysis cut from small model
+ OsiRowCut * smallModelCut(const double * originalLower, const double * originalUpper,
+ int numberRowsAtContinuous,const int * whichGenerator,
+ int typeCut=0);
+ /** Return a conflict analysis cut from model
+ If type is 0 then genuine cut, if 1 then only partially processed
+ */
+ OsiRowCut * modelCut(const double * originalLower, const double * originalUpper,
+ int numberRowsAtContinuous,const int * whichGenerator,
+ int typeCut=0);
+ //@}
+
+ //---------------------------------------------------------------------------
+ /**@name Problem information methods
+
+ These methods call the solver's query routines to return
+ information about the problem referred to by the current object.
+ Querying a problem that has no data associated with it result in
+ zeros for the number of rows and columns, and NULL pointers from
+ the methods that return vectors.
+
+ Const pointers returned from any data-query method are valid as
+ long as the data is unchanged and the solver is not called.
+ */
+ //@{
+ /**@name Methods related to querying the input data */
+ //@{
+ /// Get number of columns
+ virtual int getNumCols() const {
+ return modelPtr_->numberColumns(); }
+
+ /// Get number of rows
+ virtual int getNumRows() const {
+ return modelPtr_->numberRows(); }
+
+ /// Get number of nonzero elements
+ virtual int getNumElements() const {
+ int retVal = 0;
+ const CoinPackedMatrix * matrix =modelPtr_->matrix();
+ if ( matrix != NULL ) retVal=matrix->getNumElements();
+ return retVal; }
+
+ /// Return name of row if one exists or Rnnnnnnn
+ /// maxLen is currently ignored and only there to match the signature from the base class!
+ virtual std::string getRowName(int rowIndex,
+ unsigned maxLen = static_cast<unsigned>(std::string::npos)) const;
+
+ /// Return name of column if one exists or Cnnnnnnn
+ /// maxLen is currently ignored and only there to match the signature from the base class!
+ virtual std::string getColName(int colIndex,
+ unsigned maxLen = static_cast<unsigned>(std::string::npos)) const;
+
+
+ /// Get pointer to array[getNumCols()] of column lower bounds
+ virtual const double * getColLower() const { return modelPtr_->columnLower(); }
+
+ /// Get pointer to array[getNumCols()] of column upper bounds
+ virtual const double * getColUpper() const { return modelPtr_->columnUpper(); }
+
+ /** Get pointer to array[getNumRows()] of row constraint senses.
+ <ul>
+ <li>'L' <= constraint
+ <li>'E' = constraint
+ <li>'G' >= constraint
+ <li>'R' ranged constraint
+ <li>'N' free constraint
+ </ul>
+ */
+ virtual const char * getRowSense() const;
+
+ /** Get pointer to array[getNumRows()] of rows right-hand sides
+ <ul>
+ <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i]
+ <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i]
+ <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i]
+ <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0
+ </ul>
+ */
+ virtual const double * getRightHandSide() const ;
+
+ /** Get pointer to array[getNumRows()] of row ranges.
+ <ul>
+ <li> if rowsense()[i] == 'R' then
+ rowrange()[i] == rowupper()[i] - rowlower()[i]
+ <li> if rowsense()[i] != 'R' then
+ rowrange()[i] is undefined
+ </ul>
+ */
+ virtual const double * getRowRange() const ;
+
+ /// Get pointer to array[getNumRows()] of row lower bounds
+ virtual const double * getRowLower() const { return modelPtr_->rowLower(); }
+
+ /// Get pointer to array[getNumRows()] of row upper bounds
+ virtual const double * getRowUpper() const { return modelPtr_->rowUpper(); }
+
+ /// Get pointer to array[getNumCols()] of objective function coefficients
+ virtual const double * getObjCoefficients() const
+ { if (fakeMinInSimplex_)
+ return linearObjective_ ;
+ else
+ return modelPtr_->objective(); }
+
+ /// Get objective function sense (1 for min (default), -1 for max)
+ virtual double getObjSense() const
+ { return ((fakeMinInSimplex_)?-modelPtr_->optimizationDirection():
+ modelPtr_->optimizationDirection()); }
+
+ /// Return true if column is continuous
+ virtual bool isContinuous(int colNumber) const;
+ /// Return true if variable is binary
+ virtual bool isBinary(int colIndex) const;
+
+ /** Return true if column is integer.
+ Note: This function returns true if the the column
+ is binary or a general integer.
+ */
+ virtual bool isInteger(int colIndex) const;
+
+ /// Return true if variable is general integer
+ virtual bool isIntegerNonBinary(int colIndex) const;
+
+ /// Return true if variable is binary and not fixed at either bound
+ virtual bool isFreeBinary(int colIndex) const;
+ /** Return array of column length
+ 0 - continuous
+ 1 - binary (may get fixed later)
+ 2 - general integer (may get fixed later)
+ */
+ virtual const char * getColType(bool refresh=false) const;
+
+ /** Return true if column is integer but does not have to
+ be declared as such.
+ Note: This function returns true if the the column
+ is binary or a general integer.
+ */
+ bool isOptionalInteger(int colIndex) const;
+ /** Set the index-th variable to be an optional integer variable */
+ void setOptionalInteger(int index);
+
+ /// Get pointer to row-wise copy of matrix
+ virtual const CoinPackedMatrix * getMatrixByRow() const;
+
+ /// Get pointer to column-wise copy of matrix
+ virtual const CoinPackedMatrix * getMatrixByCol() const;
+
+ /// Get pointer to mutable column-wise copy of matrix
+ virtual CoinPackedMatrix * getMutableMatrixByCol() const;
+
+ /// Get solver's value for infinity
+ virtual double getInfinity() const { return OsiClpInfinity; }
+ //@}
+
+ /**@name Methods related to querying the solution */
+ //@{
+ /// Get pointer to array[getNumCols()] of primal solution vector
+ virtual const double * getColSolution() const;
+
+ /// Get pointer to array[getNumRows()] of dual prices
+ virtual const double * getRowPrice() const;
+
+ /// Get a pointer to array[getNumCols()] of reduced costs
+ virtual const double * getReducedCost() const;
+
+ /** Get pointer to array[getNumRows()] of row activity levels (constraint
+ matrix times the solution vector */
+ virtual const double * getRowActivity() const;
+
+ /// Get objective function value
+ virtual double getObjValue() const;
+
+ /** Get how many iterations it took to solve the problem (whatever
+ "iteration" mean to the solver. */
+ virtual int getIterationCount() const
+ { return modelPtr_->numberIterations(); }
+
+ /** Get as many dual rays as the solver can provide. (In case of proven
+ primal infeasibility there should be at least one.)
+
+ The first getNumRows() ray components will always be associated with
+ the row duals (as returned by getRowPrice()). If \c fullRay is true,
+ the final getNumCols() entries will correspond to the ray components
+ associated with the nonbasic variables. If the full ray is requested
+ and the method cannot provide it, it will throw an exception.
+
+ <strong>NOTE for implementers of solver interfaces:</strong> <br>
+ The double pointers in the vector should point to arrays of length
+ getNumRows() and they should be allocated via new[]. <br>
+
+ <strong>NOTE for users of solver interfaces:</strong> <br>
+ It is the user's responsibility to free the double pointers in the
+ vector using delete[].
+ */
+ virtual std::vector<double*> getDualRays(int maxNumRays,
+ bool fullRay = false) const;
+ /** Get as many primal rays as the solver can provide. (In case of proven
+ dual infeasibility there should be at least one.)
+
+ <strong>NOTE for implementers of solver interfaces:</strong> <br>
+ The double pointers in the vector should point to arrays of length
+ getNumCols() and they should be allocated via new[]. <br>
+
+ <strong>NOTE for users of solver interfaces:</strong> <br>
+ It is the user's responsibility to free the double pointers in the
+ vector using delete[].
+ */
+ virtual std::vector<double*> getPrimalRays(int maxNumRays) const;
+
+ //@}
+ //@}
+
+ //---------------------------------------------------------------------------
+
+ /**@name Problem modifying methods */
+ //@{
+ //-------------------------------------------------------------------------
+ /**@name Changing bounds on variables and constraints */
+ //@{
+ /** Set an objective function coefficient */
+ virtual void setObjCoeff( int elementIndex, double elementValue );
+
+ /** Set a single column lower bound<br>
+ Use -DBL_MAX for -infinity. */
+ virtual void setColLower( int elementIndex, double elementValue );
+
+ /** Set a single column upper bound<br>
+ Use DBL_MAX for infinity. */
+ virtual void setColUpper( int elementIndex, double elementValue );
+
+ /** Set a single column lower and upper bound */
+ virtual void setColBounds( int elementIndex,
+ double lower, double upper );
+
+ /** Set the bounds on a number of columns simultaneously<br>
+ The default implementation just invokes setColLower() and
+ setColUpper() over and over again.
+ @param indexFirst,indexLast pointers to the beginning and after the
+ end of the array of the indices of the variables whose
+ <em>either</em> bound changes
+ @param boundList the new lower/upper bound pairs for the variables
+ */
+ virtual void setColSetBounds(const int* indexFirst,
+ const int* indexLast,
+ const double* boundList);
+
+ /** Set a single row lower bound<br>
+ Use -DBL_MAX for -infinity. */
+ virtual void setRowLower( int elementIndex, double elementValue );
+
+ /** Set a single row upper bound<br>
+ Use DBL_MAX for infinity. */
+ virtual void setRowUpper( int elementIndex, double elementValue ) ;
+
+ /** Set a single row lower and upper bound */
+ virtual void setRowBounds( int elementIndex,
+ double lower, double upper ) ;
+
+ /** Set the type of a single row<br> */
+ virtual void setRowType(int index, char sense, double rightHandSide,
+ double range);
+
+ /** Set the bounds on a number of rows simultaneously<br>
+ The default implementation just invokes setRowLower() and
+ setRowUpper() over and over again.
+ @param indexFirst,indexLast pointers to the beginning and after the
+ end of the array of the indices of the constraints whose
+ <em>either</em> bound changes
+ @param boundList the new lower/upper bound pairs for the constraints
+ */
+ virtual void setRowSetBounds(const int* indexFirst,
+ const int* indexLast,
+ const double* boundList);
+
+ /** Set the type of a number of rows simultaneously<br>
+ The default implementation just invokes setRowType()
+ over and over again.
+ @param indexFirst,indexLast pointers to the beginning and after the
+ end of the array of the indices of the constraints whose
+ <em>any</em> characteristics changes
+ @param senseList the new senses
+ @param rhsList the new right hand sides
+ @param rangeList the new ranges
+ */
+ virtual void setRowSetTypes(const int* indexFirst,
+ const int* indexLast,
+ const char* senseList,
+ const double* rhsList,
+ const double* rangeList);
+ /** Set the objective coefficients for all columns
+ array [getNumCols()] is an array of values for the objective.
+ This defaults to a series of set operations and is here for speed.
+ */
+ virtual void setObjective(const double * array);
+
+ /** Set the lower bounds for all columns
+ array [getNumCols()] is an array of values for the objective.
+ This defaults to a series of set operations and is here for speed.
+ */
+ virtual void setColLower(const double * array);
+
+ /** Set the upper bounds for all columns
+ array [getNumCols()] is an array of values for the objective.
+ This defaults to a series of set operations and is here for speed.
+ */
+ virtual void setColUpper(const double * array);
+
+// using OsiSolverInterface::setRowName ;
+ /// Set name of row
+// virtual void setRowName(int rowIndex, std::string & name) ;
+ virtual void setRowName(int rowIndex, std::string name) ;
+
+// using OsiSolverInterface::setColName ;
+ /// Set name of column
+// virtual void setColName(int colIndex, std::string & name) ;
+ virtual void setColName(int colIndex, std::string name) ;
+
+ //@}
+
+ //-------------------------------------------------------------------------
+ /**@name Integrality related changing methods */
+ //@{
+ /** Set the index-th variable to be a continuous variable */
+ virtual void setContinuous(int index);
+ /** Set the index-th variable to be an integer variable */
+ virtual void setInteger(int index);
+ /** Set the variables listed in indices (which is of length len) to be
+ continuous variables */
+ virtual void setContinuous(const int* indices, int len);
+ /** Set the variables listed in indices (which is of length len) to be
+ integer variables */
+ virtual void setInteger(const int* indices, int len);
+ /// Number of SOS sets
+ inline int numberSOS() const
+ { return numberSOS_;}
+ /// SOS set info
+ inline const CoinSet * setInfo() const
+ { return setInfo_;}
+ /** \brief Identify integer variables and SOS and create corresponding objects.
+
+ Record integer variables and create an OsiSimpleInteger object for each
+ one. All existing OsiSimpleInteger objects will be destroyed.
+ If the solver supports SOS then do the same for SOS.
+ If justCount then no objects created and we just store numberIntegers_
+ Returns number of SOS
+ */
+
+ virtual int findIntegersAndSOS(bool justCount);
+ //@}
+
+ //-------------------------------------------------------------------------
+ /// Set objective function sense (1 for min (default), -1 for max,)
+ virtual void setObjSense(double s )
+ { modelPtr_->setOptimizationDirection( s < 0 ? -1 : 1); }
+
+ /** Set the primal solution column values
+
+ colsol[numcols()] is an array of values of the problem column
+ variables. These values are copied to memory owned by the
+ solver object or the solver. They will be returned as the
+ result of colsol() until changed by another call to
+ setColsol() or by a call to any solver routine. Whether the
+ solver makes use of the solution in any way is
+ solver-dependent.
+ */
+ virtual void setColSolution(const double * colsol);
+
+ /** Set dual solution vector
+
+ rowprice[numrows()] is an array of values of the problem row
+ dual variables. These values are copied to memory owned by the
+ solver object or the solver. They will be returned as the
+ result of rowprice() until changed by another call to
+ setRowprice() or by a call to any solver routine. Whether the
+ solver makes use of the solution in any way is
+ solver-dependent.
+ */
+ virtual void setRowPrice(const double * rowprice);
+
+ //-------------------------------------------------------------------------
+ /**@name Methods to expand a problem.<br>
+ Note that if a column is added then by default it will correspond to a
+ continuous variable. */
+ //@{
+
+ //using OsiSolverInterface::addCol ;
+ /** */
+ virtual void addCol(const CoinPackedVectorBase& vec,
+ const double collb, const double colub,
+ const double obj);
+ /*! \brief Add a named column (primal variable) to the problem.
+ */
+ virtual void addCol(const CoinPackedVectorBase& vec,
+ const double collb, const double colub,
+ const double obj, std::string name) ;
+ /** Add a column (primal variable) to the problem. */
+ virtual void addCol(int numberElements, const int * rows, const double * elements,
+ const double collb, const double colub,
+ const double obj) ;
+ /*! \brief Add a named column (primal variable) to the problem.
+ */
+ virtual void addCol(int numberElements,
+ const int* rows, const double* elements,
+ const double collb, const double colub,
+ const double obj, std::string name) ;
+ /** */
+ virtual void addCols(const int numcols,
+ const CoinPackedVectorBase * const * cols,
+ const double* collb, const double* colub,
+ const double* obj);
+ /** */
+ virtual void addCols(const int numcols,
+ const int * columnStarts, const int * rows, const double * elements,
+ const double* collb, const double* colub,
+ const double* obj);
+ /** */
+ virtual void deleteCols(const int num, const int * colIndices);
+
+ /** */
+ virtual void addRow(const CoinPackedVectorBase& vec,
+ const double rowlb, const double rowub);
+ /** */
+ /*! \brief Add a named row (constraint) to the problem.
+
+ The default implementation adds the row, then changes the name. This
+ can surely be made more efficient within an OsiXXX class.
+ */
+ virtual void addRow(const CoinPackedVectorBase& vec,
+ const double rowlb, const double rowub,
+ std::string name) ;
+ virtual void addRow(const CoinPackedVectorBase& vec,
+ const char rowsen, const double rowrhs,
+ const double rowrng);
+ /** Add a row (constraint) to the problem. */
+ virtual void addRow(int numberElements, const int * columns, const double * element,
+ const double rowlb, const double rowub) ;
+ /*! \brief Add a named row (constraint) to the problem.
+ */
+ virtual void addRow(const CoinPackedVectorBase& vec,
+ const char rowsen, const double rowrhs,
+ const double rowrng, std::string name) ;
+ /** */
+ virtual void addRows(const int numrows,
+ const CoinPackedVectorBase * const * rows,
+ const double* rowlb, const double* rowub);
+ /** */
+ virtual void addRows(const int numrows,
+ const CoinPackedVectorBase * const * rows,
+ const char* rowsen, const double* rowrhs,
+ const double* rowrng);
+
+ /** */
+ virtual void addRows(const int numrows,
+ const int * rowStarts, const int * columns, const double * element,
+ const double* rowlb, const double* rowub);
+ ///
+ void modifyCoefficient(int row, int column, double newElement,
+ bool keepZero=false)
+ {modelPtr_->modifyCoefficient(row,column,newElement, keepZero);}
+
+ /** */
+ virtual void deleteRows(const int num, const int * rowIndices);
+ /** If solver wants it can save a copy of "base" (continuous) model here
+ */
+ virtual void saveBaseModel() ;
+ /** Strip off rows to get to this number of rows.
+ If solver wants it can restore a copy of "base" (continuous) model here
+ */
+ virtual void restoreBaseModel(int numberRows);
+
+ //-----------------------------------------------------------------------
+ /** Apply a collection of row cuts which are all effective.
+ applyCuts seems to do one at a time which seems inefficient.
+ */
+ virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts);
+ /** Apply a collection of row cuts which are all effective.
+ applyCuts seems to do one at a time which seems inefficient.
+ This uses array of pointers
+ */
+ virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts);
+ /** Apply a collection of cuts.
+
+ Only cuts which have an <code>effectiveness >= effectivenessLb</code>
+ are applied.
+ <ul>
+ <li> ReturnCode.getNumineffective() -- number of cuts which were
+ not applied because they had an
+ <code>effectiveness < effectivenessLb</code>
+ <li> ReturnCode.getNuminconsistent() -- number of invalid cuts
+ <li> ReturnCode.getNuminconsistentWrtIntegerModel() -- number of
+ cuts that are invalid with respect to this integer model
+ <li> ReturnCode.getNuminfeasible() -- number of cuts that would
+ make this integer model infeasible
+ <li> ReturnCode.getNumApplied() -- number of integer cuts which
+ were applied to the integer model
+ <li> cs.size() == getNumineffective() +
+ getNuminconsistent() +
+ getNuminconsistentWrtIntegerModel() +
+ getNuminfeasible() +
+ getNumApplied()
+ </ul>
+ */
+ virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs,
+ double effectivenessLb = 0.0);
+
+ //@}
+ //@}
+
+ //---------------------------------------------------------------------------
+
+public:
+
+ /**@name Methods to input a problem */
+ //@{
+ /** Load in an problem by copying the arguments (the constraints on the
+ rows are given by lower and upper bounds). If a pointer is NULL then the
+ following values are the default:
+ <ul>
+ <li> <code>colub</code>: all columns have upper bound infinity
+ <li> <code>collb</code>: all columns have lower bound 0
+ <li> <code>rowub</code>: all rows have upper bound infinity
+ <li> <code>rowlb</code>: all rows have lower bound -infinity
+ <li> <code>obj</code>: all variables have 0 objective coefficient
+ </ul>
+ */
+ virtual void loadProblem(const CoinPackedMatrix& matrix,
+ const double* collb, const double* colub,
+ const double* obj,
+ const double* rowlb, const double* rowub);
+
+ /** Load in an problem by assuming ownership of the arguments (the
+ constraints on the rows are given by lower and upper bounds). For
+ default values see the previous method. <br>
+ <strong>WARNING</strong>: The arguments passed to this method will be
+ freed using the C++ <code>delete</code> and <code>delete[]</code>
+ functions.
+ */
+ virtual void assignProblem(CoinPackedMatrix*& matrix,
+ double*& collb, double*& colub, double*& obj,
+ double*& rowlb, double*& rowub);
+
+ /** Load in an problem by copying the arguments (the constraints on the
+ rows are given by sense/rhs/range triplets). If a pointer is NULL then the
+ following values are the default:
+ <ul>
+ <li> <code>colub</code>: all columns have upper bound infinity
+ <li> <code>collb</code>: all columns have lower bound 0
+ <li> <code>obj</code>: all variables have 0 objective coefficient
+ <li> <code>rowsen</code>: all rows are >=
+ <li> <code>rowrhs</code>: all right hand sides are 0
+ <li> <code>rowrng</code>: 0 for the ranged rows
+ </ul>
+ */
+ virtual void loadProblem(const CoinPackedMatrix& matrix,
+ const double* collb, const double* colub,
+ const double* obj,
+ const char* rowsen, const double* rowrhs,
+ const double* rowrng);
+
+ /** Load in an problem by assuming ownership of the arguments (the
+ constraints on the rows are given by sense/rhs/range triplets). For
+ default values see the previous method. <br>
+ <strong>WARNING</strong>: The arguments passed to this method will be
+ freed using the C++ <code>delete</code> and <code>delete[]</code>
+ functions.
+ */
+ virtual void assignProblem(CoinPackedMatrix*& matrix,
+ double*& collb, double*& colub, double*& obj,
+ char*& rowsen, double*& rowrhs,
+ double*& rowrng);
+
+ /** Just like the other loadProblem() methods except that the matrix is
+ given as a ClpMatrixBase. */
+ virtual void loadProblem(const ClpMatrixBase& matrix,
+ const double* collb, const double* colub,
+ const double* obj,
+ const double* rowlb, const double* rowub) ;
+
+ /** Just like the other loadProblem() methods except that the matrix is
+ given in a standard column major ordered format (without gaps). */
+ virtual void loadProblem(const int numcols, const int numrows,
+ const CoinBigIndex * start, const int* index,
+ const double* value,
+ const double* collb, const double* colub,
+ const double* obj,
+ const double* rowlb, const double* rowub);
+
+ /** Just like the other loadProblem() methods except that the matrix is
+ given in a standard column major ordered format (without gaps). */
+ virtual void loadProblem(const int numcols, const int numrows,
+ const CoinBigIndex * start, const int* index,
+ const double* value,
+ const double* collb, const double* colub,
+ const double* obj,
+ const char* rowsen, const double* rowrhs,
+ const double* rowrng);
+ /// This loads a model from a coinModel object - returns number of errors
+ virtual int loadFromCoinModel ( CoinModel & modelObject, bool keepSolution=false);
+
+ using OsiSolverInterface::readMps ;
+ /** Read an mps file from the given filename (defaults to Osi reader) - returns
+ number of errors (see OsiMpsReader class) */
+ virtual int readMps(const char *filename,
+ const char *extension = "mps") ;
+ /** Read an mps file from the given filename returns
+ number of errors (see OsiMpsReader class) */
+ int readMps(const char *filename,bool keepNames,bool allowErrors);
+ /// Read an mps file
+ virtual int readMps (const char *filename, const char*extension,
+ int & numberSets, CoinSet ** & sets);
+
+ /** Write the problem into an mps file of the given filename.
+ If objSense is non zero then -1.0 forces the code to write a
+ maximization objective and +1.0 to write a minimization one.
+ If 0.0 then solver can do what it wants */
+ virtual void writeMps(const char *filename,
+ const char *extension = "mps",
+ double objSense=0.0) const;
+ /** Write the problem into an mps file of the given filename,
+ names may be null. formatType is
+ 0 - normal
+ 1 - extra accuracy
+ 2 - IEEE hex (later)
+
+ Returns non-zero on I/O error
+ */
+ virtual int writeMpsNative(const char *filename,
+ const char ** rowNames, const char ** columnNames,
+ int formatType=0,int numberAcross=2,
+ double objSense=0.0) const ;
+ /// Read file in LP format (with names)
+ virtual int readLp(const char *filename, const double epsilon = 1e-5);
+ /** Write the problem into an Lp file of the given filename.
+ If objSense is non zero then -1.0 forces the code to write a
+ maximization objective and +1.0 to write a minimization one.
+ If 0.0 then solver can do what it wants.
+ This version calls writeLpNative with names */
+ virtual void writeLp(const char *filename,
+ const char *extension = "lp",
+ double epsilon = 1e-5,
+ int numberAcross = 10,
+ int decimals = 5,
+ double objSense = 0.0,
+ bool useRowNames = true) const;
+ /** Write the problem into the file pointed to by the parameter fp.
+ Other parameters are similar to
+ those of writeLp() with first parameter filename.
+ */
+ virtual void writeLp(FILE *fp,
+ double epsilon = 1e-5,
+ int numberAcross = 10,
+ int decimals = 5,
+ double objSense = 0.0,
+ bool useRowNames = true) const;
+ /**
+ I (JJF) am getting annoyed because I can't just replace a matrix.
+ The default behavior of this is do nothing so only use where that would not matter
+ e.g. strengthening a matrix for MIP
+ */
+ virtual void replaceMatrixOptional(const CoinPackedMatrix & matrix);
+ /// And if it does matter (not used at present)
+ virtual void replaceMatrix(const CoinPackedMatrix & matrix) ;
+ //@}
+
+ /**@name Message handling (extra for Clp messages).
+ Normally I presume you would want the same language.
+ If not then you could use underlying model pointer */
+ //@{
+ /** Pass in a message handler
+
+ It is the client's responsibility to destroy a message handler installed
+ by this routine; it will not be destroyed when the solver interface is
+ destroyed.
+ */
+ virtual void passInMessageHandler(CoinMessageHandler * handler);
+ /// Set language
+ void newLanguage(CoinMessages::Language language);
+ void setLanguage(CoinMessages::Language language)
+ {newLanguage(language);}
+ /// Set log level (will also set underlying solver's log level)
+ void setLogLevel(int value);
+ /// Create C++ lines to get to current state
+ void generateCpp( FILE * fp);
+ //@}
+ //---------------------------------------------------------------------------
+
+ /**@name Clp specific public interfaces */
+ //@{
+ /// Get pointer to Clp model
+ ClpSimplex * getModelPtr() const ;
+ /// Set pointer to Clp model and return old
+ inline ClpSimplex * swapModelPtr(ClpSimplex * newModel)
+ { ClpSimplex * model = modelPtr_; modelPtr_=newModel;return model;}
+ /// Get special options
+ inline unsigned int specialOptions() const
+ { return specialOptions_;}
+ void setSpecialOptions(unsigned int value);
+ /// Last algorithm used , 1 = primal, 2 = dual other unknown
+ inline int lastAlgorithm() const
+ { return lastAlgorithm_;}
+ /// Set last algorithm used , 1 = primal, 2 = dual other unknown
+ inline void setLastAlgorithm(int value)
+ { lastAlgorithm_ = value;}
+ /// Get scaling action option
+ inline int cleanupScaling() const
+ { return cleanupScaling_;}
+ /** Set Scaling option
+ When scaling is on it is possible that the scaled problem
+ is feasible but the unscaled is not. Clp returns a secondary
+ status code to that effect. This option allows for a cleanup.
+ If you use it I would suggest 1.
+ This only affects actions when scaled optimal
+ 0 - no action
+ 1 - clean up using dual if primal infeasibility
+ 2 - clean up using dual if dual infeasibility
+ 3 - clean up using dual if primal or dual infeasibility
+ 11,12,13 - as 1,2,3 but use primal
+ */
+ inline void setCleanupScaling(int value)
+ { cleanupScaling_=value;}
+ /** Get smallest allowed element in cut.
+ If smaller than this then ignored */
+ inline double smallestElementInCut() const
+ { return smallestElementInCut_;}
+ /** Set smallest allowed element in cut.
+ If smaller than this then ignored */
+ inline void setSmallestElementInCut(double value)
+ { smallestElementInCut_=value;}
+ /** Get smallest change in cut.
+ If (upper-lower)*element < this then element is
+ taken out and cut relaxed.
+ (upper-lower) is taken to be at least 1.0 and
+ this is assumed >= smallestElementInCut_
+ */
+ inline double smallestChangeInCut() const
+ { return smallestChangeInCut_;}
+ /** Set smallest change in cut.
+ If (upper-lower)*element < this then element is
+ taken out and cut relaxed.
+ (upper-lower) is taken to be at least 1.0 and
+ this is assumed >= smallestElementInCut_
+ */
+ inline void setSmallestChangeInCut(double value)
+ { smallestChangeInCut_=value;}
+ /// Pass in initial solve options
+ inline void setSolveOptions(const ClpSolve & options)
+ { solveOptions_ = options;}
+ /** Tighten bounds - lightweight or very lightweight
+ 0 - normal, 1 lightweight but just integers, 2 lightweight and all
+ */
+ virtual int tightenBounds(int lightweight=0);
+ /// See if any integer variables make infeasible other way
+ int infeasibleOtherWay(char * whichWay);
+ /// Return number of entries in L part of current factorization
+ virtual CoinBigIndex getSizeL() const;
+ /// Return number of entries in U part of current factorization
+ virtual CoinBigIndex getSizeU() const;
+ /// Get disaster handler
+ const OsiClpDisasterHandler * disasterHandler() const
+ { return disasterHandler_;}
+ /// Pass in disaster handler
+ void passInDisasterHandler(OsiClpDisasterHandler * handler);
+ /// Get fake objective
+ ClpLinearObjective * fakeObjective() const
+ { return fakeObjective_;}
+ /// Set fake objective (and take ownership)
+ void setFakeObjective(ClpLinearObjective * fakeObjective);
+ /// Set fake objective
+ void setFakeObjective(double * fakeObjective);
+ /*! \brief Set up solver for repeated use by Osi interface.
+
+ The normal usage does things like keeping factorization around so can be
+ used. Will also do things like keep scaling and row copy of matrix if
+ matrix does not change.
+
+ \p senseOfAdventure:
+ - 0 - safe stuff as above
+ - 1 - will take more risks - if it does not work then bug which will be
+ fixed
+ - 2 - don't bother doing most extreme termination checks e.g. don't bother
+ re-factorizing if less than 20 iterations.
+ - 3 - Actually safer than 1 (mainly just keeps factorization)
+
+ \p printOut
+ - -1 always skip round common messages instead of doing some work
+ - 0 skip if normal defaults
+ - 1 leaves
+ */
+ void setupForRepeatedUse(int senseOfAdventure=0, int printOut=0);
+ /// Synchronize model (really if no cuts in tree)
+ virtual void synchronizeModel();
+ /*! \brief Set special options in underlying clp solver.
+
+ Safe as const because #modelPtr_ is mutable.
+ */
+ void setSpecialOptionsMutable(unsigned int value) const;
+
+ //@}
+
+ //---------------------------------------------------------------------------
+
+ /**@name Constructors and destructors */
+ //@{
+ /// Default Constructor
+ OsiClpSolverInterface ();
+
+ /// Clone
+ virtual OsiSolverInterface * clone(bool copyData = true) const;
+
+ /// Copy constructor
+ OsiClpSolverInterface (const OsiClpSolverInterface &);
+
+ /// Borrow constructor - only delete one copy
+ OsiClpSolverInterface (ClpSimplex * rhs, bool reallyOwn=false);
+
+ /// Releases so won't error
+ void releaseClp();
+
+ /// Assignment operator
+ OsiClpSolverInterface & operator=(const OsiClpSolverInterface& rhs);
+
+ /// Destructor
+ virtual ~OsiClpSolverInterface ();
+
+ /// Resets as if default constructor
+ virtual void reset();
+ //@}
+
+ //---------------------------------------------------------------------------
+
+protected:
+ ///@name Protected methods
+ //@{
+ /** Apply a row cut (append to constraint matrix). */
+ virtual void applyRowCut(const OsiRowCut& rc);
+
+ /** Apply a column cut (adjust one or more bounds). */
+ virtual void applyColCut(const OsiColCut& cc);
+ //@}
+
+ //---------------------------------------------------------------------------
+
+protected:
+ /**@name Protected methods */
+ //@{
+ /// The real work of a copy constructor (used by copy and assignment)
+ void gutsOfDestructor();
+
+ /// Deletes all mutable stuff
+ void freeCachedResults() const;
+
+ /// Deletes all mutable stuff for row ranges etc
+ void freeCachedResults0() const;
+
+ /// Deletes all mutable stuff for matrix etc
+ void freeCachedResults1() const;
+
+ /// A method that fills up the rowsense_, rhs_ and rowrange_ arrays
+ void extractSenseRhsRange() const;
+
+ ///
+ void fillParamMaps();
+ /** Warm start
+
+ NOTE artificials are treated as +1 elements so for <= rhs
+ artificial will be at lower bound if constraint is tight
+
+ This means that Clpsimplex flips artificials as it works
+ in terms of row activities
+ */
+ CoinWarmStartBasis getBasis(ClpSimplex * model) const;
+ /** Sets up working basis as a copy of input
+
+ NOTE artificials are treated as +1 elements so for <= rhs
+ artificial will be at lower bound if constraint is tight
+
+ This means that Clpsimplex flips artificials as it works
+ in terms of row activities
+ */
+ void setBasis( const CoinWarmStartBasis & basis, ClpSimplex * model);
+ /// Crunch down problem a bit
+ void crunch();
+ /// Extend scale factors
+ void redoScaleFactors(int numberRows,const CoinBigIndex * starts,
+ const int * indices, const double * elements);
+public:
+ /** Sets up working basis as a copy of input and puts in as basis
+ */
+ void setBasis( const CoinWarmStartBasis & basis);
+ /// Just puts current basis_ into ClpSimplex model
+ inline void setBasis( )
+ { setBasis(basis_,modelPtr_);}
+ /// Warm start difference from basis_ to statusArray
+ CoinWarmStartDiff * getBasisDiff(const unsigned char * statusArray) const ;
+ /// Warm start from statusArray
+ CoinWarmStartBasis * getBasis(const unsigned char * statusArray) const ;
+ /// Delete all scale factor stuff and reset option
+ void deleteScaleFactors();
+ /// If doing fast hot start then ranges are computed
+ inline const double * upRange() const
+ { return rowActivity_;}
+ inline const double * downRange() const
+ { return columnActivity_;}
+ /// Pass in range array
+ inline void passInRanges(int * array)
+ { whichRange_=array;}
+ /// Pass in sos stuff from AMPl
+ void setSOSData(int numberSOS,const char * type,
+ const int * start,const int * indices, const double * weights=NULL);
+ /// Compute largest amount any at continuous away from bound
+ void computeLargestAway();
+ /// Get largest amount continuous away from bound
+ inline double largestAway() const
+ { return largestAway_;}
+ /// Set largest amount continuous away from bound
+ inline void setLargestAway(double value)
+ { largestAway_ = value;}
+ /// Sort of lexicographic resolve
+ void lexSolve();
+ //@}
+
+protected:
+ /**@name Protected member data */
+ //@{
+ /// Clp model represented by this class instance
+ mutable ClpSimplex * modelPtr_;
+ //@}
+ /**@name Cached information derived from the OSL model */
+ //@{
+ /// Pointer to dense vector of row sense indicators
+ mutable char *rowsense_;
+
+ /// Pointer to dense vector of row right-hand side values
+ mutable double *rhs_;
+
+ /** Pointer to dense vector of slack upper bounds for range
+ constraints (undefined for non-range rows)
+ */
+ mutable double *rowrange_;
+
+ /** A pointer to the warmstart information to be used in the hotstarts.
+ This is NOT efficient and more thought should be given to it... */
+ mutable CoinWarmStartBasis* ws_;
+ /** also save row and column information for hot starts
+ only used in hotstarts so can be casual */
+ mutable double * rowActivity_;
+ mutable double * columnActivity_;
+ /// Stuff for fast dual
+ ClpNodeStuff stuff_;
+ /// Number of SOS sets
+ int numberSOS_;
+ /// SOS set info
+ CoinSet * setInfo_;
+ /// Alternate model (hot starts) - but also could be permanent and used for crunch
+ ClpSimplex * smallModel_;
+ /// factorization for hot starts
+ ClpFactorization * factorization_;
+ /** Smallest allowed element in cut.
+ If smaller than this then ignored */
+ double smallestElementInCut_;
+ /** Smallest change in cut.
+ If (upper-lower)*element < this then element is
+ taken out and cut relaxed. */
+ double smallestChangeInCut_;
+ /// Largest amount continuous away from bound
+ double largestAway_;
+ /// Arrays for hot starts
+ char * spareArrays_;
+ /** Warmstart information to be used in resolves. */
+ CoinWarmStartBasis basis_;
+ /** The original iteration limit before hotstarts started. */
+ int itlimOrig_;
+
+ /*! \brief Last algorithm used
+
+ Coded as
+ - 0 invalid
+ - 1 primal
+ - 2 dual
+ - -911 disaster in the algorithm that was attempted
+ - 999 current solution no longer optimal due to change in problem or
+ basis
+ */
+ mutable int lastAlgorithm_;
+
+ /// To say if destructor should delete underlying model
+ bool notOwned_;
+
+ /// Pointer to row-wise copy of problem matrix coefficients.
+ mutable CoinPackedMatrix *matrixByRow_;
+
+ /// Pointer to row-wise copy of continuous problem matrix coefficients.
+ CoinPackedMatrix *matrixByRowAtContinuous_;
+
+ /// Pointer to integer information
+ char * integerInformation_;
+
+ /** Pointer to variables for which we want range information
+ The number is in [0]
+ memory is not owned by OsiClp
+ */
+ int * whichRange_;
+
+ //std::map<OsiIntParam, ClpIntParam> intParamMap_;
+ //std::map<OsiDblParam, ClpDblParam> dblParamMap_;
+ //std::map<OsiStrParam, ClpStrParam> strParamMap_;
+
+ /*! \brief Faking min to get proper dual solution signs in simplex API */
+ mutable bool fakeMinInSimplex_ ;
+ /*! \brief Linear objective
+
+ Normally a pointer to the linear coefficient array in the clp objective.
+ An independent copy when #fakeMinInSimplex_ is true, because we need
+ something permanent to point to when #getObjCoefficients is called.
+ */
+ mutable double *linearObjective_;
+
+ /// To save data in OsiSimplex stuff
+ mutable ClpDataSave saveData_;
+ /// Options for initialSolve
+ ClpSolve solveOptions_;
+ /** Scaling option
+ When scaling is on it is possible that the scaled problem
+ is feasible but the unscaled is not. Clp returns a secondary
+ status code to that effect. This option allows for a cleanup.
+ If you use it I would suggest 1.
+ This only affects actions when scaled optimal
+ 0 - no action
+ 1 - clean up using dual if primal infeasibility
+ 2 - clean up using dual if dual infeasibility
+ 3 - clean up using dual if primal or dual infeasibility
+ 11,12,13 - as 1,2,3 but use primal
+ */
+ int cleanupScaling_;
+ /** Special options
+ 0x80000000 off
+ 0 simple stuff for branch and bound
+ 1 try and keep work regions as much as possible
+ 2 do not use any perturbation
+ 4 allow exit before re-factorization
+ 8 try and re-use factorization if no cuts
+ 16 use standard strong branching rather than clp's
+ 32 Just go to first factorization in fast dual
+ 64 try and tighten bounds in crunch
+ 128 Model will only change in column bounds
+ 256 Clean up model before hot start
+ 512 Give user direct access to Clp regions in getBInvARow etc (i.e.,
+ do not unscale, and do not return result in getBInv parameters;
+ you have to know where to look for the answer)
+ 1024 Don't "borrow" model in initialSolve
+ 2048 Don't crunch
+ 4096 quick check for optimality
+ Bits above 8192 give where called from in Cbc
+ At present 0 is normal, 1 doing fast hotstarts, 2 is can do quick check
+ 65536 Keep simple i.e. no crunch etc
+ 131072 Try and keep scaling factors around
+ 262144 Don't try and tighten bounds (funny global cuts)
+ 524288 Fake objective and 0-1
+ 1048576 Don't recompute ray after crunch
+ 2097152
+ */
+ mutable unsigned int specialOptions_;
+ /// Copy of model when option 131072 set
+ ClpSimplex * baseModel_;
+ /// Number of rows when last "scaled"
+ int lastNumberRows_;
+ /// Continuous model
+ ClpSimplex * continuousModel_;
+ /// Possible disaster handler
+ OsiClpDisasterHandler * disasterHandler_ ;
+ /// Fake objective
+ ClpLinearObjective * fakeObjective_;
+ /// Row scale factors (has inverse at end)
+ CoinDoubleArrayWithLength rowScale_;
+ /// Column scale factors (has inverse at end)
+ CoinDoubleArrayWithLength columnScale_;
+ //@}
+};
+
+class OsiClpDisasterHandler : public ClpDisasterHandler {
+public:
+ /**@name Virtual methods that the derived classe should provide.
+ */
+ //@{
+ /// Into simplex
+ virtual void intoSimplex();
+ /// Checks if disaster
+ virtual bool check() const ;
+ /// saves information for next attempt
+ virtual void saveInfo();
+ /// Type of disaster 0 can fix, 1 abort
+ virtual int typeOfDisaster();
+ //@}
+
+
+ /**@name Constructors, destructor */
+
+ //@{
+ /** Default constructor. */
+ OsiClpDisasterHandler(OsiClpSolverInterface * model = NULL);
+ /** Destructor */
+ virtual ~OsiClpDisasterHandler();
+ // Copy
+ OsiClpDisasterHandler(const OsiClpDisasterHandler&);
+ // Assignment
+ OsiClpDisasterHandler& operator=(const OsiClpDisasterHandler&);
+ /// Clone
+ virtual ClpDisasterHandler * clone() const;
+
+ //@}
+
+ /**@name Sets/gets */
+
+ //@{
+ /** set model. */
+ void setOsiModel(OsiClpSolverInterface * model);
+ /// Get model
+ inline OsiClpSolverInterface * osiModel() const
+ { return osiModel_;}
+ /// Set where from
+ inline void setWhereFrom(int value)
+ { whereFrom_=value;}
+ /// Get where from
+ inline int whereFrom() const
+ { return whereFrom_;}
+ /// Set phase
+ inline void setPhase(int value)
+ { phase_=value;}
+ /// Get phase
+ inline int phase() const
+ { return phase_;}
+ /// are we in trouble
+ bool inTrouble() const;
+
+ //@}
+
+
+protected:
+ /**@name Data members
+ The data members are protected to allow access for derived classes. */
+ //@{
+ /// Pointer to model
+ OsiClpSolverInterface * osiModel_;
+ /** Where from
+ 0 dual (resolve)
+ 1 crunch
+ 2 primal (resolve)
+ 4 dual (initialSolve)
+ 6 primal (initialSolve)
+ */
+ int whereFrom_;
+ /** phase
+ 0 initial
+ 1 trying continuing with back in and maybe different perturb
+ 2 trying continuing with back in and different scaling
+ 3 trying dual from all slack
+ 4 trying primal from previous stored basis
+ */
+ int phase_;
+ /// Are we in trouble
+ bool inTrouble_;
+ //@}
+};
+// So unit test can find out if NDEBUG set
+bool OsiClpHasNDEBUG();
+//#############################################################################
+/** A function that tests the methods in the OsiClpSolverInterface class. */
+void OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir);
+#endif