[Coin-discuss] Proposal on addition of simplex-specific functions to OSI
Mikhail Nediak
msnediak at rutcor.rutgers.edu
Thu May 10 10:54:18 EDT 2001
Dear COIN developers,
Attached below is a plain text version of proposal on addition of
simplex-specific functions to OSI.
Comments and suggestions are very welcomed.
Kind regards,
Mikhail Nediak
******************************************************************
Proposal on addition of simplex-specific functions to OSI
This document is a result of discussion by
J. Eckstein, L. Ladanyi, J. Lee,
R. Lougee-Heimer and M. Nediak
Introduction
We propose to extend OsiSolverInterface to OsiSimplexSolverInterface class to
provide access to standard operations on the basis and facilitate
control over individual
pivots. This should facilitate an implementation of pivot-based IP
heuristics. There is also
a number of desirable problem and solution query routines that do not
seem to be
implemented in OsiSolverInterface. Finally, we would like to have a number of
additional dot-product methods for OsiPackedMatrix.
Access to the basis
It is the fact that most solvers do some kind of preprocessing of the
problem. This may result in elimination of some of the rows and
columns, and, maybe, change in the remaining elements of the
constraint matrix. Thus the purpose of the following methods is to
provide a limited access to the current problem representation only.
If the original indices of the structural variables are kept we do not
need a special version of the methods isContinuous(int colIndex),
isBinary(int colIndex), etc. in the
OsiSimplexSolverInterface. Otherwise all these will have to be
overridden.
We will assume below that slacks are index together with the primal
vector and are assigned indices from getNumCols()+1 to
getNumCols()+ getNumRows(). With this assumption we can require
isContinuous() to return true when it is given the index of slack variable.
Before we proceed with a description of OsiSimplexSolverInterface methods
it is also worth mentioning here that the
OsiSolverInterface class needs a method analogous to getColSolution():
virtual const double* getRowSlacks() const;
//Returns a pointer to an array of values of slack variables
Access to the basic and non-basic lists
The following two methods are abstract methods of the
OsiSimplexSolverInterface class. They will allow implementation of the
remaining basis access methods:
virtual bool basisIsAvailable() const;
//Returns true if the basis is available
virtual const int* getColStatus() const;
//Returns a status of the structural variables
virtual const int* getRowStatus() const;
//Returns a status of the slack variables
These functions return the pointers to arrays of integers containing
status of the columns/rows. Values in the array must belong to the
set of appropriately defined constants (indicating that the variable
is basic, nonbasic at the lower bound, nonbasic at the upper bound,
etc.).
For the rest of the methods, an implementation via getColStatus(),
getRowStatus(), getColSolution() and getRowSlacks() must be provided.
It can be overridden, if necessary for efficiency, in the descendants
of the OsiSimplexSolverInterface class:
virtual void getBasIndices(int* indices) const;
//returns basic variable indices (array indices must be of
//appropriate size)
virtual void getBasValues(double* values) const;
//returns basic variable values (array values must be of
//appropriate size)
virtual void getBasIndices(OsiVectorInt& indices) const;
//returns basic variable indices in indices (may be more convenient
//to implement than the version above)
virtual void getBasValues(OsiVectorDouble& values) const;
//returns basic variable values in values (may be more convenient
//to implement than the version above)
virtual void getBasics(OsiPackedVector& xB) const;
//get both in a packed vector
virtual void getNonBasAtLower(int* indices) const;
virtual void getNonBasAtLower(OsiVectorInt& indices) const;
//get a list of non-basic variables at their lower bounds
//(slacks included)
virtual void getNonBasAtUpper(int* indices) const;
virtual void getNonBasAtUpper(OsiVectorInt& indices) const;
//get a list of non-basic variables at their upper bounds
//(slacks included)
Access to the basic matrix
(they may use some internal buffers of the solver).
All of the following methods throw an appropriate exception if
operation is not successful.
virtual int bSolve(double* x, const double* y);
//Solve B*x=y. Components of x should be in the same order as indices
//returned by getBasIndices(). Both x and y are dense.
virtual int bSolve(double* x, const OsiPackedVectorBase& y);
//Solve B*x=y, same requirement for an order of components.
//The result is returned in a dense vector x.
virtual int bSolve(OsiPackedVector& x, const OsiPackedVectorBase& y);
//Solve B*x=y. Both arguments are sparse vectors.
virtual int btSolve(double* x, const double* y);
//Solve B^t*x=y. Components of y should be specified in the same
//order as indices returned by getBasIndices()
virtual int btSolve(double* x, const OsiPackedVectorBase& y);
//Solve B^t*x=y, checks if y has indices that are non-basic.
virtual int btSolve(OsiPackedVector& x, const OsiPackedVectorBase& y);
//Solve B^t*x=y, same requirement on indices in y.
virtual int bInvACol(double* x, int col);
virtual int bInvACol(OsiPackedVector& x, int col);
//Return a column col of B^(-1)*A in x (dense and sparse versions)
virtual int bInvARow(double* x, int row);
virtual int bInvARow(OsiPackedVector& x, int row);
//Return a row row of B^(-1)*A in x (dense and sparse versions)
virtual int bInvCol(double* x, int col);
virtual int bInvCol(OsiPackedVector& x, int col);
//Return a column col of B^(-1) in x (dense and sparse versions)
virtual int bInvRow(double* x, int row);
virtual int bInvRow(OsiPackedVector& x, int row);
//Return a row row of B^(-1) in x (dense and sparse versions)
virtual int primalPivotResult(int colIn, int& colOut, double& t,
OsiPackedVector& dx, OsiPackedVector& dz, double& obj);
//Query on the result of the primal pivot that would use entering
//column colIn.
//Leaving column is returned in colOut, the step size in t, direction
//of the change in the primal vector - in dx, direction of the change
//in the reduced costs - in dz, new objective function value - in obj.
virtual int dualPivotResult(int rowIn, int& rowOut, double& t,
OsiPackedVector& dx, OsiPackedVector& dz, double& obj);
//Query on the result of the dual pivot that would use entering
//row rowIn.
//Leaving row is returned in rowOut, the step size in t, direction
//of the change in the primal vector - in dx, direction of the change
//in the reduced costs - in dz, new objective function value - in obj.
Operations that perform an actual pivot
All of the following return 0 if successful and non-zero error code
otherwise.
virtual int primalPivot(int colIn, int& colOut, double& t,
OsiPackedVector& dx, OsiPackedVector& dz, double& obj);
//Perform the primal pivot that would use entering column colIn.
//Leaving column is returned in colOut, the step size in t, direction
//of the change in the primal vector - in dx, direction of the change
//in the reduced costs - in dz, new objective function value - in obj.
virtual int dualPivot(int colOut, int& colIn, double& t,
OsiPackedVector& dx, OsiPackedVector& dz, double& obj);
//Perform the dual pivot that would a leaving column colOut.
//Entering column is returned in colIn, the step size in t, direction
//of the change in the primal vector - in dx, direction of the change
//in the reduced costs - in dz, new objective function value - in obj.
virtual int pivot(int colIn, int colOut, int statOut);
//Perform a pivot by substituting a colOut for colIn in the basis.
//The status of the leaving variable is given in statOut
//(>0 for a variable leaving at the upper bound, <=0 - at the
//lower bound).
Reduced costs access operations
virtual void getReducedGradient(OsiPackedVector& z) const;
//Query the reduced costs vector with respect to a current objective
//and a basis
virtual void getReducedGradient(OsiPackedVector& z, const double * c);
virtual void getReducedGradient(OsiPackedVector& z, const
OsiPackedVectorBase& c);
//Find the reduced costs vector with respect to a current basis
//and the cost (gradient) vector c.
//These methods should probably not be made const as they may use some
//internal buffers of the solver.
Additional methods for OsiPackedMatrix
In computing Matrix-vector products, it may be necessary to perform
these operations only for a subset of columns (rows). While the use of
OsiPackedVector as an argument
of times() and transposeTimes() methods can partially solve this
problem, we would
like to be able to specify that only a subset of result components is
needed. Thus, we
suggest using an OsiPackedVector\& as a return argument with its index set
specifying
the required components of the product:
void times(const OsiPackedVectorBase& x,
OsiPackedVector& y) const;
//Return A * x in y. Only those components already in y are computed.
void transposeTimes(const OsiPackedVectorBase& x,
OsiPackedVector& y) const;
//Return x * A in y. Only those components already in y are computed.
More information about the Coin-discuss
mailing list