Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

OsiSolverInterface Class Reference

#include <OsiSolverInterface.hpp>

Inheritance diagram for OsiSolverInterface:

OsiClpSolverInterface OsiCpxSolverInterface OsiOslSolverInterface OsiSpxSolverInterface OsiVolSolverInterface OsiXprSolverInterface List of all members.

Private member data

CoinMessageHandlerhandler_
 Message handler.

bool defaultHandler_
CoinMessages messages_
 Messages.

void * appData_
 Pointer to user-defined data structure.

int intParam_ [OsiLastIntParam]
 Array of integer parameters.

double dblParam_ [OsiLastDblParam]
 Array of double parameters.

std::string strParam_ [OsiLastStrParam]
 Array of string parameters.

bool hintParam_ [OsiLastHintParam]
 Array of hint parameters.

OsiHintStrength hintStrength_ [OsiLastHintParam]
 Array of hint strengths.

CoinWarmStartws_

Public Member Functions

Solve methods
virtual void initialSolve ()=0
 Solve initial LP relaxation.

virtual void resolve ()=0
 Resolve an LP relaxation after problem modification.

virtual void branchAndBound ()=0
 Invoke solver's built-in enumeration algorithm.

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 volume 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.

Note:
There is a default implementation of the set/get methods, namely to store/retrieve the given value using an array in the base class. A specific solver implementation can use this feature, for example, to store parameters that should be used later on. Implementors of a solver interface should overload these functions to provide the proper interface to and accurately reflect the capabilities of a specific solver.
The format for hints is slightly different in that the value is boolean and there is an enum to show strength of hint. There is also an optional void pointer to allow for any eventuality. Hints should be initialised when a solver is instantiated. (See OsiSolverParameters.hpp for defined hint parameters and strength.) A value of true means to work with the hint, false to work against it. For example,
  •  setHintParam(OsiDoScale,true,OsiHintTry) 
    
    is a mild suggestion to the solver to scale the constraint system.
  •  setHintParam(OsiDoScale,false,OsiForceDo) 
    
    tells the solver to disable scaling, or throw an exception if it cannot comply.
As another example, a solver interface could use the value and strength of the OsiDoReducePrint hint to adjust the amount of information printed by the interface and/or solver. The extent to which a solver obeys hints is left to the solver. The value and strength returned by getHintParam will match the most recent call to setHintParam, and will not necessarily reflect the solver's ability to comply with the hint. If the hint strength is OsiForceDo, the solver is required to throw an exception if it cannot perform the specified action.

Note:
As with the other set/get methods, there is a default implementation which maintains arrays in the base class for hint value and strength. The default implementation does not store the void pointer, and always throws an exception for strength OsiForceDo. Implementors of a solver interface should overload these functions to provide the proper interface to and accurately reflect the capabilities of a specific solver.


virtual bool setIntParam (OsiIntParam key, int value)
virtual bool setDblParam (OsiDblParam key, double value)
virtual bool setStrParam (OsiStrParam key, const std::string &value)
virtual bool setHintParam (OsiHintParam key, bool yesNo=true, OsiHintStrength strength=OsiHintTry, void *otherInformation=NULL)
virtual bool getIntParam (OsiIntParam key, int &value) const
virtual bool getDblParam (OsiDblParam key, double &value) const
virtual bool getStrParam (OsiStrParam key, std::string &value) const
virtual bool getHintParam (OsiHintParam key, bool &yesNo, OsiHintStrength &strength, void *&otherInformation) const
virtual bool getHintParam (OsiHintParam key, bool &yesNo, OsiHintStrength &strength) const
virtual bool getHintParam (OsiHintParam key, bool &yesNo) const
void copyParameters (OsiSolverInterface &rhs)
Methods returning info on how the solution process terminated
virtual bool isAbandoned () const=0
 Are there numerical difficulties?

virtual bool isProvenOptimal () const=0
 Is optimality proven?

virtual bool isProvenPrimalInfeasible () const=0
 Is primal infeasiblity proven?

virtual bool isProvenDualInfeasible () const=0
 Is dual infeasiblity proven?

virtual bool isPrimalObjectiveLimitReached () const=0
 Is the given primal objective limit reached?

virtual bool isDualObjectiveLimitReached () const=0
 Is the given dual objective limit reached?

virtual bool isIterationLimitReached () const=0
 Iteration limit reached?

Warm start methods
virtual CoinWarmStartgetEmptyWarmStart () const=0
 Get an empty warm start object.

virtual CoinWarmStartgetWarmStart () const=0
virtual bool setWarmStart (const CoinWarmStart *warmstart)=0
Hot start methods
Primarily used in strong branching. The user can create a hot start object --- a snapshot of the optimization process --- then reoptimize over and over again, starting from the same point.

Note:
  • Between hot started optimizations only bound changes are allowed.
  • The copy constructor and assignment operator should NOT copy any hot start information.
  • The default implementation simply extracts a warm start object in markHotStart, resets to the warm start object in solveFromHotStart, and deletes the warm start object in unmarkHotStart. Actual solver implementations are encouraged to do better.


virtual void markHotStart ()
 Create a hot start snapshot of the optimization process.

virtual void solveFromHotStart ()
 Optimize starting from the hot start snapshot.

virtual void unmarkHotStart ()
 Delete the hot start snapshot.

Problem query methods
Querying a problem that has no data associated with it will 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.

virtual int getNumCols () const=0
 Get number of columns.

virtual int getNumRows () const=0
 Get number of rows.

virtual int getNumElements () const=0
 Get number of nonzero elements.

virtual const double * getColLower () const=0
 Get pointer to array[getNumCols()] of column lower bounds.

virtual const double * getColUpper () const=0
 Get pointer to array[getNumCols()] of column upper bounds.

virtual const char * getRowSense () const=0
virtual const double * getRightHandSide () const=0
virtual const double * getRowRange () const=0
virtual const double * getRowLower () const=0
 Get pointer to array[getNumRows()] of row lower bounds.

virtual const double * getRowUpper () const=0
 Get pointer to array[getNumRows()] of row upper bounds.

virtual const double * getObjCoefficients () const=0
 Get pointer to array[getNumCols()] of objective function coefficients.

virtual double getObjSense () const=0
 Get objective function sense (1 for min (default), -1 for max).

virtual bool isContinuous (int colIndex) const=0
 Return true if variable is continuous.

virtual bool isBinary (int colIndex) const
 Return true if variable is binary.

virtual bool isInteger (int colIndex) const
virtual bool isIntegerNonBinary (int colIndex) const
 Return true if variable is general integer.

virtual bool isFreeBinary (int colIndex) const
 Return true if variable is binary and not fixed at either bound.

virtual const CoinPackedMatrix * getMatrixByRow () const=0
 Get pointer to row-wise copy of matrix.

virtual const CoinPackedMatrix * getMatrixByCol () const=0
 Get pointer to column-wise copy of matrix.

virtual double getInfinity () const=0
 Get solver's value for infinity.

Solution query methods
virtual const double * getColSolution () const=0
 Get pointer to array[getNumCols()] of primal variable values.

virtual const double * getRowPrice () const=0
 Get pointer to array[getNumRows()] of dual variable values.

virtual const double * getReducedCost () const=0
 Get a pointer to array[getNumCols()] of reduced costs.

virtual const double * getRowActivity () const=0
virtual double getObjValue () const=0
 Get objective function value.

virtual int getIterationCount () const=0
virtual std::vector< double * > getDualRays (int maxNumRays) const=0
virtual std::vector< double * > getPrimalRays (int maxNumRays) const=0
virtual OsiVectorInt getFractionalIndices (const double etol=1.e-05) const
Methods to modify the objective, bounds, and solution
For functions which take a set of indices as parameters (setObjCoeffSet(), setColSetBounds(), setRowSetBounds(), setRowSetTypes()), the parameters follow the C++ STL iterator convention: indexFirst points to the first index in the set, and indexLast points to a position one past the last index in the set.

virtual void setObjCoeff (int elementIndex, double elementValue)=0
virtual void setObjCoeffSet (const int *indexFirst, const int *indexLast, const double *coeffList)
virtual void setColLower (int elementIndex, double elementValue)=0
virtual void setColUpper (int elementIndex, double elementValue)=0
virtual void setColBounds (int elementIndex, double lower, double upper)
virtual void setColSetBounds (const int *indexFirst, const int *indexLast, const double *boundList)
virtual void setRowLower (int elementIndex, double elementValue)=0
virtual void setRowUpper (int elementIndex, double elementValue)=0
virtual void setRowBounds (int elementIndex, double lower, double upper)
virtual void setRowType (int index, char sense, double rightHandSide, double range)=0
virtual void setRowSetBounds (const int *indexFirst, const int *indexLast, const double *boundList)
virtual void setRowSetTypes (const int *indexFirst, const int *indexLast, const char *senseList, const double *rhsList, const double *rangeList)
virtual void setObjSense (double s)=0
virtual void setColSolution (const double *colsol)=0
virtual void setRowPrice (const double *rowprice)=0
Methods to set variable type
virtual void setContinuous (int index)=0
virtual void setInteger (int index)=0
virtual void setContinuous (const int *indices, int len)
virtual void setInteger (const int *indices, int len)
Methods to expand a problem.
Note that new columns are added as continuous variables.

virtual void addCol (const CoinPackedVectorBase &vec, const double collb, const double colub, const double obj)=0
virtual void addCols (const int numcols, const CoinPackedVectorBase *const *cols, const double *collb, const double *colub, const double *obj)
virtual void deleteCols (const int num, const int *colIndices)=0
virtual void addRow (const CoinPackedVectorBase &vec, const double rowlb, const double rowub)=0
virtual void addRow (const CoinPackedVectorBase &vec, const char rowsen, const double rowrhs, const double rowrng)=0
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 deleteRows (const int num, const int *rowIndices)=0
virtual ApplyCutsReturnCode applyCuts (const OsiCuts &cs, double effectivenessLb=0.0)
virtual void applyRowCuts (int numberCuts, const OsiRowCut *cuts)
Methods to input a problem
virtual void loadProblem (const CoinPackedMatrix &matrix, const double *collb, const double *colub, const double *obj, const double *rowlb, const double *rowub)=0
virtual void assignProblem (CoinPackedMatrix *&matrix, double *&collb, double *&colub, double *&obj, double *&rowlb, double *&rowub)=0
virtual void loadProblem (const CoinPackedMatrix &matrix, const double *collb, const double *colub, const double *obj, const char *rowsen, const double *rowrhs, const double *rowrng)=0
virtual void assignProblem (CoinPackedMatrix *&matrix, double *&collb, double *&colub, double *&obj, char *&rowsen, double *&rowrhs, double *&rowrng)=0
virtual void loadProblem (const int numcols, const int numrows, const int *start, const int *index, const double *value, const double *collb, const double *colub, const double *obj, const double *rowlb, const double *rowub)=0
virtual void loadProblem (const int numcols, const int numrows, const int *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)=0
virtual int readMps (const char *filename, const char *extension="mps")
virtual void writeMps (const char *filename, const char *extension="mps", double objSense=0.0) const=0
int writeMpsNative (const char *filename, const char **rowNames, const char **columnNames, int formatType=0, int numberAcross=2, double objSense=0.0) const
Setting/Accessing application data
void setApplicationData (void *appData)
void * getApplicationData () const
 Get application data.

Message handling
See the COIN library documentation for additional information about COIN message facilities.

void passInMessageHandler (CoinMessageHandler *handler)
void newLanguage (CoinMessages::Language language)
 Set language.

void setLanguage (CoinMessages::Language language)
CoinMessageHandlermessageHandler () const
 Return a pointer to the current message handler.

CoinMessages messages ()
 Return the current set of messages.

CoinMessagesmessagesPointer ()
 Return a pointer to the current set of messages.

Methods related to testing generated cuts
virtual void activateRowCutDebugger (const char *modelName)
const OsiRowCutDebuggergetRowCutDebugger () const
Constructors and destructors
 OsiSolverInterface ()
 Default Constructor.

virtual OsiSolverInterfaceclone (bool copyData=true) const=0
 OsiSolverInterface (const OsiSolverInterface &)
 Copy constructor.

OsiSolverInterfaceoperator= (const OsiSolverInterface &rhs)
 Assignment operator.

virtual ~OsiSolverInterface ()
 Destructor.

virtual void reset ()

Protected Member Functions

Protected methods
virtual void applyRowCut (const OsiRowCut &rc)=0
virtual void applyColCut (const OsiColCut &cc)=0
void convertBoundToSense (const double lower, const double upper, char &sense, double &right, double &range) const
void convertSenseToBound (const char sense, const double right, const double range, double &lower, double &upper) const
template<class T> T forceIntoRange (const T value, const T lower, const T upper) const
void setInitialData ()

Protected Attributes

Protected member data
OsiRowCutDebuggerrowCutDebugger_
 Pointer to row cut debugger object.


Friends

void OsiSolverInterfaceCommonUnitTest (const OsiSolverInterface *emptySi, const std::string &mpsDir, const std::string &netlibDir)
void OsiSolverInterfaceMpsUnitTest (const std::vector< OsiSolverInterface * > &vecSiP, const std::string &mpsDir)
 Run solvers on NetLib problems.


Detailed Description

Solver Interface Abstract Base Class

Abstract Base Class for describing an interface to a solver.

Many OsiSolverInterface query methods return a const pointer to the requested read-only data. If the model data is changed or the solver is called, these pointers may no longer be valid and should be refreshed by invoking the member function to obtain an updated copy of the pointer. For example:

      OsiSolverInterface solverInterfacePtr ;
      const double * ruBnds = solverInterfacePtr->getRowUpper();
      solverInterfacePtr->applyCuts(someSetOfCuts);
      // ruBnds is no longer a valid pointer and must be refreshed
      ruBnds = solverInterfacePtr->getRowUpper();

Querying a problem that has no data associated with it will result in zeros for the number of rows and columns, and NULL pointers from the methods that return vectors.

Definition at line 47 of file OsiSolverInterface.hpp.


Member Function Documentation

virtual void OsiSolverInterface::activateRowCutDebugger const char *  modelName  )  [virtual]
 

Activate the row cut debugger.

If the model name passed is on list of known models then all cuts are checked to see that they do NOT cut off the known optimal solution.

virtual void OsiSolverInterface::addCol const CoinPackedVectorBase vec,
const double  collb,
const double  colub,
const double  obj
[pure virtual]
 

Add a column (primal variable) to the problem.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::addCols const int  numcols,
const CoinPackedVectorBase *const *  cols,
const double *  collb,
const double *  colub,
const double *  obj
[virtual]
 

Add a set of columns (primal variables) to the problem.

The default implementation simply makes repeated calls to addCol().

Reimplemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::addRow const CoinPackedVectorBase vec,
const double  rowlb,
const double  rowub
[pure virtual]
 

Add a row (constraint) to the problem.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::addRows const int  numrows,
const CoinPackedVectorBase *const *  rows,
const char *  rowsen,
const double *  rowrhs,
const double *  rowrng
[virtual]
 

Add a set of rows (constraints) to the problem.

The default implementation simply makes repeated calls to addRow().

Reimplemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::addRows const int  numrows,
const CoinPackedVectorBase *const *  rows,
const double *  rowlb,
const double *  rowub
[virtual]
 

Add a set of rows (constraints) to the problem.

The default implementation simply makes repeated calls to addRow().

Reimplemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::applyColCut const OsiColCut cc  )  [protected, pure virtual]
 

Apply a column cut (adjust the bounds of one or more variables).

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual ApplyCutsReturnCode OsiSolverInterface::applyCuts const OsiCuts cs,
double  effectivenessLb = 0.0
[virtual]
 

Apply a collection of cuts.

Only cuts which have an effectiveness >= effectivenessLb are applied.

  • ReturnCode.numberIneffective() -- number of cuts which were not applied because they had an effectiveness < effectivenessLb
  • ReturnCode.numberInconsistent() -- number of invalid cuts
  • ReturnCode.numberInconsistentWrtIntegerModel() -- number of cuts that are invalid with respect to this integer model
  • ReturnCode.numberInfeasible() -- number of cuts that would make this integer model infeasible
  • ReturnCode.numberApplied() -- number of integer cuts which were applied to the integer model
  • cs.size() == numberIneffective() + numberInconsistent() + numberInconsistentWrtIntegerModel() + numberInfeasible() + nubmerApplied()

virtual void OsiSolverInterface::applyRowCut const OsiRowCut rc  )  [protected, pure virtual]
 

Apply a row cut (append to the constraint matrix).

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::applyRowCuts int  numberCuts,
const OsiRowCut cuts
[virtual]
 

Apply a collection of row cuts which are all effective. applyCuts seems to do one at a time which seems inefficient. Would be even more efficient to pass an array of pointers.

Reimplemented in OsiClpSolverInterface.

virtual void OsiSolverInterface::assignProblem CoinPackedMatrix *&  matrix,
double *&  collb,
double *&  colub,
double *&  obj,
char *&  rowsen,
double *&  rowrhs,
double *&  rowrng
[pure virtual]
 

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.

Warning:
The arguments passed to this method will be freed using the C++ delete and delete[] functions.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::assignProblem CoinPackedMatrix *&  matrix,
double *&  collb,
double *&  colub,
double *&  obj,
double *&  rowlb,
double *&  rowub
[pure virtual]
 

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.

Warning:
The arguments passed to this method will be freed using the C++ delete and delete[] functions.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual OsiSolverInterface* OsiSolverInterface::clone bool  copyData = true  )  const [pure virtual]
 

Clone

The result of calling clone(false) is defined to be equivalent to calling the default constructor OsiSolverInterface().

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

void OsiSolverInterface::convertBoundToSense const double  lower,
const double  upper,
char &  sense,
double &  right,
double &  range
const [inline, protected]
 

A quick inlined function to convert from the lb/ub style of constraint definition to the sense/rhs/range style

Definition at line 1075 of file OsiSolverInterface.hpp.

References getInfinity().

Referenced by OsiXprSolverInterface::addRow(), OsiVolSolverInterface::addRow(), OsiCpxSolverInterface::addRow(), OsiVolSolverInterface::addRows(), OsiVolSolverInterface::applyRowCut(), OsiVolSolverInterface::convertBoundsToSenses_(), OsiOslSolverInterface::extractSenseRhsRange(), OsiClpSolverInterface::extractSenseRhsRange(), OsiSpxSolverInterface::getRightHandSide(), OsiXprSolverInterface::loadProblem(), OsiCpxSolverInterface::loadProblem(), OsiXprSolverInterface::setRowBounds(), OsiVolSolverInterface::setRowBounds(), OsiOslSolverInterface::setRowBounds(), OsiCpxSolverInterface::setRowBounds(), OsiXprSolverInterface::setRowLower(), OsiVolSolverInterface::setRowLower(), OsiOslSolverInterface::setRowLower(), OsiCpxSolverInterface::setRowLower(), OsiOslSolverInterface::setRowSetBounds(), OsiCpxSolverInterface::setRowSetBounds(), OsiClpSolverInterface::setRowSetBounds(), OsiXprSolverInterface::setRowUpper(), OsiVolSolverInterface::setRowUpper(), OsiOslSolverInterface::setRowUpper(), and OsiCpxSolverInterface::setRowUpper().

01078 {
01079   double inf = getInfinity();
01080   range = 0.0;
01081   if (lower > -inf) {
01082     if (upper < inf) {
01083       right = upper;
01084       if (upper==lower) {
01085         sense = 'E';
01086       } else {
01087         sense = 'R';
01088         range = upper - lower;
01089       }
01090     } else {
01091       sense = 'G';
01092       right = lower;
01093     }
01094   } else {
01095     if (upper < inf) {
01096       sense = 'L';
01097       right = upper;
01098     } else {
01099       sense = 'N';
01100       right = 0.0;
01101     }
01102   }
01103 }

void OsiSolverInterface::convertSenseToBound const char  sense,
const double  right,
const double  range,
double &  lower,
double &  upper
const [inline, protected]
 

A quick inlined function to convert from the sense/rhs/range style of constraint definition to the lb/ub style

Definition at line 1109 of file OsiSolverInterface.hpp.

References getInfinity().

Referenced by OsiVolSolverInterface::addRows(), OsiOslSolverInterface::addRows(), OsiClpSolverInterface::addRows(), OsiVolSolverInterface::convertSensesToBounds_(), OsiXprSolverInterface::getRowLower(), OsiCpxSolverInterface::getRowLower(), OsiXprSolverInterface::getRowUpper(), OsiCpxSolverInterface::getRowUpper(), OsiSpxSolverInterface::loadProblem(), OsiOslSolverInterface::loadProblem(), OsiClpSolverInterface::loadProblem(), OsiXprSolverInterface::setRowLower(), OsiCpxSolverInterface::setRowLower(), OsiOslSolverInterface::setRowSetTypes(), OsiClpSolverInterface::setRowSetTypes(), OsiVolSolverInterface::setRowType(), OsiSpxSolverInterface::setRowType(), OsiOslSolverInterface::setRowType(), OsiClpSolverInterface::setRowType(), OsiXprSolverInterface::setRowUpper(), and OsiCpxSolverInterface::setRowUpper().

01112 {
01113   double inf=getInfinity();
01114   switch (sense) {
01115   case 'E':
01116     lower = upper = right;
01117     break;
01118   case 'L':
01119     lower = -inf;
01120     upper = right;
01121     break;
01122   case 'G':
01123     lower = right;
01124     upper = inf;
01125     break;
01126   case 'R':
01127     lower = right - range;
01128     upper = right;
01129     break;
01130   case 'N':
01131     lower = -inf;
01132     upper = inf;
01133     break;
01134   }
01135 }

virtual void OsiSolverInterface::deleteCols const int  num,
const int *  colIndices
[pure virtual]
 

Remove a set of columns (primal variables) from the problem.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::deleteRows const int  num,
const int *  rowIndices
[pure virtual]
 

Delete a set of rows (constraints) from the problem.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

template<class T>
T OsiSolverInterface::forceIntoRange const T  value,
const T  lower,
const T  upper
const [inline, protected]
 

A quick inlined function to force a value to be between a minimum and a maximum value

Definition at line 996 of file OsiSolverInterface.hpp.

Referenced by OsiClpSolverInterface::addCols(), OsiClpSolverInterface::addRows(), OsiOslSolverInterface::setColLower(), OsiOslSolverInterface::setColSetBounds(), OsiClpSolverInterface::setColSetBounds(), OsiOslSolverInterface::setColUpper(), OsiOslSolverInterface::setRowBounds(), OsiOslSolverInterface::setRowLower(), OsiOslSolverInterface::setRowSetBounds(), OsiClpSolverInterface::setRowSetBounds(), and OsiOslSolverInterface::setRowUpper().

00996                                                                       {
00997       return value < lower ? lower : (value > upper ? upper : value);
00998     }

virtual std::vector<double*> OsiSolverInterface::getDualRays int  maxNumRays  )  const [pure virtual]
 

Get as many dual rays as the solver can provide. In case of proven primal infeasibility there should be at least one.

Note:
Implementors of solver interfaces note that the double pointers in the vector should point to arrays of length getNumRows() and they should be allocated via new[].

Clients of solver interfaces note that it is the client's responsibility to free the double pointers in the vector using delete[].

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual CoinWarmStart* OsiSolverInterface::getEmptyWarmStart  )  const [pure virtual]
 

Get an empty warm start object.

This routine returns an empty warm start object. Its purpose is to provide a way to give a client a warm start object of the appropriate type, which can resized and modified as desired.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual OsiVectorInt OsiSolverInterface::getFractionalIndices const double  etol = 1.e-05  )  const [virtual]
 

Get vector of indices of primal variables which are integer variables but have fractional values in the current solution.

virtual int OsiSolverInterface::getIterationCount  )  const [pure virtual]
 

Get the number of iterations it took to solve the problem (whatever ``iteration'' means to the solver).

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual std::vector<double*> OsiSolverInterface::getPrimalRays int  maxNumRays  )  const [pure virtual]
 

Get as many primal rays as the solver can provide. (In case of proven dual infeasibility there should be at least one.)

NOTE for implementers of solver interfaces:
The double pointers in the vector should point to arrays of length getNumCols() and they should be allocated via new[].

NOTE for users of solver interfaces:
It is the user's responsibility to free the double pointers in the vector using delete[].

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual const double* OsiSolverInterface::getRightHandSide  )  const [pure virtual]
 

Get pointer to array[getNumRows()] of row right-hand sides

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual const double* OsiSolverInterface::getRowActivity  )  const [pure virtual]
 

Get pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vector).

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

const OsiRowCutDebugger* OsiSolverInterface::getRowCutDebugger  )  const
 

Get the row cut debugger.

If there is a row cut debugger object associated with model AND if the known optimal solution is within the current feasible region then a pointer to the object is returned which may be used to test validity of cuts.

Otherwise NULL is returned

virtual const double* OsiSolverInterface::getRowRange  )  const [pure virtual]
 

Get pointer to array[getNumRows()] of row ranges.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual const char* OsiSolverInterface::getRowSense  )  const [pure virtual]
 

Get pointer to array[getNumRows()] of row constraint senses.

  • 'L': <= constraint
  • 'E': = constraint
  • 'G': >= constraint
  • 'R': ranged constraint
  • 'N': free constraint

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual CoinWarmStart* OsiSolverInterface::getWarmStart  )  const [pure virtual]
 

Get warm start information.

If there is no valid solution, an empty warm start object (0 rows, 0 columns) wil be returned.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual bool OsiSolverInterface::isInteger int  colIndex  )  const [virtual]
 

Return true if column is integer. Note: This function returns true if the the column is binary or a general integer.

Referenced by OsiClpSolverInterface::readMps().

virtual void OsiSolverInterface::loadProblem const int  numcols,
const int  numrows,
const int *  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
[pure virtual]
 

Just like the other loadProblem() methods except that the matrix is given in a standard column major ordered format (without gaps).

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::loadProblem const int  numcols,
const int  numrows,
const int *  start,
const int *  index,
const double *  value,
const double *  collb,
const double *  colub,
const double *  obj,
const double *  rowlb,
const double *  rowub
[pure virtual]
 

Just like the other loadProblem() methods except that the matrix is given in a standard column major ordered format (without gaps).

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::loadProblem const CoinPackedMatrix &  matrix,
const double *  collb,
const double *  colub,
const double *  obj,
const char *  rowsen,
const double *  rowrhs,
const double *  rowrng
[pure virtual]
 

Load in an problem by copying the arguments (the constraints on the rows are given by sense/rhs/range triplets). If a pointer is 0 then the following values are the default:

  • colub: all columns have upper bound infinity
  • collb: all columns have lower bound 0
  • obj: all variables have 0 objective coefficient
  • rowsen: all rows are >=
  • rowrhs: all right hand sides are 0
  • rowrng: 0 for the ranged rows

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::loadProblem const CoinPackedMatrix &  matrix,
const double *  collb,
const double *  colub,
const double *  obj,
const double *  rowlb,
const double *  rowub
[pure virtual]
 

Load in an problem by copying the arguments (the constraints on the rows are given by lower and upper bounds). If a pointer is 0 then the following values are the default:

  • colub: all columns have upper bound infinity
  • collb: all columns have lower bound 0
  • rowub: all rows have upper bound infinity
  • rowlb: all rows have lower bound -infinity
  • obj: all variables have 0 objective coefficient

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

void OsiSolverInterface::passInMessageHandler CoinMessageHandler handler  ) 
 

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 int OsiSolverInterface::readMps const char *  filename,
const char *  extension = "mps"
[virtual]
 

Read a problem in MPS format from the given filename.

The default implementation uses CoinMpsIO::readMps() to read the MPS file and returns the number of errors encountered.

Reimplemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

Referenced by OsiXprSolverInterface::readMps(), OsiSpxSolverInterface::readMps(), OsiOslSolverInterface::readMps(), OsiCpxSolverInterface::readMps(), and OsiClpSolverInterface::readMps().

virtual void OsiSolverInterface::reset  )  [virtual]
 

Reset the solver interface.

A call to reset() returns the solver interface to the same state as it would have if it had just been constructed by calling the default constructor OsiSolverInterface().

Reimplemented in OsiClpSolverInterface, OsiCpxSolverInterface, and OsiOslSolverInterface.

void OsiSolverInterface::setApplicationData void *  appData  ) 
 

Set application data.

This is a pointer that the application can store into and retrieve from the solver interface. This field is available for the application to optionally define and use.

virtual void OsiSolverInterface::setColBounds int  elementIndex,
double  lower,
double  upper
[inline, virtual]
 

Set a single column lower and upper bound. The default implementation just invokes setColLower() and setColUpper()

Reimplemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

Definition at line 552 of file OsiSolverInterface.hpp.

References setColLower(), and setColUpper().

Referenced by OsiOslSolverInterface::setColSetBounds().

00553                                                               {
00554          setColLower(elementIndex, lower);
00555          setColUpper(elementIndex, upper);
00556       }

virtual void OsiSolverInterface::setColLower int  elementIndex,
double  elementValue
[pure virtual]
 

Set a single column lower bound. Use -getInfinity() for -infinity.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

Referenced by setColBounds().

virtual void OsiSolverInterface::setColSetBounds const int *  indexFirst,
const int *  indexLast,
const double *  boundList
[virtual]
 

Set the upper and lower bounds of a set of columns. The default implementation just invokes setColBounds() over and over again. For each column, boundList must contain both a lower and upper bound, in that order.

Reimplemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

Referenced by OsiXprSolverInterface::setColSetBounds().

virtual void OsiSolverInterface::setColSolution const double *  colsol  )  [pure virtual]
 

Set the primal solution variable values

colsol[getNumCols()] is an array of values for the primal variables. These values are copied to memory owned by the solver interface object or the solver. They will be returned as the result of getColSolution() until changed by another call to setColSolution() or by a call to any solver routine. Whether the solver makes use of the solution in any way is solver-dependent.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::setColUpper int  elementIndex,
double  elementValue
[pure virtual]
 

Set a single column upper bound. Use getInfinity() for infinity.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

Referenced by setColBounds().

virtual void OsiSolverInterface::setContinuous const int *  indices,
int  len
[virtual]
 

Set the variables listed in indices (which is of length len) to be continuous variables

Reimplemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::setContinuous int  index  )  [pure virtual]
 

Set the index-th variable to be a continuous variable

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

void OsiSolverInterface::setInitialData  )  [protected]
 

Set OsiSolverInterface object state for default constructor

This routine establishes the initial values of data fields in the OsiSolverInterface object when the object is created using the default constructor.

Referenced by OsiOslSolverInterface::reset(), OsiCpxSolverInterface::reset(), and OsiClpSolverInterface::reset().

virtual void OsiSolverInterface::setInteger const int *  indices,
int  len
[virtual]
 

Set the variables listed in indices (which is of length len) to be integer variables

Reimplemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::setInteger int  index  )  [pure virtual]
 

Set the index-th variable to be an integer variable

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::setObjCoeff int  elementIndex,
double  elementValue
[pure virtual]
 

Set an objective function coefficient

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::setObjCoeffSet const int *  indexFirst,
const int *  indexLast,
const double *  coeffList
[virtual]
 

Set a set of objective function coefficients

Reimplemented in OsiCpxSolverInterface.

virtual void OsiSolverInterface::setObjSense double  s  )  [pure virtual]
 

Set the objective function sense. (1 for min (default), -1 for max)

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::setRowBounds int  elementIndex,
double  lower,
double  upper
[inline, virtual]
 

Set a single row lower and upper bound. The default implementation just invokes setRowLower() and setRowUpper()

Reimplemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

Definition at line 579 of file OsiSolverInterface.hpp.

References setRowLower(), and setRowUpper().

00580                                                               {
00581          setRowLower(elementIndex, lower);
00582          setRowUpper(elementIndex, upper);
00583       }

virtual void OsiSolverInterface::setRowLower int  elementIndex,
double  elementValue
[pure virtual]
 

Set a single row lower bound. Use -getInfinity() for -infinity.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

Referenced by setRowBounds().

virtual void OsiSolverInterface::setRowPrice const double *  rowprice  )  [pure virtual]
 

Set dual solution variable values

rowprice[getNumRows()] is an array of values for the dual variables. These values are copied to memory owned by the solver interface object or the solver. They will be returned as the result of getRowPrice() 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.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::setRowSetBounds const int *  indexFirst,
const int *  indexLast,
const double *  boundList
[virtual]
 

Set the bounds on a set of rows. The default implementation just invokes setRowBounds() over and over again.

Reimplemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

Referenced by OsiXprSolverInterface::setRowSetBounds().

virtual void OsiSolverInterface::setRowSetTypes const int *  indexFirst,
const int *  indexLast,
const char *  senseList,
const double *  rhsList,
const double *  rangeList
[virtual]
 

Set the type of a set of rows. The default implementation just invokes setRowType() over and over again.

Reimplemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

Referenced by OsiXprSolverInterface::setRowSetTypes().

virtual void OsiSolverInterface::setRowType int  index,
char  sense,
double  rightHandSide,
double  range
[pure virtual]
 

Set the type of a single row

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::setRowUpper int  elementIndex,
double  elementValue
[pure virtual]
 

Set a single row upper bound. Use getInfinity() for infinity.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

Referenced by setRowBounds().

virtual bool OsiSolverInterface::setWarmStart const CoinWarmStart warmstart  )  [pure virtual]
 

Set warm start information.

Return true/false depending on whether the warm start information was accepted or not.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

virtual void OsiSolverInterface::writeMps const char *  filename,
const char *  extension = "mps",
double  objSense = 0.0
const [pure virtual]
 

Write the problem in MPS format to the specified file.

If objSense is non-zero, a value of -1.0 causes the problem to be written with a maximization objective; +1.0 forces a minimization objective. If objSense is zero, the choice is left to implementation.

Implemented in OsiClpSolverInterface, OsiCpxSolverInterface, OsiOslSolverInterface, OsiSpxSolverInterface, OsiVolSolverInterface, and OsiXprSolverInterface.

int OsiSolverInterface::writeMpsNative const char *  filename,
const char **  rowNames,
const char **  columnNames,
int  formatType = 0,
int  numberAcross = 2,
double  objSense = 0.0
const
 

Write the problem in MPS format to the specified file.

Row and column names may be null. formatType is

  • 0 - normal
  • 1 - extra accuracy
  • 2 - IEEE hex (later)

Returns non-zero on I/O error

Reimplemented in OsiClpSolverInterface.

Referenced by OsiClpSolverInterface::writeMps(), and OsiClpSolverInterface::writeMpsNative().


Friends And Related Function Documentation

void OsiSolverInterfaceCommonUnitTest const OsiSolverInterface emptySi,
const std::string &  mpsDir,
const std::string &  netlibDir
[friend]
 

A function that tests the methods in the OsiSolverInterface class. The only reason for it not to be a member method is that this way it doesn't have to be compiled into the library. And that's a gain, because the library should be compiled with optimization on, but this method should be compiled with debugging. Also, if this method is compiled with optimization, the compilation takes 10-15 minutes and the machine pages (has 256M core memory!)...

Definition at line 1683 of file OsiSolverInterfaceTest.cpp.

01686 {
01687   
01688   int i;
01689   CoinRelFltEq eq;
01690 
01691   std::string fn = mpsDir+"exmip1";
01692   OsiSolverInterface * exmip1Si = emptySi->clone(); 
01693   exmip1Si->readMps(fn.c_str(),"mps");
01694 
01695   // Test that solverInterface knows its name.
01696   // The name is used for displaying messages when testing
01697   std::string solverName;
01698   {
01699     OsiSolverInterface * si = emptySi->clone();
01700     bool supportsSolverName = si->getStrParam(OsiSolverName,solverName);
01701     assert( supportsSolverName );
01702     assert( solverName != "Unknown Solver" );
01703     delete si;
01704   }
01705 
01706   // Determine if this is the emptySi is an OsiVolSolverInterface
01707   bool volSolverInterface = false;
01708   {
01709 #ifdef COIN_USE_VOL
01710     const OsiVolSolverInterface * si =
01711       dynamic_cast<const OsiVolSolverInterface *>(emptySi);
01712     if ( si != NULL ) volSolverInterface = true;
01713 #endif
01714   }
01715 
01716   // Determine if this is the emptySi is an OsiOslSolverInterface
01717 #ifdef COIN_USE_OSL
01718   bool oslSolverInterface = false;
01719 #endif
01720   {
01721 #ifdef COIN_USE_OSL
01722     const OsiOslSolverInterface * si =
01723       dynamic_cast<const OsiOslSolverInterface *>(emptySi);
01724     if ( si != NULL ) oslSolverInterface = true;
01725 #endif
01726   }
01727 
01728   // Determine if this is the emptySi is an OsiDylpSolverInterface
01729 #ifdef COIN_USE_DYLP
01730   bool dylpSolverInterface = false;
01731   {
01732     const OsiDylpSolverInterface * si =
01733       dynamic_cast<const OsiDylpSolverInterface *>(emptySi);
01734     if ( si != NULL ) dylpSolverInterface = true;
01735   }
01736 #endif
01737 
01738   // Determine if this is the emptySi is an OsiGlpkSolverInterface
01739   bool glpkSolverInterface = false;
01740   {
01741 #ifdef COIN_USE_GLPK
01742     const OsiGlpkSolverInterface * si =
01743       dynamic_cast<const OsiGlpkSolverInterface *>(emptySi);
01744     if ( si != NULL ) glpkSolverInterface = true;
01745 #endif
01746   }
01747 
01748   // Test that solverInterface knows about constants
01749   // in objective function.
01750   // Do not perform test if Vol solver, because it
01751   // requires problems of a special form and can not
01752   // solve netlib e226.
01753   if ( !volSolverInterface ) {
01754     OsiSolverInterface * si = emptySi->clone();
01755     std::string fn = netlibDir+"e226";
01756     si->readMps(fn.c_str(),"mps");
01757     si->initialSolve();
01758     double objValue = si->getObjValue(); 
01759     if( !eq(objValue,-18.751929066+7.113) )
01760       failureMessage(solverName,"getObjValue with constant in objective function");
01761     delete si;
01762   }
01763 
01764   // Test that values returned from an empty solverInterface
01765   {
01766     OsiSolverInterface * si = emptySi->clone();
01767     if( si->getNumRows()!=0 )
01768       failureMessage(solverName,"getNumRows with empty solverInterface");
01769     if( si->getNumCols()!=0 )
01770       failureMessage(solverName,"getNumCols with empty solverInterface");
01771     if( si->getNumElements()!=0 )
01772       failureMessage(solverName,"getNumElements with empty solverInterface");
01773     if( si->getColLower()!=NULL )
01774       failureMessage(solverName,"getColLower with empty solverInterface");
01775     if( si->getColUpper()!=NULL )
01776       failureMessage(solverName,"getColUpper with empty solverInterface");
01777     if( si->getColSolution()!=NULL )
01778       failureMessage(solverName,"getColSolution with empty solverInterface");
01779     if( si->getObjCoefficients()!=NULL )
01780       failureMessage(solverName,"getObjCoefficients with empty solverInterface");
01781     if( si->getRowRange()!=NULL )
01782       failureMessage(solverName,"getRowRange with empty solverInterface");
01783     if( si->getRightHandSide()!=NULL )
01784       failureMessage(solverName,"getRightHandSide with empty solverInterface");
01785     if( si->getRowSense()!=NULL )
01786       failureMessage(solverName,"getRowSense with empty solverInterface");
01787     if( si->getRowLower()!=NULL )
01788       failureMessage(solverName,"getRowLower with empty solverInterface");
01789     if( si->getRowUpper()!=NULL )
01790       failureMessage(solverName,"getRowUpper with empty solverInterface");
01791     delete si;
01792   }
01793   
01794   
01795   // Test that problem was loaded correctly
01796 
01797   { const char   * exmip1Sirs  = exmip1Si->getRowSense();
01798 
01799     assert( exmip1Sirs[0]=='G' );
01800     assert( exmip1Sirs[1]=='L' );
01801     assert( exmip1Sirs[2]=='E' );
01802     assert( exmip1Sirs[3]=='R' );
01803     assert( exmip1Sirs[4]=='R' );
01804     
01805     const double * exmip1Sirhs = exmip1Si->getRightHandSide();
01806     assert( eq(exmip1Sirhs[0],2.5) );
01807     assert( eq(exmip1Sirhs[1],2.1) );
01808     assert( eq(exmip1Sirhs[2],4.0) );
01809     assert( eq(exmip1Sirhs[3],5.0) );
01810     assert( eq(exmip1Sirhs[4],15.) ); 
01811     
01812     const double * exmip1Sirr  = exmip1Si->getRowRange();
01813     assert( eq(exmip1Sirr[0],0.0) );
01814     assert( eq(exmip1Sirr[1],0.0) );
01815     assert( eq(exmip1Sirr[2],0.0) );
01816     assert( eq(exmip1Sirr[3],5.0-1.8) );
01817     assert( eq(exmip1Sirr[4],15.0-3.0) );
01818 
01819     CoinPackedMatrix goldmtx ;
01820     goldmtx.reverseOrderedCopyOf(BuildExmip1Mtx()) ;
01821     CoinPackedMatrix pm;
01822     pm.setExtraGap(0.0);
01823     pm.setExtraMajor(0.0);
01824     pm = *exmip1Si->getMatrixByRow();
01825     pm.removeGaps();
01826     assert(goldmtx.isEquivalent(pm)) ;
01827     
01828     int nc = exmip1Si->getNumCols();
01829     int nr = exmip1Si->getNumRows();
01830     const double * cl = exmip1Si->getColLower();
01831     const double * cu = exmip1Si->getColUpper();
01832     const double * rl = exmip1Si->getRowLower();
01833     const double * ru = exmip1Si->getRowUpper();
01834     assert( nc == 8 );
01835     assert( nr == 5 );
01836     assert( eq(cl[0],2.5) );
01837     assert( eq(cl[1],0.0) );
01838     assert( eq(cl[2],0.0) );
01839     assert( eq(cl[3],0.0) );
01840     assert( eq(cl[4],0.5) );
01841     assert( eq(cl[5],0.0) );
01842     assert( eq(cl[6],0.0) );
01843     assert( eq(cl[7],0.0) );
01844     assert( eq(cu[0],exmip1Si->getInfinity()) );
01845     assert( eq(cu[1],4.1) );
01846     assert( eq(cu[2],1.0) );
01847     assert( eq(cu[3],1.0) );
01848     assert( eq(cu[4],4.0) );
01849     assert( eq(cu[5],exmip1Si->getInfinity()) );
01850     assert( eq(cu[6],exmip1Si->getInfinity()) );
01851     assert( eq(cu[7],4.3) );
01852 
01853     assert( eq(rl[0],2.5) );
01854     assert( eq(rl[1],-exmip1Si->getInfinity()) );
01855     assert( eq(rl[2],4.0) );
01856     assert( eq(rl[3],1.8) );
01857     assert( eq(rl[4],3.0) );
01858     assert( eq(ru[0],exmip1Si->getInfinity()) );
01859     assert( eq(ru[1],2.1) );
01860     assert( eq(ru[2],4.0) );
01861     assert( eq(ru[3],5.0) );
01862     assert( eq(ru[4],15.0) );
01863     
01864     // make sure col solution is something reasonable,
01865     // that is between upper and lower bounds
01866     const double * cs = exmip1Si->getColSolution();
01867     int c;
01868     bool okColSol=true;
01869     //double inf = exmip1Si->getInfinity();
01870     for ( c=0; c<nc; c++ ) {
01871       // if colSol is not between column bounds then 
01872       // colSol is unreasonable.
01873       if( !(cl[c]<=cs[c] && cs[c]<=cu[c]) ) okColSol=false;
01874       // if at least one column bound is not infinite,
01875       // then it is unreasonable to have colSol as infinite
01876       // FIXME: temporarily commented out pending some group thought on the
01877       //        semantics of this test. -- lh, 03.04.29 --
01878       // if ( (cl[c]<inf || cu[c]<inf) && cs[c]>=inf ) okColSol=false;
01879     }
01880     if( !okColSol )
01881       failureMessage(solverName,"getColSolution before solve");
01882     
01883     // Test value of objective function coefficients
01884     const double * objCoef = exmip1Si->getObjCoefficients();
01885     assert( eq( objCoef[0],  1.0) );
01886     assert( eq( objCoef[1],  0.0) );
01887     assert( eq( objCoef[2],  0.0) );
01888     assert( eq( objCoef[3],  0.0) );
01889     assert( eq( objCoef[4],  2.0) );
01890     assert( eq( objCoef[5],  0.0) );
01891     assert( eq( objCoef[6],  0.0) );
01892     assert( eq( objCoef[7], -1.0) );
01893 
01894     // Test that objective value is correct
01895     double correctObjValue = CoinPackedVector(nc,objCoef).dotProduct(cs);
01896     double siObjValue = exmip1Si->getObjValue();
01897     if( !eq(correctObjValue,siObjValue) ) {
01898        // FIXME: the test checks the primal value. vol fails this, because vol
01899        // considers the dual value to be the objective value
01900        failureMessage(solverName,"getObjValue before solve (OK for vol)");
01901     }
01902 
01903 
01904   }
01905   
01906   
01907   // Test matrixByCol method
01908   {
01909     CoinPackedMatrix &goldmtx = BuildExmip1Mtx() ;
01910     OsiSolverInterface & si = *exmip1Si->clone();
01911     CoinPackedMatrix sm = *si.getMatrixByCol();
01912     sm.removeGaps();
01913     bool getByColOK = goldmtx.isEquivalent(sm) ;
01914 
01915     if (!getByColOK)
01916       failureMessage(solverName,"getMatrixByCol()") ;
01917     
01918     // Test getting and setting of objective offset
01919     double objOffset;
01920     bool supportOsiObjOffset = si.getDblParam(OsiObjOffset,objOffset);
01921     assert( supportOsiObjOffset );
01922     assert( eq( objOffset, 0.0 ) );
01923     supportOsiObjOffset = si.setDblParam(OsiObjOffset, 3.21);
01924     assert( supportOsiObjOffset );
01925     si.getDblParam(OsiObjOffset,objOffset);
01926     assert( eq( objOffset, 3.21 ) );
01927     
01928     delete &si;
01929   }
01930    
01931   // Test clone
01932   {
01933     OsiSolverInterface * si2;  
01934     int ad = 13579;
01935     {
01936       OsiSolverInterface * si1 = exmip1Si->clone(); 
01937       int ad = 13579;
01938       si1->setApplicationData(&ad);
01939       assert( *((int *)(si1->getApplicationData())) == ad );
01940       si2 = si1->clone();
01941       delete si1;
01942     }
01943     
01944     if( *((int *)(si2->getApplicationData())) != ad )
01945       failureMessage(solverName,"getApplicationData on cloned solverInterface");
01946 
01947     const char   * exmip1Sirs  = si2->getRowSense();
01948     assert( exmip1Sirs[0]=='G' );
01949     assert( exmip1Sirs[1]=='L' );
01950     assert( exmip1Sirs[2]=='E' );
01951     assert( exmip1Sirs[3]=='R' );
01952     assert( exmip1Sirs[4]=='R' );
01953     
01954     const double * exmip1Sirhs = si2->getRightHandSide();
01955     assert( eq(exmip1Sirhs[0],2.5) );
01956     assert( eq(exmip1Sirhs[1],2.1) );
01957     assert( eq(exmip1Sirhs[2],4.0) );
01958     assert( eq(exmip1Sirhs[3],5.0) );
01959     assert( eq(exmip1Sirhs[4],15.) ); 
01960     
01961     const double * exmip1Sirr  = si2->getRowRange();
01962     assert( eq(exmip1Sirr[0],0.0) );
01963     assert( eq(exmip1Sirr[1],0.0) );
01964     assert( eq(exmip1Sirr[2],0.0) );
01965     assert( eq(exmip1Sirr[3],5.0-1.8) );
01966     assert( eq(exmip1Sirr[4],15.0-3.0) );
01967     
01968     CoinPackedMatrix goldmtx ;
01969     goldmtx.reverseOrderedCopyOf(BuildExmip1Mtx()) ;
01970     CoinPackedMatrix pm;
01971     pm.setExtraGap(0.0);
01972     pm.setExtraMajor(0.0);
01973     pm = *si2->getMatrixByRow();
01974     assert(goldmtx.isEquivalent(pm)) ;
01975     
01976     int nc = si2->getNumCols();
01977     int nr = si2->getNumRows();
01978     const double * cl = si2->getColLower();
01979     const double * cu = si2->getColUpper();
01980     const double * rl = si2->getRowLower();
01981     const double * ru = si2->getRowUpper();
01982     assert( nc == 8 );
01983     assert( nr == 5 );
01984     assert( eq(cl[0],2.5) );
01985     assert( eq(cl[1],0.0) );
01986     assert( eq(cl[2],0.0) );
01987     assert( eq(cl[3],0.0) );
01988     assert( eq(cl[4],0.5) );
01989     assert( eq(cl[5],0.0) );
01990     assert( eq(cl[6],0.0) );
01991     assert( eq(cl[7],0.0) );
01992     assert( eq(cu[0],si2->getInfinity()) );
01993     assert( eq(cu[1],4.1) );
01994     assert( eq(cu[2],1.0) );
01995     assert( eq(cu[3],1.0) );
01996     assert( eq(cu[4],4.0) );
01997     assert( eq(cu[5],si2->getInfinity()) );
01998     assert( eq(cu[6],si2->getInfinity()) );
01999     assert( eq(cu[7],4.3) );
02000 
02001     assert( eq(rl[0],2.5) );
02002     assert( eq(rl[1],-si2->getInfinity()) );
02003     assert( eq(rl[2],4.0) );
02004     assert( eq(rl[3],1.8) );
02005     assert( eq(rl[4],3.0) );
02006     assert( eq(ru[0],si2->getInfinity()) );
02007     assert( eq(ru[1],2.1) );
02008     assert( eq(ru[2],4.0) );
02009     assert( eq(ru[3],5.0) );
02010     assert( eq(ru[4],15.0) );
02011         
02012     // make sure col solution is something reasonable,
02013     // that is between upper and lower bounds
02014     const double * cs = exmip1Si->getColSolution();
02015     int c;
02016     bool okColSol=true;
02017     //double inf = exmip1Si->getInfinity();
02018     for ( c=0; c<nc; c++ ) {
02019       // if colSol is not between column bounds then 
02020       // colSol is unreasonable.
02021       if( !(cl[c]<=cs[c] && cs[c]<=cu[c]) ) okColSol=false;
02022       // if at least one column bound is not infinite,
02023       // then it is unreasonable to have colSol as infinite
02024       // FIXME: temporarily commented out pending some group thought on the
02025       //        semantics of this test. -- lh, 03.04.29 --
02026       // if ( (cl[c]<inf || cu[c]<inf) && cs[c]>=inf ) okColSol=false;
02027     }
02028     if( !okColSol )
02029       failureMessage(solverName,"getColSolution before solve on cloned solverInterface");
02030     
02031     assert( eq( si2->getObjCoefficients()[0],  1.0) );
02032     assert( eq( si2->getObjCoefficients()[1],  0.0) );
02033     assert( eq( si2->getObjCoefficients()[2],  0.0) );
02034     assert( eq( si2->getObjCoefficients()[3],  0.0) );
02035     assert( eq( si2->getObjCoefficients()[4],  2.0) );
02036     assert( eq( si2->getObjCoefficients()[5],  0.0) );
02037     assert( eq( si2->getObjCoefficients()[6],  0.0) );
02038     assert( eq( si2->getObjCoefficients()[7], -1.0) );
02039     
02040     // Test getting and setting of objective offset
02041     double objOffset;
02042     bool supported = si2->getDblParam(OsiObjOffset,objOffset);
02043     assert( supported );
02044     if( !eq( objOffset, 0.0 ) )
02045       failureMessage(solverName,"getDblParam OsiObjOffset on cloned solverInterface");
02046     delete si2;
02047   }
02048   // end of clone testing
02049   
02050   // Test apply cuts method
02051   {      
02052     OsiSolverInterface & im = *(exmip1Si->clone()); 
02053     OsiCuts cuts;
02054     
02055     // Generate some cuts 
02056     {
02057       // Get number of rows and columns in model
02058       int nr=im.getNumRows();
02059       int nc=im.getNumCols();
02060       assert( nr == 5 );
02061       assert( nc == 8 );
02062       
02063       // Generate a valid row cut from thin air
02064       int c;
02065       {
02066         int *inx = new int[nc];
02067         for (c=0;c<nc;c++) inx[c]=c;
02068         double *el = new double[nc];
02069         for (c=0;c<nc;c++) el[c]=((double)c)*((double)c);
02070         
02071         OsiRowCut rc;
02072         rc.setRow(nc,inx,el);
02073         rc.setLb(-100.);
02074         rc.setUb(100.);
02075         rc.setEffectiveness(22);
02076         
02077         cuts.insert(rc);
02078         delete[]el;
02079         delete[]inx;
02080       }
02081       
02082       // Generate valid col cut from thin air
02083       {
02084         const double * oslColLB = im.getColLower();
02085         const double * oslColUB = im.getColUpper();
02086         int *inx = new int[nc];
02087         for (c=0;c<nc;c++) inx[c]=c;
02088         double *lb = new double[nc];
02089         double *ub = new double[nc];
02090         for (c=0;c<nc;c++) lb[c]=oslColLB[c]+0.001;
02091         for (c=0;c<nc;c++) ub[c]=oslColUB[c]-0.001;
02092         
02093         OsiColCut cc;
02094         cc.setLbs(nc,inx,lb);
02095         cc.setUbs(nc,inx,ub);
02096         
02097         cuts.insert(cc);
02098         delete [] ub;
02099         delete [] lb;
02100         delete [] inx;
02101       }
02102       
02103       {
02104         // Generate a row and column cut which are ineffective
02105         OsiRowCut * rcP= new OsiRowCut;
02106         rcP->setEffectiveness(-1.);
02107         cuts.insert(rcP);
02108         assert(rcP==NULL);
02109         
02110         OsiColCut * ccP= new OsiColCut;
02111         ccP->setEffectiveness(-12.);
02112         cuts.insert(ccP);
02113         assert(ccP==NULL);
02114       }
02115       {
02116         //Generate inconsistent Row cut
02117         OsiRowCut rc;
02118         const int ne=1;
02119         int inx[ne]={-10};
02120         double el[ne]={2.5};
02121         rc.setRow(ne,inx,el);
02122         rc.setLb(3.);
02123         rc.setUb(4.);
02124         assert(!rc.consistent());
02125         cuts.insert(rc);
02126       }
02127       {
02128         //Generate inconsistent col cut
02129         OsiColCut cc;
02130         const int ne=1;
02131         int inx[ne]={-10};
02132         double el[ne]={2.5};
02133         cc.setUbs(ne,inx,el);
02134         assert(!cc.consistent());
02135         cuts.insert(cc);
02136       }
02137       {
02138         // Generate row cut which is inconsistent for model m
02139         OsiRowCut rc;
02140         const int ne=1;
02141         int inx[ne]={10};
02142         double el[ne]={2.5};
02143         rc.setRow(ne,inx,el);
02144         assert(rc.consistent());
02145         assert(!rc.consistent(im));
02146         cuts.insert(rc);
02147       }
02148       {
02149         // Generate col cut which is inconsistent for model m
02150         OsiColCut cc;
02151         const int ne=1;
02152         int inx[ne]={30};
02153         double el[ne]={2.0};
02154         cc.setLbs(ne,inx,el);
02155         assert(cc.consistent());
02156         assert(!cc.consistent(im));
02157         cuts.insert(cc);
02158       }
02159       {
02160         // Generate col cut which is infeasible
02161         OsiColCut cc;
02162         const int ne=1;
02163         int inx[ne]={0};
02164         double el[ne]={2.0};
02165         cc.setUbs(ne,inx,el);
02166         cc.setEffectiveness(1000.);
02167         assert(cc.consistent());
02168         assert(cc.consistent(im));
02169         assert(cc.infeasible(im));
02170         cuts.insert(cc);
02171       }
02172     }
02173     assert(cuts.sizeRowCuts()==4);
02174     assert(cuts.sizeColCuts()==5);
02175 
02176    {  
02177       OsiSolverInterface::ApplyCutsReturnCode rc = im.applyCuts(cuts);
02178       assert( rc.getNumIneffective() == 2 );
02179       assert( rc.getNumApplied() == 2 );
02180       assert( rc.getNumInfeasible() == 1 );
02181       assert( rc.getNumInconsistentWrtIntegerModel() == 2 );
02182       assert( rc.getNumInconsistent() == 2 );
02183       assert( cuts.sizeCuts() == rc.getNumIneffective() +
02184         rc.getNumApplied() +
02185         rc.getNumInfeasible() +
02186         rc.getNumInconsistentWrtIntegerModel() +
02187         rc.getNumInconsistent() );
02188     }
02189 
02190     delete &im;
02191   }
02192   // end of apply cut method testing
02193     
02194 
02195   // Test setting solution
02196 
02197   {
02198     OsiSolverInterface & m1 = *(exmip1Si->clone());
02199     int i;
02200     
02201     double * cs = new double[m1.getNumCols()];
02202     for ( i = 0;  i < m1.getNumCols();  i++ ) 
02203       cs[i] = i + .5;
02204     m1.setColSolution(cs);
02205     for ( i = 0;  i < m1.getNumCols();  i++ ) 
02206       assert(m1.getColSolution()[i] == i + .5);
02207     
02208     double * rs = new double[m1.getNumRows()];
02209     for ( i = 0;  i < m1.getNumRows();  i++ ) 
02210       rs[i] = i - .5;
02211     m1.setRowPrice(rs);
02212     for ( i = 0;  i < m1.getNumRows();  i++ ) 
02213       assert(m1.getRowPrice()[i] == i - .5);
02214     
02215     delete [] cs;
02216     delete [] rs;
02217     delete &m1;
02218   }
02219 
02220   // Test column type methods
02221 
02222   if ( volSolverInterface ) {
02223      // Test for vol since it does not support this function
02224      failureMessage(solverName,"column type methods all report continuous (OK for vol)");
02225   }
02226   else {
02227     OsiSolverInterface & fim = *(emptySi->clone());
02228     std::string fn = mpsDir+"exmip1";
02229     fim.readMps(fn.c_str(),"mps");
02230     // exmip1.mps has 2 integer variables with index 2 & 3
02231     assert(  fim.isContinuous(0) );
02232     assert(  fim.isContinuous(1) );
02233     assert( !fim.isContinuous(2) );
02234     assert( !fim.isContinuous(3) );
02235     assert(  fim.isContinuous(4) );
02236     
02237     assert( !fim.isInteger(0) );
02238     assert( !fim.isInteger(1) );
02239     assert(  fim.isInteger(2) );
02240     assert(  fim.isInteger(3) );
02241     assert( !fim.isInteger(4) );
02242     
02243     assert( !fim.isBinary(0) );
02244     assert( !fim.isBinary(1) );
02245     assert(  fim.isBinary(2) );
02246     assert(  fim.isBinary(3) );
02247     assert( !fim.isBinary(4) );
02248     
02249     assert( !fim.isIntegerNonBinary(0) );
02250     assert( !fim.isIntegerNonBinary(1) );
02251     assert( !fim.isIntegerNonBinary(2) );
02252     assert( !fim.isIntegerNonBinary(3) );
02253     assert( !fim.isIntegerNonBinary(4) );
02254     
02255     // Test fractionalIndices
02256 
02257     {
02258       double sol[]={1.0, 2.0, 2.9, 3.0, 4.0,0.0,0.0,0.0};
02259       fim.setColSolution(sol);
02260       OsiVectorInt fi = fim.getFractionalIndices(1e-5);
02261       assert( fi.size() == 1 );
02262       assert( fi[0]==2 );
02263       
02264       // Set integer variables very close to integer values
02265       sol[2]=5 + .00001/2.;
02266       sol[3]=8 - .00001/2.;
02267       fim.setColSolution(sol);
02268       fi = fim.getFractionalIndices(1e-5);
02269       assert( fi.size() == 0 );
02270       
02271       // Set integer variables close, but beyond tolerances
02272       sol[2]=5 + .00001*2.;
02273       sol[3]=8 - .00001*2.;
02274       fim.setColSolution(sol);
02275       fi = fim.getFractionalIndices(1e-5);
02276       assert( fi.size() == 2 );
02277       assert( fi[0]==2 );
02278       assert( fi[1]==3 );
02279     }
02280     
02281     // Change data so column 2 & 3 are integerNonBinary
02282     fim.setColUpper(2,5.0);
02283     assert( eq(fim.getColUpper()[2],5.0) );
02284     fim.setColUpper(3,6.0);
02285     assert( eq(fim.getColUpper()[3],6.0) );
02286     assert( !fim.isBinary(0) );
02287     assert( !fim.isBinary(1) );
02288     if( fim.isBinary(2) )
02289       failureMessage(solverName,"isBinary or setColUpper");
02290     if( fim.isBinary(3) )
02291       failureMessage(solverName,"isBinary or setColUpper");
02292     assert( !fim.isBinary(4) );
02293     
02294     assert( !fim.isIntegerNonBinary(0) );
02295     assert( !fim.isIntegerNonBinary(1) );
02296     if( !fim.isIntegerNonBinary(2) )
02297       failureMessage(solverName,"isIntegerNonBinary or setColUpper");
02298     if( !fim.isIntegerNonBinary(3) )
02299       failureMessage(solverName,"isIntegerNonBinary or setColUpper");
02300     assert( !fim.isIntegerNonBinary(4) );
02301     
02302     delete &fim;
02303   }
02304 
02305     
02306   // Test load and assign problem
02307   {
02308     {   
02309       OsiSolverInterface * base = exmip1Si->clone();
02310       OsiSolverInterface *  si1 = emptySi->clone(); 
02311       OsiSolverInterface *  si2 = emptySi->clone(); 
02312       OsiSolverInterface *  si3 = emptySi->clone(); 
02313       OsiSolverInterface *  si4 = emptySi->clone();  
02314       OsiSolverInterface *  si5 = emptySi->clone();  
02315       OsiSolverInterface *  si6 = emptySi->clone(); 
02316       OsiSolverInterface *  si7 = emptySi->clone();  
02317       OsiSolverInterface *  si8 = emptySi->clone(); 
02318         
02319       si1->loadProblem(*base->getMatrixByCol(),
02320                        base->getColLower(),base->getColUpper(),
02321                        base->getObjCoefficients(),
02322                        base->getRowSense(),base->getRightHandSide(),
02323                        base->getRowRange());
02324       si2->loadProblem(*base->getMatrixByRow(),
02325                        base->getColLower(),base->getColUpper(),
02326                        base->getObjCoefficients(),
02327                        base->getRowSense(),base->getRightHandSide(),
02328                        base->getRowRange());
02329       si3->loadProblem(*base->getMatrixByCol(),
02330                        base->getColLower(),base->getColUpper(),
02331                        base->getObjCoefficients(),
02332                        base->getRowLower(),base->getRowUpper() );
02333       si4->loadProblem(*base->getMatrixByCol(),
02334                        base->getColLower(),base->getColUpper(),
02335                        base->getObjCoefficients(),
02336                        base->getRowLower(),base->getRowUpper() );
02337       {
02338         double objOffset;
02339         base->getDblParam(OsiObjOffset,objOffset);
02340         si1->setDblParam(OsiObjOffset,objOffset);
02341         si2->setDblParam(OsiObjOffset,objOffset);
02342         si3->setDblParam(OsiObjOffset,objOffset);
02343         si4->setDblParam(OsiObjOffset,objOffset);
02344         si5->setDblParam(OsiObjOffset,objOffset);
02345         si6->setDblParam(OsiObjOffset,objOffset);
02346         si7->setDblParam(OsiObjOffset,objOffset);
02347         si8->setDblParam(OsiObjOffset,objOffset);
02348       }
02349       CoinPackedMatrix * pm = new CoinPackedMatrix(*base->getMatrixByCol());
02350       double * clb = new double[base->getNumCols()];
02351       std::copy(base->getColLower(),
02352                 base->getColLower()+base->getNumCols(),clb);
02353       double * cub = new double[base->getNumCols()];
02354       std::copy(base->getColUpper(),
02355                 base->getColUpper()+base->getNumCols(),cub);
02356       double * objc = new double[base->getNumCols()];
02357       std::copy(base->getObjCoefficients(),
02358                 base->getObjCoefficients()+base->getNumCols(),objc);
02359       double * rlb = new double[base->getNumRows()];
02360       std::copy(base->getRowLower(),
02361                 base->getRowLower()+base->getNumRows(),rlb);
02362       double * rub = new double[base->getNumRows()];
02363       std::copy(base->getRowUpper(),
02364                 base->getRowUpper()+base->getNumRows(),rub);
02365       si5->assignProblem(pm,clb,cub,objc,rlb,rub);
02366       assert(pm==NULL);
02367       assert(clb==NULL);
02368       assert(cub==NULL);
02369       assert(objc==NULL);
02370       assert(rlb==NULL);
02371       assert(rub==NULL);
02372         
02373       pm = new CoinPackedMatrix(*base->getMatrixByRow());
02374       clb = new double[base->getNumCols()];
02375       std::copy(base->getColLower(),
02376                 base->getColLower()+base->getNumCols(),clb);
02377       cub = new double[base->getNumCols()];
02378       std::copy(base->getColUpper(),
02379                 base->getColUpper()+base->getNumCols(),cub);
02380       objc = new double[base->getNumCols()];
02381       std::copy(base->getObjCoefficients(),
02382                 base->getObjCoefficients()+base->getNumCols(),objc);
02383       rlb = new double[base->getNumRows()];
02384       std::copy(base->getRowLower(),
02385                 base->getRowLower()+base->getNumRows(),rlb);
02386       rub = new double[base->getNumRows()];
02387       std::copy(base->getRowUpper(),
02388                 base->getRowUpper()+base->getNumRows(),rub);
02389       si6->assignProblem(pm,clb,cub,objc,rlb,rub);
02390       assert(pm==NULL);
02391       assert(clb==NULL);
02392       assert(cub==NULL);
02393       assert(objc==NULL);
02394       assert(rlb==NULL);
02395       assert(rub==NULL);      
02396         
02397       pm = new CoinPackedMatrix(*base->getMatrixByCol());
02398       clb = new double[base->getNumCols()];
02399       std::copy(base->getColLower(),
02400                 base->getColLower()+base->getNumCols(),clb);
02401       cub = new double[base->getNumCols()];
02402       std::copy(base->getColUpper(),
02403                 base->getColUpper()+base->getNumCols(),cub);
02404       objc = new double[base->getNumCols()];
02405       std::copy(base->getObjCoefficients(),
02406                 base->getObjCoefficients()+base->getNumCols(),objc);
02407       char * rsen = new char[base->getNumRows()];
02408       std::copy(base->getRowSense(),
02409                 base->getRowSense()+base->getNumRows(),rsen);
02410       double * rhs = new double[base->getNumRows()];
02411       std::copy(base->getRightHandSide(),
02412                 base->getRightHandSide()+base->getNumRows(),rhs);
02413       double * rng = new double[base->getNumRows()];
02414       std::copy(base->getRowRange(),
02415                 base->getRowRange()+base->getNumRows(),rng);
02416       si7->assignProblem(pm,clb,cub,objc,rsen,rhs,rng);
02417       assert(pm==NULL);
02418       assert(clb==NULL);
02419       assert(cub==NULL);
02420       assert(objc==NULL);
02421       assert(rsen==NULL);
02422       assert(rhs==NULL);
02423       assert(rng==NULL);
02424         
02425       pm = new CoinPackedMatrix(*base->getMatrixByCol());
02426       clb = new double[base->getNumCols()];
02427       std::copy(base->getColLower(),
02428                 base->getColLower()+base->getNumCols(),clb);
02429       cub = new double[base->getNumCols()];
02430       std::copy(base->getColUpper(),
02431                 base->getColUpper()+base->getNumCols(),cub);
02432       objc = new double[base->getNumCols()];
02433       std::copy(base->getObjCoefficients(),
02434                 base->getObjCoefficients()+base->getNumCols(),objc);
02435       rsen = new char[base->getNumRows()];
02436       std::copy(base->getRowSense(),
02437                 base->getRowSense()+base->getNumRows(),rsen);
02438       rhs = new double[base->getNumRows()];
02439       std::copy(base->getRightHandSide(),
02440                 base->getRightHandSide()+base->getNumRows(),rhs);
02441       rng = new double[base->getNumRows()];
02442       std::copy(base->getRowRange(),
02443                 base->getRowRange()+base->getNumRows(),rng);
02444       si8->assignProblem(pm,clb,cub,objc,rsen,rhs,rng);
02445       assert(pm==NULL);
02446       assert(clb==NULL);
02447       assert(cub==NULL);
02448       assert(objc==NULL);
02449       assert(rsen==NULL);
02450       assert(rhs==NULL);
02451       assert(rng==NULL);
02452      
02453         
02454       // Create an indices vector        
02455       CoinPackedVector basePv,pv;
02456       assert(base->getNumCols()<10);
02457       assert(base->getNumRows()<10);
02458       int indices[10];
02459       int i;
02460       for (i=0; i<10; i++) indices[i]=i;
02461         
02462       // Test solve methods.
02463       try {
02464         base->initialSolve();
02465         si1->initialSolve();
02466         si2->initialSolve();
02467         si3->initialSolve();
02468         si4->initialSolve();
02469         si5->initialSolve();
02470         si6->initialSolve();
02471         si7->initialSolve();
02472         si8->initialSolve();
02473       }        
02474       catch (CoinError e) {
02475 #ifdef COIN_USE_VOL
02476         // Vol solver interface is expected to throw
02477         // an error if the data has a ranged row.
02478           
02479         // Check that using Vol SI
02480         OsiVolSolverInterface * vsi =
02481           dynamic_cast<OsiVolSolverInterface *>(base);
02482         assert( vsi != NULL );        
02483           
02484         // Test that there is non-zero range
02485         basePv.setFull(base->getNumRows(),base->getRowRange());
02486         pv.setConstant( base->getNumRows(), indices, 0.0 );
02487         assert(!basePv.isEquivalent(pv)); 
02488 #else
02489         assert(0==1);
02490 #endif
02491       }
02492       
02493       // Test WriteMps
02494       
02495       {
02496 
02497         OsiSolverInterface *  si1 = emptySi->clone(); 
02498         OsiSolverInterface *  si2 = emptySi->clone(); 
02499         si1->readMps(fn.c_str(),"mps");
02500         si1->writeMpsNative("test.out",NULL,NULL);
02501         si1->writeMps("test2","out");
02502         si2->readMps("test.out","");
02503         bool solved = true;
02504         try {
02505            si1->initialSolve();
02506         }
02507         catch (CoinError e) {
02508            if (e.className() != "OsiVolSolverInterface") {
02509               printf("Couldn't solve initial LP in testing WriteMps\n");
02510               abort();
02511            }
02512            solved = false;
02513         }
02514         if (solved) {
02515            si2->initialSolve();
02516            double soln = si1->getObjValue();       
02517            CoinRelFltEq eq(1.0e-8) ;
02518            assert( eq(soln,si2->getObjValue()));       
02519         }
02520         delete si1;
02521         delete si2;
02522       }
02523         
02524       // Test collower
02525       basePv.setVector(base->getNumCols(),indices,base->getColLower());
02526       pv.setVector( si1->getNumCols(),indices, si1->getColLower());
02527       assert(basePv.isEquivalent(pv));
02528       pv.setVector( si2->getNumCols(),indices, si2->getColLower());
02529       assert(basePv.isEquivalent(pv));
02530       pv.setVector( si3->getNumCols(),indices, si3->getColLower());
02531       assert(basePv.isEquivalent(pv));
02532       pv.setVector( si4->getNumCols(),indices, si4->getColLower());
02533       assert(basePv.isEquivalent(pv));
02534       pv.setVector( si5->getNumCols(),indices, si5->getColLower());
02535       assert(basePv.isEquivalent(pv));
02536       pv.setVector( si6->getNumCols(),indices, si6->getColLower());
02537       assert(basePv.isEquivalent(pv));
02538       pv.setVector( si7->getNumCols(),indices, si7->getColLower());
02539       assert(basePv.isEquivalent(pv));
02540       pv.setVector( si8->getNumCols(),indices, si8->getColLower());
02541       assert(basePv.isEquivalent(pv));
02542         
02543       // Test colupper
02544       basePv.setVector(base->getNumCols(),indices,base->getColUpper());
02545       pv.setVector( si1->getNumCols(),indices, si1->getColUpper());
02546       assert(basePv.isEquivalent(pv));
02547       pv.setVector( si2->getNumCols(),indices, si2->getColUpper());
02548       assert(basePv.isEquivalent(pv));
02549       pv.setVector( si3->getNumCols(),indices, si3->getColUpper());
02550       assert(basePv.isEquivalent(pv));
02551       pv.setVector( si4->getNumCols(),indices, si4->getColUpper());
02552       assert(basePv.isEquivalent(pv));
02553       pv.setVector( si5->getNumCols(),indices, si5->getColUpper());
02554       assert(basePv.isEquivalent(pv));
02555       pv.setVector( si6->getNumCols(),indices, si6->getColUpper());
02556       assert(basePv.isEquivalent(pv));
02557       pv.setVector( si7->getNumCols(),indices, si7->getColUpper());
02558       assert(basePv.isEquivalent(pv));
02559       pv.setVector( si8->getNumCols(),indices, si8->getColUpper());
02560       assert(basePv.isEquivalent(pv));
02561         
02562       // Test getObjCoefficients
02563       basePv.setVector(base->getNumCols(),indices,base->getObjCoefficients());
02564       pv.setVector( si1->getNumCols(),indices, si1->getObjCoefficients());
02565       assert(basePv.isEquivalent(pv));
02566       pv.setVector( si2->getNumCols(),indices, si2->getObjCoefficients());
02567       assert(basePv.isEquivalent(pv));
02568       pv.setVector( si3->getNumCols(),indices, si3->getObjCoefficients());
02569       assert(basePv.isEquivalent(pv));
02570       pv.setVector( si4->getNumCols(),indices, si4->getObjCoefficients());
02571       assert(basePv.isEquivalent(pv));
02572       pv.setVector( si5->getNumCols(),indices, si5->getObjCoefficients());
02573       assert(basePv.isEquivalent(pv));
02574       pv.setVector( si6->getNumCols(),indices, si6->getObjCoefficients());
02575       assert(basePv.isEquivalent(pv));
02576       pv.setVector( si7->getNumCols(),indices, si7->getObjCoefficients());
02577       assert(basePv.isEquivalent(pv));
02578       pv.setVector( si8->getNumCols(),indices, si8->getObjCoefficients());
02579       assert(basePv.isEquivalent(pv));
02580                 
02581       // Test rowrhs
02582       basePv.setFull(base->getNumRows(),base->getRightHandSide());
02583       pv.setFull( si1->getNumRows(), si1->getRightHandSide());
02584       assert(basePv.isEquivalent(pv));
02585       pv.setFull( si2->getNumRows(), si2->getRightHandSide());
02586       assert(basePv.isEquivalent(pv));
02587       pv.setFull( si3->getNumRows(), si3->getRightHandSide());
02588       assert(basePv.isEquivalent(pv));
02589       pv.setFull( si4->getNumRows(), si4->getRightHandSide());
02590       assert(basePv.isEquivalent(pv));
02591       pv.setFull( si5->getNumRows(), si5->getRightHandSide());
02592       assert(basePv.isEquivalent(pv));
02593       pv.setFull( si6->getNumRows(), si6->getRightHandSide());
02594       assert(basePv.isEquivalent(pv));
02595       pv.setFull( si7->getNumRows(), si7->getRightHandSide());
02596       assert(basePv.isEquivalent(pv));
02597       pv.setFull( si8->getNumRows(), si8->getRightHandSide());
02598       assert(basePv.isEquivalent(pv));
02599         
02600       // Test rowrange
02601       basePv.setFull(base->getNumRows(),base->getRowRange());
02602       pv.setFull( si1->getNumRows(), si1->getRowRange());
02603       assert(basePv.isEquivalent(pv));
02604       pv.setFull( si2->getNumRows(), si2->getRowRange());
02605       assert(basePv.isEquivalent(pv));
02606       pv.setFull( si3->getNumRows(), si3->getRowRange());
02607       assert(basePv.isEquivalent(pv));
02608       pv.setFull( si4->getNumRows(), si4->getRowRange());
02609       assert(basePv.isEquivalent(pv));
02610       pv.setFull( si5->getNumRows(), si5->getRowRange());
02611       assert(basePv.isEquivalent(pv));
02612       pv.setFull( si6->getNumRows(), si6->getRowRange());
02613       assert(basePv.isEquivalent(pv));
02614       pv.setFull( si7->getNumRows(), si7->getRowRange());
02615       assert(basePv.isEquivalent(pv));
02616       pv.setFull( si8->getNumRows(), si8->getRowRange());
02617       assert(basePv.isEquivalent(pv));
02618         
02619       // Test row sense
02620       {
02621         const char * cb = base->getRowSense();
02622         const char * c1 = si1->getRowSense();
02623         const char * c2 = si2->getRowSense();
02624         const char * c3 = si3->getRowSense();
02625         const char * c4 = si4->getRowSense();
02626         const char * c5 = si5->getRowSense();
02627         const char * c6 = si6->getRowSense();
02628         const char * c7 = si7->getRowSense();
02629         const char * c8 = si8->getRowSense();
02630         int nr = base->getNumRows();
02631         for ( i=0; i<nr; i++ ) {
02632           assert( cb[i]==c1[i] );
02633           assert( cb[i]==c2[i] );
02634           assert( cb[i]==c3[i] );
02635           assert( cb[i]==c4[i] );
02636           assert( cb[i]==c5[i] );
02637           assert( cb[i]==c6[i] );
02638           assert( cb[i]==c7[i] );
02639           assert( cb[i]==c8[i] );
02640         }
02641       }
02642         
02643       // Test rowlower
02644       basePv.setVector(base->getNumRows(),indices,base->getRowLower());
02645       pv.setVector( si1->getNumRows(),indices, si1->getRowLower());
02646       assert(basePv.isEquivalent(pv));
02647       pv.setVector( si2->getNumRows(),indices, si2->getRowLower());
02648       assert(basePv.isEquivalent(pv));
02649       pv.setVector( si3->getNumRows(),indices, si3->getRowLower());
02650       assert(basePv.isEquivalent(pv));
02651       pv.setVector( si4->getNumRows(),indices, si4->getRowLower());
02652       assert(basePv.isEquivalent(pv));
02653       pv.setVector( si5->getNumRows(),indices, si5->getRowLower());
02654       assert(basePv.isEquivalent(pv));
02655       pv.setVector( si6->getNumRows(),indices, si6->getRowLower());
02656       assert(basePv.isEquivalent(pv));
02657       pv.setVector( si7->getNumRows(),indices, si7->getRowLower());
02658       assert(basePv.isEquivalent(pv));
02659       pv.setVector( si8->getNumRows(),indices, si8->getRowLower());
02660       assert(basePv.isEquivalent(pv));
02661         
02662       // Test rowupper
02663       basePv.setVector(base->getNumRows(),indices,base->getRowUpper());
02664       pv.setVector( si1->getNumRows(),indices, si1->getRowUpper());
02665       assert(basePv.isEquivalent(pv));
02666       pv.setVector( si2->getNumRows(),indices, si2->getRowUpper());
02667       assert(basePv.isEquivalent(pv));
02668       pv.setVector( si3->getNumRows(),indices, si3->getRowUpper());
02669       assert(basePv.isEquivalent(pv));
02670       pv.setVector( si4->getNumRows(),indices, si4->getRowUpper());
02671       assert(basePv.isEquivalent(pv));
02672       pv.setVector( si5->getNumRows(),indices, si5->getRowUpper());
02673       assert(basePv.isEquivalent(pv));
02674       pv.setVector( si6->getNumRows(),indices, si6->getRowUpper());
02675       assert(basePv.isEquivalent(pv));
02676       pv.setVector( si7->getNumRows(),indices, si7->getRowUpper());
02677       assert(basePv.isEquivalent(pv));
02678       pv.setVector( si8->getNumRows(),indices, si8->getRowUpper());
02679       assert(basePv.isEquivalent(pv)); 
02680         
02681       // Test Constraint Matrix
02682       assert( base->getMatrixByCol()->isEquivalent(*si1->getMatrixByCol()) );
02683       assert( base->getMatrixByRow()->isEquivalent(*si1->getMatrixByRow()) );
02684       assert( base->getMatrixByCol()->isEquivalent(*si2->getMatrixByCol()) );
02685       assert( base->getMatrixByRow()->isEquivalent(*si2->getMatrixByRow()) );
02686       assert( base->getMatrixByCol()->isEquivalent(*si3->getMatrixByCol()) );
02687       assert( base->getMatrixByRow()->isEquivalent(*si3->getMatrixByRow()) );
02688       assert( base->getMatrixByCol()->isEquivalent(*si4->getMatrixByCol()) );
02689       assert( base->getMatrixByRow()->isEquivalent(*si4->getMatrixByRow()) );
02690       assert( base->getMatrixByCol()->isEquivalent(*si5->getMatrixByCol()) );
02691       assert( base->getMatrixByRow()->isEquivalent(*si5->getMatrixByRow()) );
02692       assert( base->getMatrixByCol()->isEquivalent(*si6->getMatrixByCol()) );
02693       assert( base->getMatrixByRow()->isEquivalent(*si6->getMatrixByRow()) );
02694       assert( base->getMatrixByCol()->isEquivalent(*si7->getMatrixByCol()) );
02695       assert( base->getMatrixByRow()->isEquivalent(*si7->getMatrixByRow()) );
02696       assert( base->getMatrixByCol()->isEquivalent(*si8->getMatrixByCol()) );
02697       assert( base->getMatrixByRow()->isEquivalent(*si8->getMatrixByRow()) );
02698         
02699       // Test Objective Value
02700       assert( eq(base->getObjValue(),si1->getObjValue()) );
02701       assert( eq(base->getObjValue(),si2->getObjValue()) );
02702       assert( eq(base->getObjValue(),si3->getObjValue()) );
02703       assert( eq(base->getObjValue(),si4->getObjValue()) );
02704       assert( eq(base->getObjValue(),si5->getObjValue()) );
02705       assert( eq(base->getObjValue(),si6->getObjValue()) );
02706       assert( eq(base->getObjValue(),si7->getObjValue()) );
02707       assert( eq(base->getObjValue(),si8->getObjValue()) );
02708         
02709       // Clean-up
02710       delete si8;
02711       delete si7;
02712       delete si6;
02713       delete si5;
02714       delete si4;
02715       delete si3;
02716       delete si2;
02717       delete si1;
02718       delete base;
02719     }     
02720     // Test load/assign with null parms
02721     {
02722       //Load problem with row bounds and all rims at defaults
02723       {
02724         OsiSolverInterface *  si = emptySi->clone(); 
02725           
02726         si->loadProblem(*exmip1Si->getMatrixByCol(),NULL,NULL,NULL,NULL,NULL);
02727           
02728         // Test column settings
02729         assert(si->getNumCols()==exmip1Si->getNumCols() );
02730         for ( i=0; i<si->getNumCols(); i++ ) {
02731           assert( eq(si->getColLower()[i],0.0) );
02732           assert( eq(si->getColUpper()[i],si->getInfinity()) );
02733           assert( eq(si->getObjCoefficients()[i],0.0) );
02734         }
02735         // Test row settings
02736         assert(si->getNumRows()==exmip1Si->getNumRows() );
02737         const double * rh = si->getRightHandSide();
02738         const double * rr = si->getRowRange();
02739         const char * rs = si->getRowSense();
02740         const double * rl = si->getRowLower();
02741         const double * ru = si->getRowUpper();
02742         for ( i=0; i<si->getNumRows(); i++ ) {
02743           assert( eq(rh[i],0.0) );
02744           assert( eq(rr[i],0.0) );
02745           assert( 'N'==rs[i] );
02746           assert( eq(rl[i],-si->getInfinity()) );
02747           assert( eq(ru[i], si->getInfinity()) );
02748         }
02749           
02750         delete si;
02751       }
02752       //Load problem with row rhs and all rims at defaults
02753       {
02754         OsiSolverInterface *  si = emptySi->clone(); 
02755           
02756         si->loadProblem(*exmip1Si->getMatrixByRow(),
02757                         NULL,NULL,NULL,
02758                         exmip1Si->getRowSense(),
02759                         exmip1Si->getRightHandSide(),
02760                         exmip1Si->getRowRange());
02761         // Test column settings
02762         assert(si->getNumCols()==exmip1Si->getNumCols() );
02763         for ( i=0; i<si->getNumCols(); i++ ) {
02764           assert( eq(si->getColLower()[i],0.0) );
02765           assert( eq(si->getColUpper()[i],si->getInfinity()) );
02766           assert( eq(si->getObjCoefficients()[i],0.0) );
02767         }
02768         // Test row settings
02769         assert(si->getNumRows()==exmip1Si->getNumRows() );
02770         for ( i=0; i<si->getNumRows(); i++ ) {
02771           char s = si->getRowSense()[i];
02772           assert( eq(si->getRightHandSide()[i],
02773                      exmip1Si->getRightHandSide()[i]) );
02774           assert( eq(si->getRowRange()[i],
02775                      exmip1Si->getRowRange()[i]) );
02776           assert( s==exmip1Si->getRowSense()[i] );
02777             
02778           if ( s=='G' ) {
02779             assert( eq(si->getRowLower()[i],
02780                        exmip1Si->getRightHandSide()[i]) );
02781             assert( eq(si->getRowUpper()[i],
02782                        si->getInfinity()) );
02783           }
02784           else if ( s=='L' ) {
02785             assert( eq(si->getRowLower()[i],
02786                        -si->getInfinity()) );
02787             assert( eq(si->getRowUpper()[i],
02788                        exmip1Si->getRightHandSide()[i]) );
02789           }
02790           else if ( s=='E' ) {
02791             assert( eq(si->getRowLower()[i],
02792                        si->getRowUpper()[i]) );
02793             assert( eq(si->getRowUpper()[i],
02794                        exmip1Si->getRightHandSide()[i]) );
02795           }
02796           else if ( s=='N' ) {
02797             assert( eq(si->getRowLower()[i], -si->getInfinity()) );
02798             assert( eq(si->getRowUpper()[i],  si->getInfinity()) );
02799           }
02800           else if ( s=='R' ) {
02801             assert( eq(si->getRowLower()[i],
02802                        exmip1Si->getRightHandSide()[i] -
02803                        exmip1Si->getRowRange()[i]) );
02804             assert( eq(si->getRowUpper()[i],
02805                        exmip1Si->getRightHandSide()[i]) );
02806           }
02807         }
02808           
02809         delete si;
02810       }
02811       // Test adding rows to NULL
02812       {
02813         OsiSolverInterface *  si = emptySi->clone();
02814         int i;
02815 
02816         //Matrix
02817         int column[]={0,1,2};
02818         double row1E[]={4.0,7.0,5.0};
02819         double row2E[]={7.0,4.0,5.0};
02820         CoinPackedVector row1(3,column,row1E);
02821         CoinPackedVector row2(3,column,row2E);
02822 
02823         double objective[]={5.0,6.0,5.5};
02824 
02825   {
02826           // Add empty columns
02827           for (i=0;i<3;i++) 
02828             si->addCol(CoinPackedVector(),0.0,10.0,objective[i]);
02829 
02830           // Add rows
02831           si->addRow(row1,2.0,100.0);
02832           si->addRow(row2,2.0,100.0);
02833 
02834     // Vol can not solve problem of this form
02835     if ( !volSolverInterface ) {
02836             // solve
02837             si->initialSolve();
02838 
02839       CoinRelFltEq eq(1.0e-7) ;
02840       double objValue = si->getObjValue();
02841             if ( !eq(objValue,2.0) )
02842         failureMessage(solverName,"getObjValue after adding empty cols and then rows.");;
02843     }
02844   }
02845 
02846         delete si;
02847       }
02848       // Test adding columns to NULL
02849       {
02850         OsiSolverInterface *  si = emptySi->clone();
02851         int i;
02852 
02853         //Matrix
02854         int row[]={0,1};
02855         double col1E[]={4.0,7.0};
02856         double col2E[]={7.0,4.0};
02857         double col3E[]={5.0,5.0};
02858         CoinPackedVector col1(2,row,col1E);
02859         CoinPackedVector col2(2,row,col2E);
02860         CoinPackedVector col3(2,row,col3E);
02861 
02862         double objective[]={5.0,6.0,5.5};
02863   {
02864      // Add empty rows
02865      for (i=0;i<2;i++) 
02866         si->addRow(CoinPackedVector(),2.0,100.0);
02867 
02868      // Add columns
02869      if ( volSolverInterface ) {
02870         // FIXME: this test could be done w/ the volume, but the rows must not
02871         // be ranged.
02872         failureMessage(solverName,"addCol add columns to null");
02873      }
02874      else {
02875         si->addCol(col1,0.0,10.0,objective[0]);
02876         si->addCol(col2,0.0,10.0,objective[1]);
02877         si->addCol(col3,0.0,10.0,objective[2]);
02878 
02879         // solve
02880         si->initialSolve();
02881 
02882         CoinRelFltEq eq(1.0e-7) ;      
02883         double objValue = si->getObjValue();
02884         if ( !eq(objValue,2.0) )
02885            failureMessage(solverName,"getObjValue after adding empty rows and then cols.");
02886 
02887      }
02888   }
02889         delete si;
02890       }
02891     }
02892   }
02893 
02894   // Add a Laci suggested test case
02895   // Load in a problem as column ordered matrix, 
02896   // extract the row ordered copy, 
02897   // add a row, 
02898   // extract the row ordered copy again and test whether it's ok. 
02899   // (the same can be done with reversing the role
02900   //  of row and column ordered.)
02901   {
02902     OsiSolverInterface *  si = emptySi->clone(); 
02903       
02904     si->loadProblem(
02905                     *(exmip1Si->getMatrixByCol()),
02906                     exmip1Si->getColLower(),
02907                     exmip1Si->getColUpper(),
02908                     exmip1Si->getObjCoefficients(),
02909                     exmip1Si->getRowSense(),
02910                     exmip1Si->getRightHandSide(),
02911                     exmip1Si->getRowRange() );
02912 
02913     CoinPackedMatrix pm1 = *(si->getMatrixByRow());
02914 
02915     // Get a row of the matrix to make a cut
02916     CoinPackedVector pv =exmip1Si->getMatrixByRow()->getVector(1);
02917     pv.setElement(0,3.14*pv.getElements()[0]);
02918 
02919     OsiRowCut rc;
02920     rc.setRow( pv );
02921     rc.setLb( exmip1Si->getRowLower()[1]-0.5 );
02922     rc.setUb( exmip1Si->getRowUpper()[1]-0.5 );
02923 
02924     OsiCuts cuts;
02925     cuts.insert(rc);
02926 
02927     si->applyCuts(cuts);
02928       
02929     CoinPackedMatrix pm2 = *(si->getMatrixByRow());
02930 
02931     assert(pm1.getNumRows()==pm2.getNumRows()-1);
02932     int i;
02933     for( i=0; i<pm1.getNumRows(); ++i ) {
02934       assert( pm1.getVector(i) == pm2.getVector(i) );
02935     }
02936     // Test that last row of pm2 is same as added cut
02937     assert( pm2.getVector(pm2.getNumRows()-1).isEquivalent(pv) );
02938 
02939     delete si;
02940   }
02941   {
02942     OsiSolverInterface *  si = emptySi->clone(); 
02943       
02944     si->loadProblem(
02945                     *(exmip1Si->getMatrixByRow()),
02946                     exmip1Si->getColLower(),
02947                     exmip1Si->getColUpper(),
02948                     exmip1Si->getObjCoefficients(),
02949                     exmip1Si->getRowLower(),
02950                     exmip1Si->getRowUpper() );
02951 
02952     CoinPackedMatrix pm1 = *(si->getMatrixByCol());
02953 
02954     // Get a row of the matrix to make a cut
02955     CoinPackedVector pv =exmip1Si->getMatrixByRow()->getVector(1);
02956     pv.setElement(0,3.14*pv.getElements()[0]);
02957 
02958     OsiRowCut rc;
02959     rc.setRow( pv );
02960     rc.setLb( exmip1Si->getRowLower()[1]-0.5 );
02961     rc.setUb( exmip1Si->getRowUpper()[1]-0.5 );
02962 
02963     OsiCuts cuts;
02964     cuts.insert(rc);
02965 
02966     si->applyCuts(cuts);
02967       
02968     CoinPackedMatrix pm2 = *(si->getMatrixByCol());
02969 
02970     assert( pm1.isColOrdered() );
02971     assert( pm2.isColOrdered() );
02972     assert( pm1.getNumRows()==pm2.getNumRows()-1 );
02973 
02974     CoinPackedMatrix pm1ByRow;
02975     pm1ByRow.reverseOrderedCopyOf(pm1);
02976     CoinPackedMatrix pm2ByRow;
02977     pm2ByRow.reverseOrderedCopyOf(pm2);
02978 
02979     assert( !pm1ByRow.isColOrdered() );
02980     assert( !pm2ByRow.isColOrdered() );      
02981     assert( pm1ByRow.getNumRows()==pm2ByRow.getNumRows()-1 );
02982     assert( pm1.getNumRows() == pm1ByRow.getNumRows() );
02983     assert( pm2.getNumRows() == pm2ByRow.getNumRows() );
02984 
02985     int i;
02986     for( i=0; i<pm1ByRow.getNumRows(); ++i ) {
02987       assert( pm1ByRow.getVector(i) == pm2ByRow.getVector(i) );
02988     }
02989     // Test that last row of pm2 is same as added cut
02990     assert( pm2ByRow.getVector(pm2ByRow.getNumRows()-1).isEquivalent(pv) );
02991 
02992     delete si;
02993   }
02994     
02995   delete exmip1Si;
02996 
02997   {
02998     // Testing parameter settings
02999     OsiSolverInterface *  si = emptySi->clone();
03000     int i;
03001     int ival;
03002     double dval;
03003     bool hint;
03004     OsiHintStrength hintStrength;
03005     assert(si->getIntParam(OsiLastIntParam, ival) == false);
03006     assert(si->getDblParam(OsiLastDblParam, dval) == false);
03007     assert(si->getHintParam(OsiLastHintParam, hint) == false);
03008     assert(si->setIntParam(OsiLastIntParam, 0) == false);
03009     assert(si->setDblParam(OsiLastDblParam, 0) == false);
03010     assert(si->setHintParam(OsiLastHintParam, false) == false);
03011     
03012     for (i = 0; i < OsiLastIntParam; ++i) {
03013       const bool exists = si->getIntParam(static_cast<OsiIntParam>(i), ival);
03014       // existence and test should result in the same
03015       assert(!exists ^ testIntParam(si, i, -1));
03016       assert(!exists ^ testIntParam(si, i, 0));
03017       assert(!exists ^ testIntParam(si, i, 1));
03018       assert(!exists ^ testIntParam(si, i, 9999999));
03019       assert(!exists ^ testIntParam(si, i, INT_MAX));
03020       if (exists)
03021         assert(si->getIntParam(static_cast<OsiIntParam>(i), ival));
03022     }
03023     // Test for glpk since it dies on this test
03024     if ( glpkSolverInterface ) {
03025       failureMessage(solverName,"[g,s]etDblParam");
03026     }
03027     else {
03028       for (i = 0; i < OsiLastDblParam; ++i) {
03029         const bool exists = si->getDblParam(static_cast<OsiDblParam>(i), dval);
03030         // existence and test should result in the same
03031         assert(!exists ^ testDblParam(si, i, -1e50));
03032         assert(!exists ^ testDblParam(si, i, -1e10));
03033         assert(!exists ^ testDblParam(si, i, -1));
03034         assert(!exists ^ testDblParam(si, i, -1e-4));
03035         assert(!exists ^ testDblParam(si, i, -1e-15));
03036         assert(!exists ^ testDblParam(si, i, 1e50));
03037         assert(!exists ^ testDblParam(si, i, 1e10));
03038         assert(!exists ^ testDblParam(si, i, 1));
03039         assert(!exists ^ testDblParam(si, i, 1e-4));
03040         assert(!exists ^ testDblParam(si, i, 1e-15));
03041         if (exists)
03042           assert(si->setDblParam(static_cast<OsiDblParam>(i), dval));
03043       }
03044     }
03045 
03046     // test hints --- see testHintParam for detailed explanation.
03047 
03048     { int throws = 0 ;
03049 
03050       for (i = 0 ; i < OsiLastHintParam ; ++i)
03051       { const bool exists =
03052           si->getHintParam(static_cast<OsiHintParam>(i),hint,hintStrength) ;
03053 
03054         assert(!exists ^ testHintParam(si,i,true,OsiHintIgnore,&throws)) ;
03055         assert(!exists ^ testHintParam(si,i,true,OsiHintTry,&throws)) ;
03056         assert(!exists ^ testHintParam(si,i,false,OsiHintTry,&throws)) ;
03057         assert(!exists ^ testHintParam(si,i,true,OsiHintDo,&throws)) ;
03058         assert(!exists ^ testHintParam(si,i,false,OsiHintDo,&throws)) ;
03059         assert(!exists ^ testHintParam(si,i,true,OsiForceDo,&throws)) ;
03060         assert(!exists ^ testHintParam(si,i,false,OsiForceDo,&throws)) ; }
03061       
03062       std::cerr << "Checked " << OsiLastHintParam <<
03063                    " hints x (true, false) at strength OsiForceDo; " <<
03064                    throws << " throws." << std::endl ;
03065     }
03066 
03067     delete si;
03068   }
03069   
03070   // Test case submitted by Vivian De Smedt (slightly modifed to work with
03071   // Vol Algorithm).
03072 
03073   {
03074     OsiSolverInterface *s = emptySi->clone();
03075     double dEmpty = 0;
03076     int iEmpty = 0;
03077     //char cEmpty = '?';
03078     
03079     s->loadProblem(0, 0, &iEmpty, &iEmpty, &dEmpty, &dEmpty, &dEmpty, &dEmpty, &dEmpty, &dEmpty);
03080     double inf = s->getInfinity();
03081     CoinPackedVector c;
03082     
03083     s->addCol(c, 0, 10, 3);
03084     s->addCol(c, 0, 10, 1);
03085     
03086     CoinPackedVector r1;
03087     r1.insert(0, 2);
03088     r1.insert(1, 1);
03089     s->addRow(r1, -inf, 10);
03090     
03091     CoinPackedVector r2;
03092     r2.insert(0, 1);
03093     r2.insert(1, 3);
03094     s->addRow(r2, -inf, 15);
03095     
03096     s->setObjSense(-1);
03097 
03098     s->initialSolve() ;
03099     const double * colSol = s->getColSolution();
03100     // Don't test for exact answer, because Vol algorithm
03101     // only returns an appoximate solution
03102     assert( colSol[0]>4.5 );
03103     assert( colSol[1]<0.5 );
03104     
03105     s->setObjCoeff(0, 1);
03106     s->setObjCoeff(1, 1);
03107     
03108     s->resolve();    
03109     colSol = s->getColSolution();
03110     // Don't test for exact answer, because Vol algorithm
03111     // only returns an appoximate solution
03112     assert( colSol[0]>2.3 && colSol[0]<3.7 );
03113     assert( colSol[1]>3.5 && colSol[1]<4.5 );
03114     delete s;
03115   }
03116 
03117   // Test presolve
03118   if ( !volSolverInterface) {
03119     OsiSolverInterface * si = emptySi->clone();
03120     std::string fn = netlibDir+"25fv47";
03121     si->readMps(fn.c_str(),"mps");
03122     OsiSolverInterface * presolvedModel;
03123     OsiPresolve pinfo;
03124     int numberPasses=5; // can change this
03125     /* Use a tolerance of 1.0e-8 for feasibility, treat problem as 
03126        not being integer, do "numberpasses" passes */
03127     presolvedModel = pinfo.presolvedModel(*si,1.0e-8,false,numberPasses);
03128     assert(presolvedModel);
03129     // switch off presolve
03130     presolvedModel->setHintParam(OsiDoPresolveInInitial,false);
03131     presolvedModel->initialSolve();
03132     double objValue = presolvedModel->getObjValue(); 
03133     if( !eq(objValue,5.5018458883e+03) )
03134       failureMessage(solverName,"OsiPresolved model has wrong objective");
03135     pinfo.postsolve(true);
03136 
03137 
03138     delete presolvedModel;
03139     si->setHintParam(OsiDoPresolveInResolve,false);
03140     si->setHintParam(OsiDoDualInResolve,false);
03141     si->resolve();
03142     objValue = si->getObjValue(); 
03143     if( !eq(objValue,5.5018458883e+03) )
03144       failureMessage(solverName,"OsiPresolve - final objective wrong");
03145     if (si->getIterationCount())
03146       failureMessage(solverName,"OsiPresolve - minor error, needs iterations");
03147     delete si;
03148   }
03149 
03150   // Perform tests that are embodied in functions
03151   if ( !volSolverInterface )
03152   {
03153     
03154     typedef bool (*TestFunction)(OsiSolverInterface*);
03155     std::vector<std::pair<TestFunction, const char*> > test_functions;
03156     test_functions.push_back(std::pair<TestFunction, const char*>(&test1VivianDeSmedt, "test1VivianDeSmedt"));
03157     test_functions.push_back(std::pair<TestFunction, const char*>(&test2VivianDeSmedt, "test2VivianDeSmedt"));
03158     test_functions.push_back(std::pair<TestFunction, const char*>(&test3VivianDeSmedt, "test3VivianDeSmedt"));
03159     test_functions.push_back(std::pair<TestFunction, const char*>(&test4VivianDeSmedt, "test4VivianDeSmedt"));
03160     test_functions.push_back(std::pair<TestFunction, const char*>(&test5VivianDeSmedt, "test5VivianDeSmedt"));
03161     test_functions.push_back(std::pair<TestFunction, const char*>(&test6VivianDeSmedt, "test6VivianDeSmedt"));
03162     test_functions.push_back(std::pair<TestFunction, const char*>(&test7VivianDeSmedt, "test7VivianDeSmedt"));
03163     test_functions.push_back(std::pair<TestFunction, const char*>(&test8VivianDeSmedt, "test8VivianDeSmedt"));
03164     test_functions.push_back(std::pair<TestFunction, const char*>(&test9VivianDeSmedt, "test9VivianDeSmedt"));
03165     test_functions.push_back(std::pair<TestFunction, const char*>(&test10VivianDeSmedt,"test10VivianDeSmedt"));
03166     test_functions.push_back(std::pair<TestFunction, const char*>(&test11VivianDeSmedt,"test11VivianDeSmedt"));
03167     test_functions.push_back(std::pair<TestFunction, const char*>(&test12VivianDeSmedt,"test12VivianDeSmedt"));
03168     test_functions.push_back(std::pair<TestFunction, const char*>(&test13VivianDeSmedt,"test13VivianDeSmedt"));
03169     test_functions.push_back(std::pair<TestFunction, const char*>(&test14VivianDeSmedt,"test14VivianDeSmedt"));
03170     test_functions.push_back(std::pair<TestFunction, const char*>(&test15VivianDeSmedt,"test15VivianDeSmedt"));
03171     
03172     unsigned int i;
03173     for (i = 0; i < test_functions.size(); ++i) {
03174       OsiSolverInterface *s = emptySi->clone();
03175       const char * testName = test_functions[i].second;
03176       {
03177         bool test = test_functions[i].first(s);
03178         if (!test)
03179           failureMessage(*s, testName);
03180       }
03181       delete s;
03182     }
03183   }
03184   /*
03185     Orphan comment? If anyone happens to poke at the code that this belongs
03186     to, move it. 
03187 
03188     With this matrix we have a primal/dual infeas problem. Leaving the first
03189     row makes it primal feas, leaving the first col makes it dual feas.
03190     All vars are >= 0
03191 
03192     obj: -1  2 -3  4 -5 (min)
03193 
03194           0 -1  0  0 -2  >=  1
03195           1  0 -3  0  4  >= -2
03196           0  3  0 -5  0  >=  3
03197           0  0  5  0 -6  >= -4
03198           2 -4  0  6  0  >=  5
03199   */
03200 }

void OsiSolverInterfaceMpsUnitTest const std::vector< OsiSolverInterface * > &  vecSiP,
const std::string &  mpsDir
[friend]
 

Run solvers on NetLib problems.

The routine creates a vector of NetLib problems (problem name, objective, various other characteristics), and a vector of solvers to be tested.

Each solver is run on each problem. The run is deemed successful if the solver reports the correct problem size after loading and returns the correct objective value after optimization.

If multiple solvers are available, the results are compared pairwise against the results reported by adjacent solvers in the solver vector. Due to limitations of the volume solver, it must be the last solver in vecEmptySiP.

Definition at line 1116 of file OsiSolverInterfaceTest.cpp.

01119 { int i ;
01120   unsigned int m ;
01121 
01122 /*
01123   Vectors to hold test problem names and characteristics. The objective value
01124   after optimization (objValue) must agree to the specified tolerance
01125   (objValueTol).
01126 */
01127   std::vector<std::string> mpsName ;
01128   std::vector<bool> min ;
01129   std::vector<int> nRows ;
01130   std::vector<int> nCols ;
01131   std::vector<double> objValue ;
01132   std::vector<double> objValueTol ;
01133 /*
01134   And a macro to make the vector creation marginally readable.
01135 */
01136 #define PUSH_MPS(zz_mpsName_zz,zz_min_zz,\
01137                  zz_nRows_zz,zz_nCols_zz,zz_objValue_zz,zz_objValueTol_zz) \
01138   mpsName.push_back(zz_mpsName_zz) ; \
01139   min.push_back(zz_min_zz) ; \
01140   nRows.push_back(zz_nRows_zz) ; \
01141   nCols.push_back(zz_nCols_zz) ; \
01142   objValueTol.push_back(zz_objValueTol_zz) ; \
01143   objValue.push_back(zz_objValue_zz) ;
01144 
01145 /*
01146   Load up the problem vector. Note that the row counts here include the
01147   objective function.
01148 */
01149   PUSH_MPS("25fv47",true,822,1571,5.5018458883E+03,1.0e-10)
01150   PUSH_MPS("80bau3b",true,2263,9799,9.8722419241E+05,1.e-10)
01151   PUSH_MPS("adlittle",true,57,97,2.2549496316e+05,1.e-10)
01152   PUSH_MPS("afiro",true,28,32,-4.6475314286e+02,1.e-10)
01153   PUSH_MPS("agg",true,489,163,-3.5991767287e+07,1.e-10)
01154   PUSH_MPS("agg2",true,517,302,-2.0239252356e+07,1.e-10)
01155   PUSH_MPS("agg3",true,517,302,1.0312115935e+07,1.e-10)
01156   PUSH_MPS("bandm",true,306,472,-1.5862801845e+02,1.e-10)
01157   PUSH_MPS("beaconfd",true,174,262,3.3592485807e+04,1.e-10)
01158   PUSH_MPS("blend",true,75,83,-3.0812149846e+01,1.e-10)
01159   PUSH_MPS("bnl1",true,644,1175,1.9776295615E+03,1.e-10)
01160   PUSH_MPS("bnl2",true,2325,3489,1.8112365404e+03,1.e-10)
01161   PUSH_MPS("boeing1",true,/*351*/352,384,-3.3521356751e+02,1.e-10)
01162   PUSH_MPS("boeing2",true,167,143,-3.1501872802e+02,1.e-10)
01163   PUSH_MPS("bore3d",true,234,315,1.3730803942e+03,1.e-10)
01164   PUSH_MPS("brandy",true,221,249,1.5185098965e+03,1.e-10)
01165   PUSH_MPS("capri",true,272,353,2.6900129138e+03,1.e-10)
01166   PUSH_MPS("cycle",true,1904,2857,-5.2263930249e+00,1.e-9)
01167   PUSH_MPS("czprob",true,930,3523,2.1851966989e+06,1.e-10)
01168   PUSH_MPS("d2q06c",true,2172,5167,122784.21557456,1.e-7)
01169   PUSH_MPS("d6cube",true,416,6184,3.1549166667e+02,1.e-8)
01170   PUSH_MPS("degen2",true,445,534,-1.4351780000e+03,1.e-10)
01171   PUSH_MPS("degen3",true,1504,1818,-9.8729400000e+02,1.e-10)
01172   PUSH_MPS("dfl001",true,6072,12230,1.1266396047E+07,1.e-5)
01173   PUSH_MPS("e226",true,224,282,(-18.751929066+7.113),1.e-10) // NOTE: Objective function has constant of 7.113
01174   PUSH_MPS("etamacro",true,401,688,-7.5571521774e+02 ,1.e-6)
01175   PUSH_MPS("fffff800",true,525,854,5.5567961165e+05,1.e-6)
01176   PUSH_MPS("finnis",true,498,614,1.7279096547e+05,1.e-6)
01177   PUSH_MPS("fit1d",true,25,1026,-9.1463780924e+03,1.e-10)
01178   PUSH_MPS("fit1p",true,628,1677,9.1463780924e+03,1.e-10)
01179   PUSH_MPS("fit2d",true,26,10500,-6.8464293294e+04,1.e-10)
01180   PUSH_MPS("fit2p",true,3001,13525,6.8464293232e+04,1.e-9)
01181   PUSH_MPS("forplan",true,162,421,-6.6421873953e+02,1.e-6)
01182   PUSH_MPS("ganges",true,1310,1681,-1.0958636356e+05,1.e-5)
01183   PUSH_MPS("gfrd-pnc",true,617,1092,6.9022359995e+06,1.e-10)
01184   PUSH_MPS("greenbea",true,2393,5405,/*-7.2462405908e+07*/-72555248.129846,1.e-10)
01185   PUSH_MPS("greenbeb",true,2393,5405,/*-4.3021476065e+06*/-4302260.2612066,1.e-10)
01186   PUSH_MPS("grow15",true,301,645,-1.0687094129e+08,1.e-10)
01187   PUSH_MPS("grow22",true,441,946,-1.6083433648e+08,1.e-10)
01188   PUSH_MPS("grow7",true,141,301,-4.7787811815e+07,1.e-10)
01189   PUSH_MPS("israel",true,175,142,-8.9664482186e+05,1.e-10)
01190   PUSH_MPS("kb2",true,44,41,-1.7499001299e+03,1.e-10)
01191   PUSH_MPS("lotfi",true,154,308,-2.5264706062e+01,1.e-10)
01192   PUSH_MPS("maros",true,847,1443,-5.8063743701e+04,1.e-10)
01193   PUSH_MPS("maros-r7",true,3137,9408,1.4971851665e+06,1.e-10)
01194   PUSH_MPS("modszk1",true,688,1620,3.2061972906e+02,1.e-10)
01195   PUSH_MPS("nesm",true,663,2923,1.4076073035e+07,1.e-5)
01196   PUSH_MPS("perold",true,626,1376,-9.3807580773e+03,1.e-6)
01197   PUSH_MPS("pilot",true,1442,3652,/*-5.5740430007e+02*/-557.48972927292,5.e-5)
01198   PUSH_MPS("pilot4",true,411,1000,-2.5811392641e+03,1.e-6)
01199   PUSH_MPS("pilot87",true,2031,4883,3.0171072827e+02,1.e-4)
01200   PUSH_MPS("pilotnov",true,976,2172,-4.4972761882e+03,1.e-10)
01201   // ?? PUSH_MPS("qap8",true,913,1632,2.0350000000e+02,1.e-10)
01202   // ?? PUSH_MPS("qap12",true,3193,8856,5.2289435056e+02,1.e-10)
01203   // ?? PUSH_MPS("qap15",true,6331,22275,1.0409940410e+03,1.e-10)
01204   PUSH_MPS("recipe",true,92,180,-2.6661600000e+02,1.e-10)
01205   PUSH_MPS("sc105",true,106,103,-5.2202061212e+01,1.e-10)
01206   PUSH_MPS("sc205",true,206,203,-5.2202061212e+01,1.e-10)
01207   PUSH_MPS("sc50a",true,51,48,-6.4575077059e+01,1.e-10)
01208   PUSH_MPS("sc50b",true,51,48,-7.0000000000e+01,1.e-10)
01209   PUSH_MPS("scagr25",true,472,500,-1.4753433061e+07,1.e-10)
01210   PUSH_MPS("scagr7",true,130,140,-2.3313892548e+06,1.e-6)
01211   PUSH_MPS("scfxm1",true,331,457,1.8416759028e+04,1.e-10)
01212   PUSH_MPS("scfxm2",true,661,914,3.6660261565e+04,1.e-10)
01213   PUSH_MPS("scfxm3",true,991,1371,5.4901254550e+04,1.e-10)
01214   PUSH_MPS("scorpion",true,389,358,1.8781248227e+03,1.e-10)
01215   PUSH_MPS("scrs8",true,491,1169,9.0429998619e+02,1.e-5)
01216   PUSH_MPS("scsd1",true,78,760,8.6666666743e+00,1.e-10)
01217   PUSH_MPS("scsd6",true,148,1350,5.0500000078e+01,1.e-10)
01218   PUSH_MPS("scsd8",true,398,2750,9.0499999993e+02,1.e-8)
01219   PUSH_MPS("sctap1",true,301,480,1.4122500000e+03,1.e-10)
01220   PUSH_MPS("sctap2",true,1091,1880,1.7248071429e+03,1.e-10)
01221   PUSH_MPS("sctap3",true,1481,2480,1.4240000000e+03,1.e-10)
01222   PUSH_MPS("seba",true,516,1028,1.5711600000e+04,1.e-10)
01223   PUSH_MPS("share1b",true,118,225,-7.6589318579e+04,1.e-10)
01224   PUSH_MPS("share2b",true,97,79,-4.1573224074e+02,1.e-10)
01225   PUSH_MPS("shell",true,537,1775,1.2088253460e+09,1.e-10)
01226   PUSH_MPS("ship04l",true,403,2118,1.7933245380e+06,1.e-10)
01227   PUSH_MPS("ship04s",true,403,1458,1.7987147004e+06,1.e-10)
01228   PUSH_MPS("ship08l",true,779,4283,1.9090552114e+06,1.e-10)
01229   PUSH_MPS("ship08s",true,779,2387,1.9200982105e+06,1.e-10)
01230   PUSH_MPS("ship12l",true,1152,5427,1.4701879193e+06,1.e-10)
01231   PUSH_MPS("ship12s",true,1152,2763,1.4892361344e+06,1.e-10)
01232   PUSH_MPS("sierra",true,1228,2036,1.5394362184e+07,1.e-10)
01233   PUSH_MPS("stair",true,357,467,-2.5126695119e+02,1.e-10)
01234   PUSH_MPS("standata",true,360,1075,1.2576995000e+03,1.e-10)
01235   // GUB PUSH_MPS("standgub",true,362,1184,1257.6995,1.e-10) 
01236   PUSH_MPS("standmps",true,468,1075,1.4060175000E+03,1.e-10) 
01237   PUSH_MPS("stocfor1",true,118,111,-4.1131976219E+04,1.e-10)
01238   PUSH_MPS("stocfor2",true,2158,2031,-3.9024408538e+04,1.e-10)
01239   // ?? PUSH_MPS("stocfor3",true,16676,15695,-3.9976661576e+04,1.e-10)
01240   // ?? PUSH_MPS("truss",true,1001,8806,4.5881584719e+05,1.e-10)
01241   PUSH_MPS("tuff",true,334,587,2.9214776509e-01,1.e-10)
01242   PUSH_MPS("vtpbase",true,199,203,1.2983146246e+05,1.e-10)
01243   PUSH_MPS("wood1p",true,245,2594,1.4429024116e+00,5.e-5)
01244   PUSH_MPS("woodw",true,1099,8405,1.3044763331E+00,1.e-10)
01245 
01246 #undef PUSH_MPS
01247 
01248 /*
01249   Create a vector of solver interfaces that we can use to run the test
01250   problems. The strategy is to create a fresh clone of the `empty' solvers
01251   from vecEmptySiP for each problem, then proceed in stages: read the MPS
01252   file, solve the problem, check the solution. If there are multiple
01253   solvers in vecSiP, the results of each solver are compared with its
01254   neighbors in the vector.
01255 */
01256   std::vector<OsiSolverInterface*> vecSiP(vecEmptySiP.size()) ;
01257 
01258   // Create vector to store a name for each solver interface
01259   // and a count on the number of problems the solver intface solved.
01260   std::vector<std::string> siName;
01261   std::vector<int> numProbSolved;
01262   std::vector<double> timeTaken;
01263   const int vecsize = vecSiP.size();
01264   for ( i=0; i<vecsize; i++ ) {
01265     siName.push_back("unknown");
01266     numProbSolved.push_back(0);
01267     timeTaken.push_back(0.0);
01268   }
01269   
01270   
01271   //Open the main loop to step through the MPS problems.
01272   for (m = 0 ; m < mpsName.size() ; m++) { 
01273     std::cerr << "  processing mps file: " << mpsName[m] 
01274       << " (" << m+1 << " out of " << mpsName.size() << ")" << std::endl ;
01275     bool allSolversReadMpsFile = true;
01276     
01277     
01278     //Stage 1: Read the MPS file into each solver interface.
01279     //Fill vecSiP with fresh clones of the solvers and read in the MPS file. As
01280     //a basic check, make sure the size of the constraint matrix is correct.
01281     for (i = vecSiP.size()-1 ; i >= 0 ; --i) { 
01282       vecSiP[i] = vecEmptySiP[i]->clone() ;
01283       
01284       vecSiP[i]->getStrParam(OsiSolverName,siName[i]);
01285 /* 
01286   REMOVE ME
01287 
01288   #     ifdef COIN_USE_DYLP
01289       { 
01290         OsiDylpSolverInterface * si =
01291           dynamic_cast<OsiDylpSolverInterface *>(vecSiP[i]) ;
01292         if (si != NULL )  { 
01293           // Solver is DYLP.
01294           // Skip over netlib cases that DYLP struggles with.
01295           // Does not read forplan mps file
01296           if ( mpsName[m]=="forplan" ) {
01297             failureMessage(siName[i],"mps reader will not read forplan");
01298             allSolversReadMpsFile = false;
01299             continue;
01300           }
01301         }
01302       }
01303   #     endif
01304 */
01305       
01306       std::string fn = mpsDir+mpsName[m] ;
01307       vecSiP[i]->readMps(fn.c_str(),"mps") ;
01308       
01309       if (min[m])
01310         vecSiP[i]->setObjSense(1.0) ;
01311       else
01312         vecSiP[i]->setObjSense(-1.0) ;
01313       
01314       int nr = vecSiP[i]->getNumRows() ;
01315       int nc = vecSiP[i]->getNumCols() ;
01316       assert(nr == nRows[m]-1) ;
01317       assert(nc == nCols[m]) ; 
01318     } 
01319     
01320     //If we have multiple solvers, compare the representations.
01321     if ( allSolversReadMpsFile )
01322       for (i = vecSiP.size()-1 ; i > 0 ; --i) { 
01323         CoinPackedVector vim1,vi ;
01324         
01325         // Compare col lowerbounds
01326         assert(
01327           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01328           vecSiP[i-1]->getColLower(),vecSiP[i  ]->getColLower(),
01329           vecSiP[i  ]->getNumCols() )
01330           ) ;
01331         
01332         // Compare col upperbounds
01333         assert(
01334           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01335           vecSiP[i-1]->getColUpper(),vecSiP[i  ]->getColUpper(),
01336           vecSiP[i  ]->getNumCols() )
01337           ) ;
01338         
01339         // Compare row lowerbounds
01340         assert(
01341           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01342           vecSiP[i-1]->getRowLower(),vecSiP[i  ]->getRowLower(),
01343           vecSiP[i  ]->getNumRows() )
01344           ) ;
01345         
01346         // Compare row upperbounds
01347         assert( 
01348           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01349           vecSiP[i-1]->getRowUpper(),vecSiP[i  ]->getRowUpper(),
01350           vecSiP[i  ]->getNumRows() )
01351           ) ;
01352         
01353         // Compare row sense
01354         {
01355           const char * rsm1 = vecSiP[i-1]->getRowSense() ;
01356           const char * rs   = vecSiP[i  ]->getRowSense() ;
01357           int nr = vecSiP[i]->getNumRows() ;
01358           int r ;
01359           for (r = 0 ; r < nr ; r++) assert (rsm1[r] == rs[r]) ;
01360         }
01361         
01362         // Compare rhs
01363         assert( 
01364           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01365           vecSiP[i-1]->getRightHandSide(),vecSiP[i  ]->getRightHandSide(),
01366           vecSiP[i  ]->getNumRows() )
01367           ) ;
01368         
01369         // Compare range
01370         assert( 
01371           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01372           vecSiP[i-1]->getRowRange(),vecSiP[i  ]->getRowRange(),
01373           vecSiP[i  ]->getNumRows() )
01374           ) ;
01375         
01376         // Compare objective sense
01377         assert( vecSiP[i-1]->getObjSense() == vecSiP[i  ]->getObjSense() ) ;
01378         
01379         // Compare objective coefficients
01380         assert( 
01381           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
01382           vecSiP[i-1]->getObjCoefficients(),vecSiP[i  ]->getObjCoefficients(),
01383           vecSiP[i  ]->getNumCols() )
01384           ) ;
01385         
01386         // Compare number of elements
01387         assert( vecSiP[i-1]->getNumElements() == vecSiP[i]->getNumElements() ) ;
01388         
01389         // Compare constraint matrix
01390         { 
01391           const CoinPackedMatrix * rmm1=vecSiP[i-1]->getMatrixByRow() ;
01392           const CoinPackedMatrix * rm  =vecSiP[i  ]->getMatrixByRow() ;
01393           assert( rmm1->isEquivalent(*rm) ) ;
01394           
01395           const CoinPackedMatrix * cmm1=vecSiP[i-1]->getMatrixByCol() ;
01396           const CoinPackedMatrix * cm  =vecSiP[i  ]->getMatrixByCol() ;
01397           assert( cmm1->isEquivalent(*cm) ) ; 
01398         } 
01399       }
01400       
01401       //If we have multiple solvers, compare the variable type information      
01402       if ( allSolversReadMpsFile )
01403         for (i = vecSiP.size()-1 ; i > 0 ; --i){ 
01404           CoinPackedVector vim1,vi ;
01405           int c ;
01406           
01407           { 
01408             OsiVectorInt sm1 = vecSiP[i-1]->getFractionalIndices() ;
01409             OsiVectorInt s   = vecSiP[i  ]->getFractionalIndices() ;
01410             assert( sm1.size() == s.size() ) ;
01411             for (c = s.size()-1 ; c >= 0 ; --c) assert( sm1[c] == s[c] ) ; 
01412           }
01413           
01414           { 
01415             int nc = vecSiP[i]->getNumCols() ;
01416             for (c = 0 ; c < nc ; c++){ 
01417               assert(
01418                 vecSiP[i-1]->isContinuous(c) == vecSiP[i]->isContinuous(c)
01419                 ) ;
01420               assert(
01421                 vecSiP[i-1]->isBinary(c) == vecSiP[i]->isBinary(c)
01422                 ) ;
01423               assert(
01424                 vecSiP[i-1]->isIntegerNonBinary(c) ==
01425                 vecSiP[i  ]->isIntegerNonBinary(c)
01426                 ) ;
01427               assert(
01428                 vecSiP[i-1]->isFreeBinary(c) == vecSiP[i]->isFreeBinary(c)
01429                 ) ;
01430               assert(
01431                 vecSiP[i-1]->isInteger(c) == vecSiP[i]->isInteger(c)
01432                 ) ; 
01433             } 
01434           } 
01435         }
01436         
01437       //Stage 2: Call each solver to solve the problem.
01438       //
01439       // We call each solver, then check the return code and objective.
01440       //  
01441       //    Note that the volume solver can't handle the Netlib cases. The strategy is
01442       //    to require that it be the last solver in vecSiP and then break out of the
01443       //    loop. This ensures that all previous solvers are run and compared to one
01444       //    another.      
01445       for (i = 0 ; i < static_cast<int>(vecSiP.size()) ; ++i) {
01446         double startTime = CoinCpuTime();
01447         
01448 #     ifdef COIN_USE_VOL
01449         { 
01450           OsiVolSolverInterface * si =
01451             dynamic_cast<OsiVolSolverInterface *>(vecSiP[i]) ;
01452           if (si != NULL )  { 
01453             // VOL does not solve netlib cases so don't bother trying to solve
01454             break ; 
01455           }
01456         }
01457 #     endif
01458 
01459 /*
01460   #     ifdef COIN_USE_DYLP
01461         { 
01462           OsiDylpSolverInterface * si =
01463             dynamic_cast<OsiDylpSolverInterface *>(vecSiP[i]) ;
01464           if (si != NULL )  { 
01465             // Solver is DYLP.
01466             // Skip over netlib cases that DYLP struggles with
01467             if ( mpsName[m]=="forplan" ) { continue; }
01468             // Does not converge to solution after many hours run time for pilot
01469             if ( mpsName[m]=="pilot" ) {
01470               failureMessage(siName[i],"skipping pilot. does not solve after many hours on windows");
01471               continue;
01472             }
01473             // Does not converge to solution after many hours run time for pilot
01474             if ( mpsName[m]=="pilot87" ) {
01475               failureMessage(siName[i],"skipping pilot. does not solve after an hour cpu time on windows");
01476               continue;
01477             }
01478           }
01479         }
01480   #     endif
01481 */
01482         
01483         vecSiP[i]->initialSolve() ;
01484         
01485         double timeOfSolution = CoinCpuTime()-startTime;
01486         if (vecSiP[i]->isProvenOptimal()) { 
01487           double soln = vecSiP[i]->getObjValue();       
01488           CoinRelFltEq eq(objValueTol[m]) ;
01489           if (eq(soln,objValue[m])) { 
01490             std::cerr 
01491               <<siName[i]<<"SolverInterface "
01492               << soln << " = " << objValue[m] << " ; okay";
01493             numProbSolved[i]++;
01494           } else  { 
01495             std::cerr <<siName[i] <<" " <<soln << " != " <<objValue[m] << "; error=" ;
01496             std::cerr <<fabs(objValue[m] - soln); 
01497           }
01498         } else {
01499           if (vecSiP[i]->isProvenPrimalInfeasible())  
01500             std::cerr << "error; primal infeasible" ;
01501           else if (vecSiP[i]->isProvenDualInfeasible())  
01502             std::cerr << "error; dual infeasible" ;
01503           else if (vecSiP[i]->isIterationLimitReached()) 
01504             std::cerr << "error; iteration limit" ;
01505           else if (vecSiP[i]->isAbandoned()) 
01506             std::cerr << "error; abandoned" ;
01507           else  
01508             std::cerr << "error; unknown" ;
01509         }
01510         std::cerr<<" - took " <<timeOfSolution<<" seconds."<<std::endl; 
01511         timeTaken[i] += timeOfSolution;
01512       }
01513       /*
01514       Delete the used solver interfaces so we can reload fresh clones for the
01515       next problem.
01516       */
01517       for (i = vecSiP.size()-1 ; i >= 0 ; --i) delete vecSiP[i] ;
01518   }
01519 
01520   const int siName_size = siName.size();
01521   for ( i=0; i<siName_size; i++ ) {
01522     std::cerr 
01523       <<siName[i] 
01524       <<" solved " 
01525       <<numProbSolved[i]
01526       <<" out of "
01527       <<objValue.size()
01528       <<" and took "
01529       <<timeTaken[i]
01530       <<" seconds."
01531       <<std::endl;
01532   } 
01533 }


Member Data Documentation

bool OsiSolverInterface::defaultHandler_ [protected]
 

Flag to say if the currrent handler is the default handler. Indicates if the solver interface object is responsible for destruction of the handler (true) or if the client is responsible (false).

Definition at line 1043 of file OsiSolverInterface.hpp.

CoinWarmStart* OsiSolverInterface::ws_ [private]
 

Warm start information used for hot starts when the default hot start implementation is used.

Reimplemented in OsiClpSolverInterface, and OsiOslSolverInterface.

Definition at line 1033 of file OsiSolverInterface.hpp.


The documentation for this class was generated from the following file:
Generated on Wed Dec 3 14:35:45 2003 for Osi by doxygen 1.3.5