AbcSimplexDual Class Reference

This solves LPs using the dual simplex method. More...

#include <AbcSimplexDual.hpp>

Inheritance diagram for AbcSimplexDual:
Inheritance graph
[legend]
Collaboration diagram for AbcSimplexDual:
Collaboration graph
[legend]

List of all members.

Public Member Functions

Description of algorithm



int dual ()
 Dual algorithm.
int strongBranching (int numberVariables, const int *variables, double *newLower, double *newUpper, double **outputSolution, int *outputStatus, int *outputIterations, bool stopOnFirstInfeasible=true, bool alwaysFinish=false, int startFinishOptions=0)
 For strong branching.
AbcSimplexFactorizationsetupForStrongBranching (char *arrays, int numberRows, int numberColumns, bool solveLp=false)
 This does first part of StrongBranching.
void cleanupAfterStrongBranching (AbcSimplexFactorization *factorization)
 This cleans up after strong branching.
Functions used in dual



int whileIteratingSerial ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
void whileIterating2 ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
int whileIteratingParallel (int numberIterations)
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
int whileIterating3 ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
void updatePrimalSolution ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
int noPivotRow ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
int noPivotColumn ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
void dualPivotColumn ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
void createDualPricingVectorSerial ()
 Create dual pricing vector.
int getTableauColumnFlipAndStartReplaceSerial ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
void getTableauColumnPart1Serial ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
void getTableauColumnPart2 ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
int checkReplace ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
void replaceColumnPart3 ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
void checkReplacePart1 ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
void checkReplacePart1a ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
void checkReplacePart1b ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
void updateDualsInDual ()
 The duals are updated.
int flipBounds ()
 The duals are updated by the given arrays.
void flipBack (int number)
 Undo a flip.
void dualColumn1 (bool doAll=false)
 Array has tableau row (row section) Puts candidates for rows in list Returns guess at upper theta (infinite if no pivot) and may set sequenceIn_ if free Can do all (if tableauRow created).
double dualColumn1A ()
 Array has tableau row (row section) Just does slack part Returns guess at upper theta (infinite if no pivot) and may set sequenceIn_ if free.
double dualColumn1B ()
 Do all given tableau row.
void dualColumn2 ()
 Chooses incoming Puts flipped ones in list If necessary will modify costs.
void dualColumn2Most (dualColumnResult &result)
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
void dualColumn2First (dualColumnResult &result)
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
void dualColumn2 (dualColumnResult &result)
 Chooses part of incoming Puts flipped ones in list If necessary will modify costs.
void checkPossibleCleanup (CoinIndexedVector *array)
 This sees what is best thing to do in branch and bound cleanup If sequenceIn_ < 0 then can't do anything.
void dualPivotRow ()
 Chooses dual pivot row Would be faster with separate region to scan and will have this (with square of infeasibility) when steepest For easy problems we can just choose one of the first rows we look at.
int changeBounds (int initialize, double &changeCost)
 Checks if any fake bounds active - if so returns number and modifies updatedDualBound_ and everything.
bool changeBound (int iSequence)
 As changeBounds but just changes new bounds for a single variable.
void originalBound (int iSequence)
 Restores bound to original bound.
int checkUnbounded (CoinIndexedVector &ray, double changeCost)
 Checks if tentative optimal actually means unbounded in dual Returns -3 if not, 2 if is unbounded.
void statusOfProblemInDual (int type)
 Refactorizes if necessary Checks if finished.
int whatNext ()
 Fast iterations.
bool checkCutoff (bool computeObjective)
 see if cutoff reached
int bounceTolerances (int type)
 Does something about fake tolerances.
void perturb (double factor)
 Perturbs problem.
void perturbB (double factor, int type)
 Perturbs problem B.
int makeNonFreeVariablesDualFeasible (bool changeCosts=false)
 Make non free variables dual feasible by moving to a bound.
int fastDual (bool alwaysFinish=false)
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
int numberAtFakeBound ()
 Checks number of variables at fake bounds.
int pivotResultPart1 ()
 Pivot in a variable and choose an outgoing one.
int nextSuperBasic ()
 Get next free , -1 if none.
void startupSolve ()
 Startup part of dual.
void finishSolve ()
 Ending part of dual.
void gutsOfDual ()
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.
int resetFakeBounds (int type)
 This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Detailed Description

This solves LPs using the dual simplex method.

It inherits from AbcSimplex. It has no data of its own and is never created - only cast from a AbcSimplex object at algorithm time.

Definition at line 49 of file AbcSimplexDual.hpp.


Member Function Documentation

int AbcSimplexDual::dual (  ) 

Dual algorithm.

Method

It tries to be a single phase approach with a weight of 1.0 being given to getting optimal and a weight of updatedDualBound_ being given to getting dual feasible. In this version I have used the idea that this weight can be thought of as a fake bound. If the distance between the lower and upper bounds on a variable is less than the feasibility weight then we are always better off flipping to other bound to make dual feasible. If the distance is greater then we make up a fake bound updatedDualBound_ away from one bound. If we end up optimal or primal infeasible, we check to see if bounds okay. If so we have finished, if not we increase updatedDualBound_ and continue (after checking if unbounded). I am undecided about free variables - there is coding but I am not sure about it. At present I put them in basis anyway.

The code is designed to take advantage of sparsity so arrays are seldom zeroed out from scratch or gone over in their entirety. The only exception is a full scan to find outgoing variable for Dantzig row choice. For steepest edge we keep an updated list of infeasibilities (actually squares). On easy problems we don't need full scan - just pick first reasonable.

One problem is how to tackle degeneracy and accuracy. At present I am using the modification of costs which I put in OSL and some of what I think is the dual analog of Gill et al. I am still not sure of the exact details.

The flow of dual is three while loops as follows:

while (not finished) {

while (not clean solution) {

Factorize and/or clean up solution by flipping variables so dual feasible. If looks finished check fake dual bounds. Repeat until status is iterating (-1) or finished (0,1,2)

}

while (status==-1) {

Iterate until no pivot in or out or time to re-factorize.

Flow is:

choose pivot row (outgoing variable). if none then we are primal feasible so looks as if done but we need to break and check bounds etc.

Get pivot row in tableau

Choose incoming column. If we don't find one then we look primal infeasible so break and check bounds etc. (Also the pivot tolerance is larger after any iterations so that may be reason)

If we do find incoming column, we may have to adjust costs to keep going forwards (anti-degeneracy). Check pivot will be stable and if unstable throw away iteration and break to re-factorize. If minor error re-factorize after iteration.

Update everything (this may involve flipping variables to stay dual feasible.

}

}

TODO's (or maybe not)

At present we never check we are going forwards. I overdid that in OSL so will try and make a last resort.

Needs partial scan pivot out option.

May need other anti-degeneracy measures, especially if we try and use loose tolerances as a way to solve in fewer iterations.

I like idea of dynamic scaling. This gives opportunity to decouple different implications of scaling for accuracy, iteration count and feasibility tolerance.

for use of exotic parameter startFinishoptions see Abcsimplex.hpp

Reimplemented from AbcSimplex.

int AbcSimplexDual::strongBranching ( int  numberVariables,
const int *  variables,
double *  newLower,
double *  newUpper,
double **  outputSolution,
int *  outputStatus,
int *  outputIterations,
bool  stopOnFirstInfeasible = true,
bool  alwaysFinish = false,
int  startFinishOptions = 0 
)

For strong branching.

On input lower and upper are new bounds while on output they are change in objective function values (>1.0e50 infeasible). Return code is 0 if nothing interesting, -1 if infeasible both ways and +1 if infeasible one way (check values to see which one(s)) Solutions are filled in as well - even down, odd up - also status and number of iterations

Reimplemented from ClpSimplex.

AbcSimplexFactorization* AbcSimplexDual::setupForStrongBranching ( char *  arrays,
int  numberRows,
int  numberColumns,
bool  solveLp = false 
)

This does first part of StrongBranching.

void AbcSimplexDual::cleanupAfterStrongBranching ( AbcSimplexFactorization factorization  ) 

This cleans up after strong branching.

int AbcSimplexDual::whileIteratingSerial (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

void AbcSimplexDual::whileIterating2 (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

int AbcSimplexDual::whileIteratingParallel ( int  numberIterations  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

int AbcSimplexDual::whileIterating3 (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

void AbcSimplexDual::updatePrimalSolution (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

int AbcSimplexDual::noPivotRow (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

int AbcSimplexDual::noPivotColumn (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

void AbcSimplexDual::dualPivotColumn (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

void AbcSimplexDual::createDualPricingVectorSerial (  ) 

Create dual pricing vector.

int AbcSimplexDual::getTableauColumnFlipAndStartReplaceSerial (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

void AbcSimplexDual::getTableauColumnPart1Serial (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

void AbcSimplexDual::getTableauColumnPart2 (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

int AbcSimplexDual::checkReplace (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

void AbcSimplexDual::replaceColumnPart3 (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

void AbcSimplexDual::checkReplacePart1 (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

void AbcSimplexDual::checkReplacePart1a (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

void AbcSimplexDual::checkReplacePart1b (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

void AbcSimplexDual::updateDualsInDual (  ) 

The duals are updated.

int AbcSimplexDual::flipBounds (  ) 

The duals are updated by the given arrays.

This is in values pass - so no changes to primal is made While dualColumn gets flips this does actual flipping. returns number flipped

void AbcSimplexDual::flipBack ( int  number  ) 

Undo a flip.

void AbcSimplexDual::dualColumn1 ( bool  doAll = false  ) 

Array has tableau row (row section) Puts candidates for rows in list Returns guess at upper theta (infinite if no pivot) and may set sequenceIn_ if free Can do all (if tableauRow created).

double AbcSimplexDual::dualColumn1A (  ) 

Array has tableau row (row section) Just does slack part Returns guess at upper theta (infinite if no pivot) and may set sequenceIn_ if free.

double AbcSimplexDual::dualColumn1B (  ) 

Do all given tableau row.

void AbcSimplexDual::dualColumn2 (  ) 

Chooses incoming Puts flipped ones in list If necessary will modify costs.

void AbcSimplexDual::dualColumn2Most ( dualColumnResult result  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

void AbcSimplexDual::dualColumn2First ( dualColumnResult result  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

void AbcSimplexDual::dualColumn2 ( dualColumnResult result  ) 

Chooses part of incoming Puts flipped ones in list If necessary will modify costs.

void AbcSimplexDual::checkPossibleCleanup ( CoinIndexedVector array  ) 

This sees what is best thing to do in branch and bound cleanup If sequenceIn_ < 0 then can't do anything.

void AbcSimplexDual::dualPivotRow (  ) 

Chooses dual pivot row Would be faster with separate region to scan and will have this (with square of infeasibility) when steepest For easy problems we can just choose one of the first rows we look at.

int AbcSimplexDual::changeBounds ( int  initialize,
double &  changeCost 
)

Checks if any fake bounds active - if so returns number and modifies updatedDualBound_ and everything.

Free variables will be left as free Returns number of bounds changed if >=0 Returns -1 if not initialize and no effect fills cost of change vector

bool AbcSimplexDual::changeBound ( int  iSequence  ) 

As changeBounds but just changes new bounds for a single variable.

Returns true if change

void AbcSimplexDual::originalBound ( int  iSequence  ) 

Restores bound to original bound.

int AbcSimplexDual::checkUnbounded ( CoinIndexedVector ray,
double  changeCost 
)

Checks if tentative optimal actually means unbounded in dual Returns -3 if not, 2 if is unbounded.

void AbcSimplexDual::statusOfProblemInDual ( int  type  ) 

Refactorizes if necessary Checks if finished.

Updates status. lastCleaned refers to iteration at which some objective/feasibility cleaning too place.

type - 0 initial so set up save arrays etc

  • 1 normal -if good update save
  • 2 restoring from saved
int AbcSimplexDual::whatNext (  ) 

Fast iterations.

Misses out a lot of initialization. Normally stops on maximum iterations, first re-factorization or tentative optimum. If looks interesting then continues as normal. Returns 0 if finished properly, 1 otherwise. Gets tableau column - does flips and checks what to do next Knows tableau column in 1, flips in 2 and gets an array for flips (as serial here)

bool AbcSimplexDual::checkCutoff ( bool  computeObjective  ) 

see if cutoff reached

int AbcSimplexDual::bounceTolerances ( int  type  ) 

Does something about fake tolerances.

void AbcSimplexDual::perturb ( double  factor  ) 

Perturbs problem.

void AbcSimplexDual::perturbB ( double  factor,
int  type 
)

Perturbs problem B.

int AbcSimplexDual::makeNonFreeVariablesDualFeasible ( bool  changeCosts = false  ) 

Make non free variables dual feasible by moving to a bound.

int AbcSimplexDual::fastDual ( bool  alwaysFinish = false  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

int AbcSimplexDual::numberAtFakeBound (  ) 

Checks number of variables at fake bounds.

This is used by fastDual so can exit gracefully before end

int AbcSimplexDual::pivotResultPart1 (  ) 

Pivot in a variable and choose an outgoing one.

Assumes dual feasible - will not go through a reduced cost. Returns step length in theta Return codes as before but -1 means no acceptable pivot

int AbcSimplexDual::nextSuperBasic (  ) 

Get next free , -1 if none.

void AbcSimplexDual::startupSolve (  ) 

Startup part of dual.

void AbcSimplexDual::finishSolve (  ) 

Ending part of dual.

void AbcSimplexDual::gutsOfDual (  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)

int AbcSimplexDual::resetFakeBounds ( int  type  ) 

This has the flow between re-factorizations Broken out for clarity and will be used by strong branching.

Reasons to come out: -1 iterations etc -2 inaccuracy -3 slight inaccuracy (and done iterations) +0 looks optimal (might be unbounded - but we will investigate) +1 looks infeasible +3 max iterations

If givenPi not NULL then in values pass (copy from ClpSimplexDual)


The documentation for this class was generated from the following file:

Generated on 5 Apr 2015 by  doxygen 1.6.1