public class DantzigLCPSolver extends java.lang.Object implements LCPSolver
The algorithm implemented here is the simple principal pivoting
method attributed to Dantzig. At the start of each major cycle the most
infeasible variable (the one whose residual is most negative, or for a BLCP
most violates its bound) is selected as the driving variable; a
minimum-ratio test then determines a sequence of single (1x1) principal
pivots that drive it to feasibility while keeping all other variables
feasible. This corresponds to Algorithm 4.2.11 ("Dantzig; van de Panne and
Whinston") in The Linear Complementarity Problem by Cottle, Pang, and
Stone. This implementation generalizes the method to the bounded (BLCP)
case, and maintains an incrementally updated Cholesky factorization of the
basis matrix, which makes it considerably faster than a dense tableau
implementation such as SimpleLCPSolver.
Warm starting is supported and may be enabled with
setWarmStartEnabled(boolean); when enabled, the state argument to the
solve methods is used to seed the initial basis, which can greatly
reduce the number of pivots when a sequence of related problems is solved
with a slowly changing active set.
Note that SimpleLCPSolver implements the same simple
principal pivoting method (for LCPs only), so for nondegenerate SPSD problems
the two classes produce the same sequence of pivots. They would differ only
at zero-diagonal degeneracies: robustly handling those requires the 2x2
block pivots and negative lower-bound device of Keller's general (symmetric)
principal pivoting method (Algorithm 4.3.2 in Cottle, Pang and Stone; E.
Keller, "The general quadratic optimization problem", Mathematical
Programming 5, 1973), neither of which is implemented here or in
SimpleLCPSolver.
The method is also described in Claude Lacoursiere's Ph.D. thesis, Ghosts and Machines: Regularized Variational Methods for Interactive Simulations of Multibodies with Dry Frictional Contact (2007). Be aware, however, that Lacoursiere uses the name "Cottle-Dantzig" for an incremental variant that introduces the variables one at a time in a fixed index order; that is not the method implemented here (which, like Algorithm 4.2.11 above, selects the most infeasible variable from the full set at each cycle).
LCPSolver.Status| Modifier and Type | Field and Description |
|---|---|
static int |
SHOW_ALL |
static int |
SHOW_MIN_RATIO |
static int |
SHOW_NONE |
static int |
SHOW_PIVOTS |
static int |
SHOW_QM |
static int |
SHOW_RETURNS |
static int |
SHOW_VARIABLES |
INF, W_VAR_LOWER, W_VAR_UPPER, Z_VAR| Constructor and Description |
|---|
DantzigLCPSolver()
Creates a new Dantzig solver.
|
| Modifier and Type | Method and Description |
|---|---|
boolean |
getComputeResidual() |
int |
getDebug() |
int |
getIterationCount()
Returns the number of iterations that were used in the most recent
solution operation.
|
int |
getIterationLimit()
Gets the iteration limit for this solver.
|
double |
getLastSolveTol()
Returns the numeric tolerance used to determine complementarity for the
most recent solution.
|
int |
getPivotCount()
Returns the number of pivots that were used in the most recent solution
operation.
|
double |
getResidual() |
boolean |
getSilent() |
double |
getTolerance()
Returns the numeric tolerence for this solver.
|
boolean |
isBLCPSupported()
Queries whether this solver supported the solution of bounded linear
complementarity problems (BLCPs).
|
boolean |
isWarmStartSupported()
Queries whether this solver supports warm starts.
|
int |
numFailedPivots()
Returns the number of pivots that were attempted and rejected because
they would have resulted in a basis matrix that was not SPD.
|
void |
resolve(VectorNd z,
VectorNd q,
int[] state)
Solves the system
|
void |
setComputeResidual(boolean enable) |
void |
setDebug(int code) |
void |
setIterationLimit(int limit)
Sets the iteration limit for this solver.
|
void |
setSilent(boolean code) |
void |
setTolerance(double tol)
Sets the numeric tolerance for this solver.
|
void |
setWarmStartEnabled(boolean enable)
Enables or disables warm starts.
|
LCPSolver.Status |
solve(VectorNd z,
VectorNd w,
VectorNi state,
MatrixNd M,
VectorNd q,
VectorNd lo,
VectorNd hi,
int nub)
If
LCPSolver.isBLCPSupported() returns true, solves the BLCP |
LCPSolver.Status |
solve(VectorNd z,
VectorNi state,
MatrixNd M,
VectorNd q)
Solves the LCP
|
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitclearState, stateToChar, stateToString, stateToString, stateToString, stringToStatepublic static final int SHOW_NONE
public static final int SHOW_PIVOTS
public static final int SHOW_MIN_RATIO
public static final int SHOW_QM
public static final int SHOW_VARIABLES
public static final int SHOW_RETURNS
public static final int SHOW_ALL
public int getDebug()
public void setDebug(int code)
public boolean getSilent()
public void setSilent(boolean code)
public boolean getComputeResidual()
public void setComputeResidual(boolean enable)
public double getResidual()
public double getTolerance()
setTolerance(double)public void setTolerance(double tol)
>= 0, as described in the class documentation. In particular, a
solution will be considered found whenever q' >= -tol.tol - new numeric tolerance. Negative numbers will be truncated to 0.getTolerance()public int getIterationLimit()
public void setIterationLimit(int limit)
limit - new iteration limitpublic int getIterationCount()
getIterationCount in interface LCPSolverpublic int getPivotCount()
getPivotCount in interface LCPSolverpublic double getLastSolveTol()
getLastSolveTol in interface LCPSolverpublic int numFailedPivots()
numFailedPivots in interface LCPSolverpublic LCPSolver.Status solve(VectorNd z, VectorNi state, MatrixNd M, VectorNd q)
w = M z + qwhere M is a matrix whose characteristics should match the capabilities of the solver.
solve in interface LCPSolverz - returns the solution for zstate - optional argument, which if non-null, returns the
state vector resulting from the LCP solve. For solvers capable of warm
starts (i.e., if LCPSolver.isWarmStartSupported() returns true), the
value of this vector on input will also specify the initial starting
state.M - system matrixq - system vectorpublic void resolve(VectorNd z, VectorNd q, int[] state)
w = M z + qusing the same matrix M and active set that was determined in the previous call to solve. Non-active z variables are set to 0.
z - returns the solution for zq - system vectorstate - (optional) if specified, returns which z variables are basic in the
solution.public LCPSolver.Status solve(VectorNd z, VectorNd w, VectorNi state, MatrixNd M, VectorNd q, VectorNd lo, VectorNd hi, int nub)
LCPSolver.isBLCPSupported() returns true, solves the BLCP
w = M z + q = wpos - wneg, 0 ≤ hi - z perp wneg ≥ 0, 0 ≤ z - lo perp wpos ≥ 0,where M is a matrix whose characteristics should match the capabilities of the solver. If BLCPs are not supported, then this method returns
LCPSolver.Status.UNIMPLEMENTED.solve in interface LCPSolverz - returns the solution for zw - returns the solution for wstate - optional argument, which if non-null, returns the
state vector resulting from the LCP solve. For solvers capable of warm
starts (i.e., if LCPSolver.isWarmStartSupported() returns true), the
value of this vector on input will also specify the initial starting
state.M - system matrixq - system vectorlo - lower bounds for the z variableshi - upper bounds for the z variablesnub - number of unbounded variables (corresponding to bilateral constraints).
If nub > 0, then the first nub entries of lo
and hi must be negative and positive infinity, respectively.public boolean isBLCPSupported()
isBLCPSupported in interface LCPSolvertrue if BLCPs are supported.public boolean isWarmStartSupported()
isWarmStartSupported in interface LCPSolvertrue if warm starts are supported.public void setWarmStartEnabled(boolean enable)
solve() methods, when non-null, is used
to supply an initial guess for the LCP solution. Warm starts are
disabled by default. Enabling them causes isWarmStartSupported()
to return true.