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

ClpSimplex Class Reference

#include <ClpSimplex.hpp>

Inheritance diagram for ClpSimplex:

ClpModel ClpSimplexDual ClpSimplexPrimal ClpSimplexPrimalQuadratic List of all members.

Public Types

enum  Status {
  isFree = 0x00, basic = 0x01, atUpperBound = 0x02, atLowerBound = 0x03,
  superBasic = 0x04, isFixed = 0x05
}
enum  FakeBound { noFake = 0x00, bothFake = 0x01, upperFake = 0x02, lowerFake = 0x03 }

Public Member Functions

Constructors and destructor and copy
 ClpSimplex ()
 Default constructor.

 ClpSimplex (const ClpSimplex &)
 Copy constructor.

 ClpSimplex (const ClpModel &)
 Copy constructor from model.

 ClpSimplex (const ClpModel *wholeModel, int numberRows, const int *whichRows, int numberColumns, const int *whichColumns, bool dropNames=true, bool dropIntegers=true)
 ClpSimplex (ClpSimplex *wholeModel, int numberColumns, const int *whichColumns)
void originalModel (ClpSimplex *miniModel)
ClpSimplexoperator= (const ClpSimplex &rhs)
 Assignment operator. This copies the data.

 ~ClpSimplex ()
 Destructor.

void loadProblem (const ClpMatrixBase &matrix, const double *collb, const double *colub, const double *obj, const double *rowlb, const double *rowub, const double *rowObjective=NULL)
void loadProblem (const CoinPackedMatrix &matrix, const double *collb, const double *colub, const double *obj, const double *rowlb, const double *rowub, const double *rowObjective=NULL)
void loadProblem (const int numcols, const int numrows, const CoinBigIndex *start, const int *index, const double *value, const double *collb, const double *colub, const double *obj, const double *rowlb, const double *rowub, const double *rowObjective=NULL)
void loadProblem (const int numcols, const int numrows, const CoinBigIndex *start, const int *index, const double *value, const int *length, const double *collb, const double *colub, const double *obj, const double *rowlb, const double *rowub, const double *rowObjective=NULL)
 This one is for after presolve to save memory.

int readMps (const char *filename, bool keepNames=false, bool ignoreErrors=false)
 Read an mps file from the given filename.

void borrowModel (ClpModel &otherModel)
Functions most useful to user
int initialSolve (ClpSolve &options)
int initialSolve ()
 Default initial solve.

int initialDualSolve ()
 Dual initial solve.

int initialPrimalSolve ()
 Primal initial solve.

int dual (int ifValuesPass=0)
int primal (int ifValuesPass=0)
int quadraticSLP (int numberPasses, double deltaTolerance)
int quadraticPrimal (int phase=2)
 Solves quadratic using Dantzig's algorithm - primal.

void setFactorization (ClpFactorization &factorization)
 Passes in factorization.

void scaling (int mode=1)
 Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later).

int scalingFlag () const
 Gets scalingFlag.

int tightenPrimalBounds (double factor=0.0)
int crash (double gap, int pivot)
void setDualRowPivotAlgorithm (ClpDualRowPivot &choice)
 Sets row pivot choice algorithm in dual.

void setPrimalColumnPivotAlgorithm (ClpPrimalColumnPivot &choice)
 Sets column pivot choice algorithm in primal.

int strongBranching (int numberVariables, const int *variables, double *newLower, double *newUpper, double **outputSolution, int *outputStatus, int *outputIterations, bool stopOnFirstInfeasible=true, bool alwaysFinish=false)
Needed for functionality of OsiSimplexInterface
int pivot ()
int primalPivotResult ()
int dualPivotResult ()
int startup (int ifValuesPass)
void finish ()
bool statusOfProblem ()
most useful gets and sets
bool primalFeasible () const
 If problem is primal feasible.

bool dualFeasible () const
 If problem is dual feasible.

ClpFactorization * factorization () const
 factorization

bool sparseFactorization () const
 Sparsity on or off.

void setSparseFactorization (bool value)
int factorizationFrequency () const
 Factorization frequency.

void setFactorizationFrequency (int value)
double dualBound () const
 Dual bound.

void setDualBound (double value)
double infeasibilityCost () const
 Infeasibility cost.

void setInfeasibilityCost (double value)
int perturbation () const
void setPerturbation (int value)
int algorithm () const
 Current (or last) algorithm.

void setAlgorithm (int value)
 Set algorithm.

double sumDualInfeasibilities () const
 Sum of dual infeasibilities.

int numberDualInfeasibilities () const
 Number of dual infeasibilities.

double sumPrimalInfeasibilities () const
 Sum of primal infeasibilities.

void setSumPrimalInfeasibilities (double value)
int numberPrimalInfeasibilities () const
 Number of primal infeasibilities.

int saveModel (const char *fileName)
int restoreModel (const char *fileName)
void checkSolution ()
CoinIndexedVectorrowArray (int index) const
 Useful row length arrays (0,1,2,3,4,5).

CoinIndexedVectorcolumnArray (int index) const
 Useful column length arrays (0,1,2,3,4,5).

Functions less likely to be useful to casual user
int getSolution (const double *rowActivities, const double *columnActivities)
int getSolution ()
int createPiecewiseLinearCosts (const int *starts, const double *lower, const double *gradient)
void returnModel (ClpSimplex &otherModel)
ClpDataSave saveData ()
 Save data.

void restoreData (ClpDataSave saved)
 Restore data.

int internalFactorize (int solveType)
void cleanStatus ()
 Clean up status.

int factorize ()
 Factorizes using current basis. For external use.

void computeDuals (double *givenDjs)
void computePrimals (const double *rowActivities, const double *columnActivities)
 Computes primals from scratch.

void unpack (CoinIndexedVector *rowArray) const
void unpack (CoinIndexedVector *rowArray, int sequence) const
void unpackPacked (CoinIndexedVector *rowArray)
void unpackPacked (CoinIndexedVector *rowArray, int sequence)
int housekeeping (double objectiveChange)
void checkPrimalSolution (const double *rowActivities=NULL, const double *columnActivies=NULL)
void checkDualSolution ()
void setValuesPassAction (float incomingInfeasibility, float allowedInfeasibility)
Matrix times vector methods
They can be faster if scalar is +- 1 These are covers so user need not worry about scaling Also for simplex I am not using basic/non-basic split

void times (double scalar, const double *x, double *y) const
void transposeTimes (double scalar, const double *x, double *y) const
most useful gets and sets
double columnPrimalInfeasibility () const
 Worst column primal infeasibility.

int columnPrimalSequence () const
 Sequence of worst (-1 if feasible).

double rowPrimalInfeasibility () const
 Worst row primal infeasibility.

int rowPrimalSequence () const
 Sequence of worst (-1 if feasible).

double columnDualInfeasibility () const
int columnDualSequence () const
 Sequence of worst (-1 if feasible).

double rowDualInfeasibility () const
 Worst row dual infeasibility.

int rowDualSequence () const
 Sequence of worst (-1 if feasible).

double primalToleranceToGetOptimal () const
 Primal tolerance needed to make dual feasible (<largeTolerance).

double remainingDualInfeasibility () const
 Remaining largest dual infeasibility.

double largeValue () const
 Large bound value (for complementarity etc).

void setLargeValue (double value)
double largestPrimalError () const
 Largest error on Ax-b.

double largestDualError () const
 Largest error on basic duals.

double largestSolutionError () const
 Largest difference between input primal solution and computed.

int * pivotVariable () const
 Basic variables pivoting on which rows.

double objectiveScale () const
 Scaling of objective 12345.0 (auto), 0.0 (off), other user.

void setObjectiveScale (double value)
double currentDualTolerance () const
 Current dual tolerance.

void setCurrentDualTolerance (double value)
double currentPrimalTolerance () const
 Current primal tolerance.

void setCurrentPrimalTolerance (double value)
int numberRefinements () const
 How many iterative refinements to do.

void setNumberRefinements (int value)
double alpha () const
 Alpha (pivot element) for use by classes e.g. steepestedge.

double dualIn () const
 Reduced cost of last incoming for use by classes e.g. steepestedge.

int pivotRow () const
 Pivot Row for use by classes e.g. steepestedge.

double valueIncomingDual () const
 value of incoming variable (in Dual)

public methods
double * solutionRegion (int section)
double * djRegion (int section)
double * lowerRegion (int section)
double * upperRegion (int section)
double * costRegion (int section)
double * solutionRegion ()
 Return region as single array.

double * djRegion ()
double * lowerRegion ()
double * upperRegion ()
double * costRegion ()
Status getStatus (int sequence) const
void setStatus (int sequence, Status status)
void setInitialDenseFactorization (bool onOff)
bool initialDenseFactorization () const
int sequenceIn () const
int sequenceOut () const
void setSequenceIn (int sequence)
void setSequenceOut (int sequence)
int directionIn () const
int directionOut () const
void setDirectionIn (int direction)
void setDirectionOut (int direction)
int isColumn (int sequence) const
 Returns 1 if sequence indicates column.

int sequenceWithin (int sequence) const
 Returns sequence number within section.

double solution (int sequence)
 Return row or column values.

double & solutionAddress (int sequence)
 Return address of row or column values.

double reducedCost (int sequence)
double & reducedCostAddress (int sequence)
double lower (int sequence)
double & lowerAddress (int sequence)
 Return address of row or column lower bound.

double upper (int sequence)
double & upperAddress (int sequence)
 Return address of row or column upper bound.

double cost (int sequence)
double & costAddress (int sequence)
 Return address of row or column cost.

double originalLower (int iSequence) const
 Return original lower bound.

double originalUpper (int iSequence) const
 Return original lower bound.

double theta () const
 Theta (pivot change).

const double * rowScale () const
 Scaling.

const double * columnScale () const
void setRowScale (double *scale)
void setColumnScale (double *scale)
ClpNonLinearCostnonLinearCost () const
 Return pointer to details of costs.

status methods
void setFakeBound (int sequence, FakeBound fakeBound)
FakeBound getFakeBound (int sequence) const
void setRowStatus (int sequence, Status status)
Status getRowStatus (int sequence) const
void setColumnStatus (int sequence, Status status)
Status getColumnStatus (int sequence) const
void setPivoted (int sequence)
void clearPivoted (int sequence)
bool pivoted (int sequence) const
void setFlagged (int sequence)
 To flag a variable.

void clearFlagged (int sequence)
bool flagged (int sequence) const
void setActive (int iRow)
 To say row active in primal pivot row choice.

void clearActive (int iRow)
bool active (int iRow) const
void createStatus ()
void allSlackBasis ()
int lastBadIteration () const
 So we know when to be cautious.

int progressFlag () const
 Progress flag - at present 0 bit says artificials out.

void forceFactorization (int value)
 Force re-factorization early.

double rawObjectiveValue () const
 Raw objective value (so always minimize in primal).


Protected Member Functions

protected methods
int gutsOfSolution (double *givenDuals, const double *givenPrimals, bool valuesPass=false)
void gutsOfDelete (int type)
 Does most of deletion (0 = all, 1 = most, 2 most + factorization).

void gutsOfCopy (const ClpSimplex &rhs)
 Does most of copying.

bool createRim (int what, bool makeRowCopy=false)
void deleteRim (int getRidOfFactorizationData=2)
bool sanityCheck ()
 Sanity check on input rim data (after scaling) - returns true if okay.


Protected Attributes

data. Many arrays have a row part and a column part.
There is a single array with both - columns then rows and then normally two arrays pointing to rows and columns. The single array is the owner of memory

double columnPrimalInfeasibility_
 Worst column primal infeasibility.

double rowPrimalInfeasibility_
 Worst row primal infeasibility.

int columnPrimalSequence_
 Sequence of worst (-1 if feasible).

int rowPrimalSequence_
 Sequence of worst (-1 if feasible).

double columnDualInfeasibility_
 Worst column dual infeasibility.

double rowDualInfeasibility_
 Worst row dual infeasibility.

int columnDualSequence_
 Sequence of worst (-1 if feasible).

int rowDualSequence_
 Sequence of worst (-1 if feasible).

double primalToleranceToGetOptimal_
 Primal tolerance needed to make dual feasible (<largeTolerance).

double remainingDualInfeasibility_
 Remaining largest dual infeasibility.

double largeValue_
 Large bound value (for complementarity etc).

double objectiveScale_
 Scaling of objective.

double largestPrimalError_
 Largest error on Ax-b.

double largestDualError_
 Largest error on basic duals.

double largestSolutionError_
 Largest difference between input primal solution and computed.

double dualBound_
 Dual bound.

double alpha_
 Alpha (pivot element).

double theta_
 Theta (pivot change).

double lowerIn_
 Lower Bound on In variable.

double valueIn_
 Value of In variable.

double upperIn_
 Upper Bound on In variable.

double dualIn_
 Reduced cost of In variable.

double lowerOut_
 Lower Bound on Out variable.

double valueOut_
 Value of Out variable.

double upperOut_
 Upper Bound on Out variable.

double dualOut_
 Infeasibility (dual) or ? (primal) of Out variable.

double dualTolerance_
 Current dual tolerance for algorithm.

double primalTolerance_
 Current primal tolerance for algorithm.

double sumDualInfeasibilities_
 Sum of dual infeasibilities.

double sumPrimalInfeasibilities_
 Sum of primal infeasibilities.

double infeasibilityCost_
 Weight assigned to being infeasible in primal.

double sumOfRelaxedDualInfeasibilities_
 Sum of Dual infeasibilities using tolerance based on error in duals.

double sumOfRelaxedPrimalInfeasibilities_
 Sum of Primal infeasibilities using tolerance based on error in primals.

double * lower_
 Working copy of lower bounds (Owner of arrays below).

double * rowLowerWork_
 Row lower bounds - working copy.

double * columnLowerWork_
 Column lower bounds - working copy.

double * upper_
 Working copy of upper bounds (Owner of arrays below).

double * rowUpperWork_
 Row upper bounds - working copy.

double * columnUpperWork_
 Column upper bounds - working copy.

double * cost_
 Working copy of objective (Owner of arrays below).

double * rowObjectiveWork_
 Row objective - working copy.

double * objectiveWork_
 Column objective - working copy.

CoinIndexedVectorrowArray_ [6]
 Useful row length arrays.

CoinIndexedVectorcolumnArray_ [6]
 Useful column length arrays.

int sequenceIn_
 Sequence of In variable.

int directionIn_
 Direction of In, 1 going up, -1 going down, 0 not a clude.

int sequenceOut_
 Sequence of Out variable.

int directionOut_
 Direction of Out, 1 to upper bound, -1 to lower bound, 0 - superbasic.

int pivotRow_
 Pivot Row.

int lastGoodIteration_
 Last good iteration (immediately after a re-factorization).

double * dj_
 Working copy of reduced costs (Owner of arrays below).

double * rowReducedCost_
 Reduced costs of slacks not same as duals (or - duals).

double * reducedCostWork_
 Possible scaled reduced costs.

double * solution_
 Working copy of primal solution (Owner of arrays below).

double * rowActivityWork_
 Row activities - working copy.

double * columnActivityWork_
 Column activities - working copy.

int numberDualInfeasibilities_
 Number of dual infeasibilities.

int numberDualInfeasibilitiesWithoutFree_
 Number of dual infeasibilities (without free).

int numberPrimalInfeasibilities_
 Number of primal infeasibilities.

int numberRefinements_
 How many iterative refinements to do.

ClpDualRowPivotdualRowPivot_
 dual row pivot choice

ClpPrimalColumnPivotprimalColumnPivot_
 primal column pivot choice

int * pivotVariable_
 Basic variables pivoting on which rows.

ClpFactorization * factorization_
 factorization

double * rowScale_
 Row scale factors for matrix.

double * savedSolution_
 Saved version of solution.

double * columnScale_
 Column scale factors.

int scalingFlag_
 Scale flag, 0 none, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic.

int numberTimesOptimal_
 Number of times code has tentatively thought optimal.

int changeMade_
 If change has been made (first attempt at stopping looping).

int algorithm_
 Algorithm >0 == Primal, <0 == Dual.

int forceFactorization_
int perturbation_
unsigned char * saveStatus_
 Saved status regions.

ClpNonLinearCostnonLinearCost_
unsigned int specialOptions_
int lastBadIteration_
 So we know when to be cautious.

int numberFake_
 Can be used for count of fake bounds (dual) or fake costs (primal).

int progressFlag_
 Progress flag - at present 0 bit says artificials out, 1 free in.

int firstFree_
 First free/super-basic variable (-1 if none).

float incomingInfeasibility_
float allowedInfeasibility_
ClpSimplexProgressprogress_
 For dealing with all issues of cycling etc.


Friends

void ClpSimplexUnitTest (const std::string &mpsDir, const std::string &netlibDir)

Detailed Description

This solves LPs using the simplex method

It inherits from ClpModel and all its arrays are created at algorithm time. Originally I tried to work with model arrays but for simplicity of coding I changed to single arrays with structural variables then row variables. Some coding is still based on old style and needs cleaning up.

For a description of algorithms:

for dual see ClpSimplexDual.hpp and at top of ClpSimplexDual.cpp for primal see ClpSimplexPrimal.hpp and at top of ClpSimplexPrimal.cpp

There is an algorithm data member. + for primal variations and - for dual variations

This file also includes (at end) a very simple class ClpSimplexProgress which is where anti-looping stuff should migrate to

Definition at line 46 of file ClpSimplex.hpp.


Member Enumeration Documentation

enum ClpSimplex::Status
 

enums for status of various sorts. First 4 match CoinWarmStartBasis, isFixed means fixed at lower bound and out of basis

Definition at line 55 of file ClpSimplex.hpp.

00055               {
00056     isFree = 0x00,
00057     basic = 0x01,
00058     atUpperBound = 0x02,
00059     atLowerBound = 0x03,
00060     superBasic = 0x04,
00061     isFixed = 0x05
00062   };


Constructor & Destructor Documentation

ClpSimplex::ClpSimplex const ClpModel wholeModel,
int  numberRows,
const int *  whichRows,
int  numberColumns,
const int *  whichColumns,
bool  dropNames = true,
bool  dropIntegers = true
 

Subproblem constructor. A subset of whole model is created from the row and column lists given. The new order is given by list order and duplicates are allowed. Name and integer information can be dropped

Definition at line 130 of file ClpSimplex.cpp.

References columnArray_, dualRowPivot_, factorization_, primalColumnPivot_, rowArray_, and saveStatus_.

00134   : ClpModel(rhs, numberRows, whichRow,
00135              numberColumns,whichColumn,dropNames,dropIntegers),
00136   columnPrimalInfeasibility_(0.0),
00137   rowPrimalInfeasibility_(0.0),
00138   columnPrimalSequence_(-2),
00139   rowPrimalSequence_(-2), 
00140   columnDualInfeasibility_(0.0),
00141   rowDualInfeasibility_(0.0),
00142   columnDualSequence_(-2),
00143   rowDualSequence_(-2),
00144   primalToleranceToGetOptimal_(-1.0),
00145   remainingDualInfeasibility_(0.0),
00146   largeValue_(1.0e15),
00147   largestPrimalError_(0.0),
00148   largestDualError_(0.0),
00149   largestSolutionError_(0.0),
00150   dualBound_(1.0e10),
00151   alpha_(0.0),
00152   theta_(0.0),
00153   lowerIn_(0.0),
00154   valueIn_(0.0),
00155   upperIn_(0.0),
00156   dualIn_(0.0),
00157   lowerOut_(-1),
00158   valueOut_(-1),
00159   upperOut_(-1),
00160   dualOut_(-1),
00161   dualTolerance_(0.0),
00162   primalTolerance_(0.0),
00163   sumDualInfeasibilities_(0.0),
00164   sumPrimalInfeasibilities_(0.0),
00165   infeasibilityCost_(1.0e10),
00166   sumOfRelaxedDualInfeasibilities_(0.0),
00167   sumOfRelaxedPrimalInfeasibilities_(0.0),
00168   lower_(NULL),
00169   rowLowerWork_(NULL),
00170   columnLowerWork_(NULL),
00171   upper_(NULL),
00172   rowUpperWork_(NULL),
00173   columnUpperWork_(NULL),
00174   cost_(NULL),
00175   rowObjectiveWork_(NULL),
00176   objectiveWork_(NULL),
00177   sequenceIn_(-1),
00178   directionIn_(-1),
00179   sequenceOut_(-1),
00180   directionOut_(-1),
00181   pivotRow_(-1),
00182   lastGoodIteration_(-100),
00183   dj_(NULL),
00184   rowReducedCost_(NULL),
00185   reducedCostWork_(NULL),
00186   solution_(NULL),
00187   rowActivityWork_(NULL),
00188   columnActivityWork_(NULL),
00189   numberDualInfeasibilities_(0),
00190   numberDualInfeasibilitiesWithoutFree_(0),
00191   numberPrimalInfeasibilities_(100),
00192   numberRefinements_(0),
00193   pivotVariable_(NULL),
00194   factorization_(NULL),
00195   rowScale_(NULL),
00196   savedSolution_(NULL),
00197   columnScale_(NULL),
00198   scalingFlag_(3),
00199   numberTimesOptimal_(0),
00200   changeMade_(1),
00201   algorithm_(0),
00202   forceFactorization_(-1),
00203   perturbation_(100),
00204   nonLinearCost_(NULL),
00205   specialOptions_(0),
00206   lastBadIteration_(-999999),
00207   numberFake_(0),
00208   progressFlag_(0),
00209   firstFree_(-1),
00210   incomingInfeasibility_(1.0),
00211   allowedInfeasibility_(10.0),
00212   progress_(NULL)
00213 {
00214   int i;
00215   for (i=0;i<6;i++) {
00216     rowArray_[i]=NULL;
00217     columnArray_[i]=NULL;
00218   }
00219   saveStatus_=NULL;
00220   // get an empty factorization so we can set tolerances etc
00221   factorization_ = new ClpFactorization();
00222   // say Steepest pricing
00223   dualRowPivot_ = new ClpDualRowSteepest();
00224   // say Steepest pricing
00225   primalColumnPivot_ = new ClpPrimalColumnSteepest();
00226   solveType_=1; // say simplex based life form
00227   
00228 }

ClpSimplex::ClpSimplex ClpSimplex wholeModel,
int  numberColumns,
const int *  whichColumns
 

This constructor modifies original ClpSimplex and stores original stuff in created ClpSimplex. It is only to be used in conjunction with originalModel

Definition at line 4944 of file ClpSimplex.cpp.

References ClpNonLinearCost::checkInfeasibilities(), columnActivityWork_, columnLowerWork_, columnScale_, columnUpperWork_, cost_, createRim(), dj_, ClpModel::getDblParam(), getStatus(), lower_, ClpModel::matrix_, nonLinearCost_, ClpModel::numberColumns_, ClpNonLinearCost::numberInfeasibilities(), ClpModel::numberRows_, objectiveWork_, pivotVariable_, primalColumnPivot_, reducedCostWork_, rowActivityWork_, ClpModel::rowCopy_, rowLowerWork_, rowObjectiveWork_, rowReducedCost_, rowScale_, rowUpperWork_, savedSolution_, saveStatus_, ClpPrimalColumnPivot::saveWeights(), ClpModel::setDblParam(), solution_, ClpModel::status_, ClpMatrixBase::subsetClone(), ClpNonLinearCost::sumInfeasibilities(), ClpMatrixBase::times(), and upper_.

04946 {
04947 
04948   // Set up dummy row selection list
04949   numberRows_ = wholeModel->numberRows_;
04950   int * whichRow = new int [numberRows_];
04951   int iRow;
04952   for (iRow=0;iRow<numberRows_;iRow++)
04953     whichRow[iRow]=iRow;
04954   // ClpModel stuff (apart from numberColumns_)
04955   matrix_ = wholeModel->matrix_;
04956   rowCopy_ = wholeModel->rowCopy_;
04957   if (wholeModel->rowCopy_) {
04958     // note reversal of order
04959     wholeModel->rowCopy_ = wholeModel->rowCopy_->subsetClone(numberRows_,whichRow,
04960                                                              numberColumns,whichColumns);
04961   } else {
04962     wholeModel->rowCopy_=NULL;
04963   }
04964   assert (wholeModel->matrix_);
04965   wholeModel->matrix_ = wholeModel->matrix_->subsetClone(numberRows_,whichRow,
04966                                         numberColumns,whichColumns);
04967   delete [] whichRow;
04968   numberColumns_ = wholeModel->numberColumns_;
04969   // Now ClpSimplex stuff and status_
04970   ClpPrimalColumnSteepest * steep =
04971     dynamic_cast< ClpPrimalColumnSteepest*>(wholeModel->primalColumnPivot_);
04972 #ifdef NDEBUG
04973   if (!steep)
04974     abort();
04975 #else
04976   assert (steep);
04977 #endif
04978   delete  wholeModel->primalColumnPivot_;
04979   wholeModel->primalColumnPivot_ = new ClpPrimalColumnSteepest(0);
04980   nonLinearCost_ = wholeModel->nonLinearCost_;
04981 
04982   // Now main arrays
04983   int iColumn;
04984   int numberTotal = numberRows_+numberColumns;
04985   printf("%d %d %d\n",numberTotal,numberRows_,numberColumns);
04986   // mapping 
04987   int * mapping = new int[numberRows_+numberColumns_];
04988   for (iColumn=0;iColumn<numberColumns_;iColumn++) 
04989     mapping[iColumn]=-1;
04990   for (iRow=0;iRow<numberRows_;iRow++) 
04991     mapping[iRow+numberColumns_] = iRow+numberColumns;
04992   // Redo costs and bounds of whole model
04993   wholeModel->createRim(5,false);
04994   lower_ = wholeModel->lower_;
04995   wholeModel->lower_ = new double [numberTotal];
04996   memcpy(wholeModel->lower_+numberColumns,lower_+numberColumns_,numberRows_*sizeof(double));
04997   for (iColumn=0;iColumn<numberColumns;iColumn++) {
04998     int jColumn = whichColumns[iColumn];
04999     wholeModel->lower_[iColumn]=lower_[jColumn];
05000     // and pointer back 
05001     mapping[jColumn]=iColumn;
05002   }
05003 #ifdef CLP_DEBUG
05004   for (iColumn=0;iColumn<numberRows_+numberColumns_;iColumn++) 
05005     printf("mapx %d %d\n",iColumn,mapping[iColumn]);
05006 #endif
05007   // Re-define pivotVariable_
05008   for (iRow=0;iRow<numberRows_;iRow++) {
05009     int iPivot = wholeModel->pivotVariable_[iRow];
05010     wholeModel->pivotVariable_[iRow]=mapping[iPivot];
05011 #ifdef CLP_DEBUG
05012     printf("p row %d, pivot %d -> %d\n",iRow,iPivot,mapping[iPivot]);
05013 #endif
05014     assert (wholeModel->pivotVariable_[iRow]>=0);
05015   }
05016   // Reverse mapping (so extended version of whichColumns)
05017   for (iColumn=0;iColumn<numberColumns;iColumn++) 
05018     mapping[iColumn]=whichColumns[iColumn];
05019   for (;iColumn<numberRows_+numberColumns;iColumn++) 
05020     mapping[iColumn] = iColumn + (numberColumns_-numberColumns);
05021 #ifdef CLP_DEBUG
05022   for (iColumn=0;iColumn<numberRows_+numberColumns;iColumn++) 
05023     printf("map %d %d\n",iColumn,mapping[iColumn]);
05024 #endif
05025   // Save mapping somewhere - doesn't matter
05026   rowUpper_ = (double *) mapping;
05027   upper_ = wholeModel->upper_;
05028   wholeModel->upper_ = new double [numberTotal];
05029   for (iColumn=0;iColumn<numberTotal;iColumn++) {
05030     int jColumn = mapping[iColumn];
05031     wholeModel->upper_[iColumn]=upper_[jColumn];
05032   }
05033   cost_ = wholeModel->cost_;
05034   wholeModel->cost_ = new double [numberTotal];
05035   for (iColumn=0;iColumn<numberTotal;iColumn++) {
05036     int jColumn = mapping[iColumn];
05037     wholeModel->cost_[iColumn]=cost_[jColumn];
05038   }
05039   dj_ = wholeModel->dj_;
05040   wholeModel->dj_ = new double [numberTotal];
05041   for (iColumn=0;iColumn<numberTotal;iColumn++) {
05042     int jColumn = mapping[iColumn];
05043     wholeModel->dj_[iColumn]=dj_[jColumn];
05044   }
05045   solution_ = wholeModel->solution_;
05046   wholeModel->solution_ = new double [numberTotal];
05047   for (iColumn=0;iColumn<numberTotal;iColumn++) {
05048     int jColumn = mapping[iColumn];
05049     wholeModel->solution_[iColumn]=solution_[jColumn];
05050   }
05051   // now see what variables left out do to row solution
05052   double * rowSolution = wholeModel->solution_+numberColumns;
05053   double * fullSolution = solution_;
05054   double * sumFixed = new double[numberRows_];
05055   memset (sumFixed,0,numberRows_*sizeof(double));
05056   // zero out ones in small problem
05057   for (iColumn=0;iColumn<numberColumns;iColumn++) {
05058     int jColumn = mapping[iColumn];
05059     fullSolution[jColumn]=0.0;
05060   }
05061   // Get objective offset
05062   double originalOffset;
05063   wholeModel->getDblParam(ClpObjOffset,originalOffset);
05064   double offset=0.0;
05065   const double * cost = cost_;
05066   for (iColumn=0;iColumn<numberColumns_;iColumn++) 
05067     offset += fullSolution[iColumn]*cost[iColumn];
05068   wholeModel->setDblParam(ClpObjOffset,originalOffset-offset);
05069   setDblParam(ClpObjOffset,originalOffset);
05070   matrix_->times(1.0,fullSolution,sumFixed,wholeModel->rowScale_,wholeModel->columnScale_);
05071       
05072   double * lower = lower_+numberColumns;
05073   double * upper = upper_+numberColumns;
05074   double fixed=0.0;
05075   for (iRow=0;iRow<numberRows_;iRow++) {
05076     fixed += fabs(sumFixed[iRow]);
05077     if (lower[iRow]>-1.0e50) 
05078       lower[iRow] -= sumFixed[iRow];
05079     if (upper[iRow]<1.0e50)
05080       upper[iRow] -= sumFixed[iRow];
05081     rowSolution[iRow] -= sumFixed[iRow];
05082   }
05083   printf("offset %g sumfixed %g\n",offset,fixed);
05084   delete [] sumFixed;
05085   columnScale_ = wholeModel->columnScale_;
05086   if (columnScale_) {
05087     wholeModel->columnScale_ = new double [numberTotal];
05088     for (iColumn=0;iColumn<numberColumns;iColumn++) {
05089       int jColumn = mapping[iColumn];
05090       wholeModel->columnScale_[iColumn]=columnScale_[jColumn];
05091     }
05092   }
05093   status_ = wholeModel->status_;
05094   wholeModel->status_ = new unsigned char [numberTotal];
05095   for (iColumn=0;iColumn<numberTotal;iColumn++) {
05096     int jColumn = mapping[iColumn];
05097     wholeModel->status_[iColumn]=status_[jColumn];
05098   }
05099   savedSolution_ = wholeModel->savedSolution_;
05100   if (savedSolution_) {
05101     wholeModel->savedSolution_ = new double [numberTotal];
05102     for (iColumn=0;iColumn<numberTotal;iColumn++) {
05103       int jColumn = mapping[iColumn];
05104       wholeModel->savedSolution_[iColumn]=savedSolution_[jColumn];
05105     }
05106   }
05107   saveStatus_ = wholeModel->saveStatus_;
05108   if (saveStatus_) {
05109     wholeModel->saveStatus_ = new unsigned char [numberTotal];
05110     for (iColumn=0;iColumn<numberTotal;iColumn++) {
05111       int jColumn = mapping[iColumn];
05112       wholeModel->saveStatus_[iColumn]=saveStatus_[jColumn];
05113     }
05114   }
05115   
05116   wholeModel->numberColumns_ = numberColumns;
05117   // Initialize weights
05118   wholeModel->primalColumnPivot_->saveWeights(wholeModel,2);
05119   // Costs
05120   wholeModel->nonLinearCost_ = new ClpNonLinearCost(wholeModel);
05121   wholeModel->nonLinearCost_->checkInfeasibilities();
05122   printf("after contraction %d infeasibilities summing to %g\n",
05123          nonLinearCost_->numberInfeasibilities(),nonLinearCost_->sumInfeasibilities());
05124   // Redo some stuff
05125   wholeModel->reducedCostWork_ = wholeModel->dj_;
05126   wholeModel->rowReducedCost_ = wholeModel->dj_+wholeModel->numberColumns_;
05127   wholeModel->columnActivityWork_ = wholeModel->solution_;
05128   wholeModel->rowActivityWork_ = wholeModel->solution_+wholeModel->numberColumns_;
05129   wholeModel->objectiveWork_ = wholeModel->cost_;
05130   wholeModel->rowObjectiveWork_ = wholeModel->cost_+wholeModel->numberColumns_;
05131   wholeModel->rowLowerWork_ = wholeModel->lower_+wholeModel->numberColumns_;
05132   wholeModel->columnLowerWork_ = wholeModel->lower_;
05133   wholeModel->rowUpperWork_ = wholeModel->upper_+wholeModel->numberColumns_;
05134   wholeModel->columnUpperWork_ = wholeModel->upper_;
05135 #ifndef NDEBUG
05136   // Check status
05137   ClpSimplex * xxxx = wholeModel;
05138   int nBasic=0;
05139   for (iColumn=0;iColumn<xxxx->numberRows_+xxxx->numberColumns_;iColumn++)
05140     if (xxxx->getStatus(iColumn)==basic)
05141       nBasic++;
05142   assert (nBasic==xxxx->numberRows_);
05143   for (iRow=0;iRow<xxxx->numberRows_;iRow++) {
05144     int iPivot=xxxx->pivotVariable_[iRow];
05145     assert (xxxx->getStatus(iPivot)==basic);
05146   }
05147 #endif
05148 }


Member Function Documentation

void ClpSimplex::borrowModel ClpModel otherModel  ) 
 

Borrow model. This is so we dont have to copy large amounts of data around. It assumes a derived class wants to overwrite an empty model with a real one - while it does an algorithm. This is same as ClpModel one, but sets scaling on etc.

Reimplemented from ClpModel.

Definition at line 2957 of file ClpSimplex.cpp.

References ClpModel::borrowModel(), createStatus(), setDualRowPivotAlgorithm(), and setPrimalColumnPivotAlgorithm().

02958 {
02959   ClpModel::borrowModel(otherModel);
02960   createStatus();
02961   ClpDualRowSteepest steep1;
02962   setDualRowPivotAlgorithm(steep1);
02963   ClpPrimalColumnSteepest steep2;
02964   setPrimalColumnPivotAlgorithm(steep2);
02965 }

void ClpSimplex::checkDualSolution  ) 
 

This sets largest infeasibility and most infeasible and sum and number of infeasibilities (Dual)

Definition at line 1718 of file ClpSimplex.cpp.

References columnActivityWork_, columnDualInfeasibility_, columnDualSequence_, columnLowerWork_, columnPrimalInfeasibility_, columnUpperWork_, dualTolerance_, firstFree_, largestDualError_, largeValue_, ClpSimplexProgress::lastIterationNumber(), numberDualInfeasibilities_, numberDualInfeasibilitiesWithoutFree_, primalTolerance_, primalToleranceToGetOptimal_, progress_, reducedCostWork_, remainingDualInfeasibility_, rowActivityWork_, rowDualInfeasibility_, rowDualSequence_, rowLowerWork_, rowPrimalInfeasibility_, rowReducedCost_, rowUpperWork_, sumDualInfeasibilities_, and sumOfRelaxedDualInfeasibilities_.

Referenced by checkSolution(), gutsOfSolution(), and ClpSimplexDual::statusOfProblemInDual().

01719 {
01720 
01721   int iRow,iColumn;
01722   sumDualInfeasibilities_=0.0;
01723   numberDualInfeasibilities_=0;
01724   numberDualInfeasibilitiesWithoutFree_=0;
01725   columnDualInfeasibility_=0.0;
01726   columnDualSequence_=-1;
01727   rowDualInfeasibility_=0.0;
01728   rowDualSequence_=-1;
01729   int firstFreePrimal = -1;
01730   int firstFreeDual = -1;
01731   int numberSuperBasicWithDj=0;
01732   primalToleranceToGetOptimal_=max(rowPrimalInfeasibility_,
01733                                    columnPrimalInfeasibility_);
01734   remainingDualInfeasibility_=0.0;
01735   double relaxedTolerance=dualTolerance_;
01736   // we can't really trust infeasibilities if there is dual error
01737   double error = min(1.0e-3,largestDualError_);
01738   // allow tolerance at least slightly bigger than standard
01739   relaxedTolerance = relaxedTolerance +  error;
01740   sumOfRelaxedDualInfeasibilities_ = 0.0;
01741 
01742   for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01743     if (getColumnStatus(iColumn) != basic&&!flagged(iColumn)) {
01744       // not basic
01745       double distanceUp = columnUpperWork_[iColumn]-
01746         columnActivityWork_[iColumn];
01747       double distanceDown = columnActivityWork_[iColumn] -
01748         columnLowerWork_[iColumn];
01749       if (distanceUp>primalTolerance_) {
01750         double value = reducedCostWork_[iColumn];
01751         // Check if "free"
01752         if (distanceDown>primalTolerance_) {
01753           if (fabs(value)>1.0e2*relaxedTolerance) {
01754             numberSuperBasicWithDj++;
01755             if (firstFreeDual<0)
01756               firstFreeDual = iColumn;
01757           }
01758           if (firstFreePrimal<0)
01759             firstFreePrimal = iColumn;
01760         }
01761         // should not be negative
01762         if (value<0.0) {
01763           value = - value;
01764           if (value>columnDualInfeasibility_) {
01765             columnDualInfeasibility_=value;
01766             columnDualSequence_=iColumn;
01767           }
01768           if (value>dualTolerance_) {
01769             if (getColumnStatus(iColumn) != isFree) {
01770               numberDualInfeasibilitiesWithoutFree_ ++;
01771               sumDualInfeasibilities_ += value-dualTolerance_;
01772               if (value>relaxedTolerance) 
01773                 sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01774               numberDualInfeasibilities_ ++;
01775             } else {
01776               // free so relax a lot
01777               value *= 0.01;
01778               if (value>dualTolerance_) {
01779                 sumDualInfeasibilities_ += value-dualTolerance_;
01780                 if (value>relaxedTolerance) 
01781                   sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01782                 numberDualInfeasibilities_ ++;
01783               }
01784             }
01785             // maybe we can make feasible by increasing tolerance
01786             if (distanceUp<largeValue_) {
01787               if (distanceUp>primalToleranceToGetOptimal_)
01788                 primalToleranceToGetOptimal_=distanceUp;
01789             } else {
01790               //gap too big for any tolerance
01791               remainingDualInfeasibility_=
01792                 max(remainingDualInfeasibility_,value);
01793             }
01794           }
01795         }
01796       }
01797       if (distanceDown>primalTolerance_) {
01798         double value = reducedCostWork_[iColumn];
01799         // should not be positive
01800         if (value>0.0) {
01801           if (value>columnDualInfeasibility_) {
01802             columnDualInfeasibility_=value;
01803             columnDualSequence_=iColumn;
01804           }
01805           if (value>dualTolerance_) {
01806             sumDualInfeasibilities_ += value-dualTolerance_;
01807             if (value>relaxedTolerance) 
01808               sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01809             numberDualInfeasibilities_ ++;
01810             if (getColumnStatus(iColumn) != isFree) 
01811               numberDualInfeasibilitiesWithoutFree_ ++;
01812             // maybe we can make feasible by increasing tolerance
01813             if (distanceDown<largeValue_&&
01814                 distanceDown>primalToleranceToGetOptimal_)
01815               primalToleranceToGetOptimal_=distanceDown;
01816           }
01817         }
01818       }
01819     }
01820   }
01821   for (iRow=0;iRow<numberRows_;iRow++) {
01822     if (getRowStatus(iRow) != basic&&!flagged(iRow+numberColumns_)) {
01823       // not basic
01824       double distanceUp = rowUpperWork_[iRow]-rowActivityWork_[iRow];
01825       double distanceDown = rowActivityWork_[iRow] -rowLowerWork_[iRow];
01826       if (distanceUp>primalTolerance_) {
01827         double value = rowReducedCost_[iRow];
01828         // Check if "free"
01829         if (distanceDown>primalTolerance_) {
01830           if (fabs(value)>1.0e2*relaxedTolerance) {
01831             numberSuperBasicWithDj++;
01832             if (firstFreeDual<0)
01833               firstFreeDual = iRow+numberColumns_;
01834           }
01835           if (firstFreePrimal<0)
01836             firstFreePrimal = iRow+numberColumns_;
01837         }
01838         // should not be negative
01839         if (value<0.0) {
01840           value = - value;
01841           if (value>rowDualInfeasibility_) {
01842             rowDualInfeasibility_=value;
01843             rowDualSequence_=iRow;
01844           }
01845           if (value>dualTolerance_) {
01846             sumDualInfeasibilities_ += value-dualTolerance_;
01847             if (value>relaxedTolerance) 
01848               sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01849             numberDualInfeasibilities_ ++;
01850             if (getRowStatus(iRow) != isFree) 
01851               numberDualInfeasibilitiesWithoutFree_ ++;
01852             // maybe we can make feasible by increasing tolerance
01853             if (distanceUp<largeValue_) {
01854               if (distanceUp>primalToleranceToGetOptimal_)
01855                 primalToleranceToGetOptimal_=distanceUp;
01856             } else {
01857               //gap too big for any tolerance
01858               remainingDualInfeasibility_=
01859                 max(remainingDualInfeasibility_,value);
01860             }
01861           }
01862         }
01863       }
01864       if (distanceDown>primalTolerance_) {
01865         double value = rowReducedCost_[iRow];
01866         // should not be positive
01867         if (value>0.0) {
01868           if (value>rowDualInfeasibility_) {
01869             rowDualInfeasibility_=value;
01870             rowDualSequence_=iRow;
01871           }
01872           if (value>dualTolerance_) {
01873             sumDualInfeasibilities_ += value-dualTolerance_;
01874             if (value>relaxedTolerance) 
01875               sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01876             numberDualInfeasibilities_ ++;
01877             if (getRowStatus(iRow) != isFree) 
01878               numberDualInfeasibilitiesWithoutFree_ ++;
01879             // maybe we can make feasible by increasing tolerance
01880             if (distanceDown<largeValue_&&
01881                 distanceDown>primalToleranceToGetOptimal_)
01882               primalToleranceToGetOptimal_=distanceDown;
01883           }
01884         }
01885       }
01886     }
01887   }
01888   if (algorithm_<0&&firstFreeDual>=0) {
01889     // dual
01890     firstFree_ = firstFreeDual;
01891   } else if (numberSuperBasicWithDj||
01892              (progress_&&progress_->lastIterationNumber(0)<=0)) {
01893     firstFree_=firstFreePrimal;
01894   }
01895 }

void ClpSimplex::checkPrimalSolution const double *  rowActivities = NULL,
const double *  columnActivies = NULL
 

This sets largest infeasibility and most infeasible and sum and number of infeasibilities (Primal)

Definition at line 1645 of file ClpSimplex.cpp.

References columnActivityWork_, columnLowerWork_, columnPrimalInfeasibility_, columnPrimalSequence_, columnUpperWork_, largestPrimalError_, largestSolutionError_, numberPrimalInfeasibilities_, objectiveWork_, primalTolerance_, rowActivityWork_, rowLowerWork_, rowObjectiveWork_, rowPrimalInfeasibility_, rowPrimalSequence_, rowUpperWork_, solution(), sumOfRelaxedPrimalInfeasibilities_, and sumPrimalInfeasibilities_.

Referenced by checkSolution(), gutsOfSolution(), and ClpSimplexDual::strongBranching().

01647 {
01648   double * solution;
01649   int iRow,iColumn;
01650 
01651   objectiveValue_ = 0.0;
01652   // now look at primal solution
01653   columnPrimalInfeasibility_=0.0;
01654   columnPrimalSequence_=-1;
01655   rowPrimalInfeasibility_=0.0;
01656   rowPrimalSequence_=-1;
01657   largestSolutionError_=0.0;
01658   solution = rowActivityWork_;
01659   sumPrimalInfeasibilities_=0.0;
01660   numberPrimalInfeasibilities_=0;
01661   double primalTolerance = primalTolerance_;
01662   double relaxedTolerance=primalTolerance_;
01663   // we can't really trust infeasibilities if there is primal error
01664   double error = min(1.0e-3,largestPrimalError_);
01665   // allow tolerance at least slightly bigger than standard
01666   relaxedTolerance = relaxedTolerance +  error;
01667   sumOfRelaxedPrimalInfeasibilities_ = 0.0;
01668 
01669   for (iRow=0;iRow<numberRows_;iRow++) {
01670     //assert (fabs(solution[iRow])<1.0e15||getRowStatus(iRow) == basic);
01671     double infeasibility=0.0;
01672     objectiveValue_ += solution[iRow]*rowObjectiveWork_[iRow];
01673     if (solution[iRow]>rowUpperWork_[iRow]) {
01674       infeasibility=solution[iRow]-rowUpperWork_[iRow];
01675     } else if (solution[iRow]<rowLowerWork_[iRow]) {
01676       infeasibility=rowLowerWork_[iRow]-solution[iRow];
01677     }
01678     if (infeasibility>primalTolerance) {
01679       sumPrimalInfeasibilities_ += infeasibility-primalTolerance_;
01680       if (infeasibility>relaxedTolerance) 
01681         sumOfRelaxedPrimalInfeasibilities_ += infeasibility-relaxedTolerance;
01682       numberPrimalInfeasibilities_ ++;
01683     }
01684     if (infeasibility>rowPrimalInfeasibility_) {
01685       rowPrimalInfeasibility_=infeasibility;
01686       rowPrimalSequence_=iRow;
01687     }
01688     infeasibility = fabs(rowActivities[iRow]-solution[iRow]);
01689     if (infeasibility>largestSolutionError_)
01690       largestSolutionError_=infeasibility;
01691   }
01692   solution = columnActivityWork_;
01693   for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01694     //assert (fabs(solution[iColumn])<1.0e15||getColumnStatus(iColumn) == basic);
01695     double infeasibility=0.0;
01696     objectiveValue_ += objectiveWork_[iColumn]*solution[iColumn];
01697     if (solution[iColumn]>columnUpperWork_[iColumn]) {
01698       infeasibility=solution[iColumn]-columnUpperWork_[iColumn];
01699     } else if (solution[iColumn]<columnLowerWork_[iColumn]) {
01700       infeasibility=columnLowerWork_[iColumn]-solution[iColumn];
01701     }
01702     if (infeasibility>columnPrimalInfeasibility_) {
01703       columnPrimalInfeasibility_=infeasibility;
01704       columnPrimalSequence_=iColumn;
01705     }
01706     if (infeasibility>primalTolerance) {
01707       sumPrimalInfeasibilities_ += infeasibility-primalTolerance_;
01708       if (infeasibility>relaxedTolerance) 
01709         sumOfRelaxedPrimalInfeasibilities_ += infeasibility-relaxedTolerance;
01710       numberPrimalInfeasibilities_ ++;
01711     }
01712     infeasibility = fabs(columnActivities[iColumn]-solution[iColumn]);
01713     if (infeasibility>largestSolutionError_)
01714       largestSolutionError_=infeasibility;
01715   }
01716 }

void ClpSimplex::checkSolution  ) 
 

Just check solution (for external use) - sets sum of infeasibilities etc

Definition at line 3673 of file ClpSimplex.cpp.

References checkDualSolution(), checkPrimalSolution(), columnActivityWork_, createRim(), deleteRim(), dj_, dualTolerance_, numberDualInfeasibilities_, numberPrimalInfeasibilities_, ClpModel::objectiveValue(), primalTolerance_, rowActivityWork_, and solution_.

Referenced by initialSolve().

03674 {
03675   // put in standard form
03676   createRim(7+8+16);
03677   dualTolerance_=dblParam_[ClpDualTolerance];
03678   primalTolerance_=dblParam_[ClpPrimalTolerance];
03679   checkPrimalSolution( rowActivityWork_, columnActivityWork_);
03680   checkDualSolution();
03681   if (!numberDualInfeasibilities_&&
03682       !numberPrimalInfeasibilities_)
03683     problemStatus_=0;
03684   else
03685     problemStatus_=-1;
03686 #ifdef CLP_DEBUG
03687   int i;
03688   double value=0.0;
03689   for (i=0;i<numberRows_+numberColumns_;i++)
03690     value += dj_[i]*solution_[i];
03691   printf("dual value %g, primal %g\n",value,objectiveValue());
03692 #endif
03693   // release extra memory
03694   deleteRim(0);
03695 }

double ClpSimplex::columnDualInfeasibility  )  const [inline]
 

Worst column dual infeasibility (note - these may not be as meaningful if the problem is primal infeasible

Definition at line 474 of file ClpSimplex.hpp.

References columnDualInfeasibility_.

00475           { return columnDualInfeasibility_;} ;

void ClpSimplex::computeDuals double *  givenDjs  ) 
 

Computes duals from scratch. If givenDjs then allows for nonzero basic djs

Definition at line 492 of file ClpSimplex.cpp.

References CoinIndexedVector::checkClear(), CoinIndexedVector::clear(), cost_, CoinIndexedVector::denseVector(), dj_, factorization_, CoinIndexedVector::getIndices(), largestDualError_, numberRefinements_, objectiveWork_, pivotVariable_, reducedCostWork_, CoinIndexedVector::reserve(), rowArray_, rowObjectiveWork_, rowReducedCost_, CoinIndexedVector::setNumElements(), and transposeTimes().

Referenced by gutsOfSolution(), ClpSimplexPrimal::primal(), and ClpSimplexDual::statusOfProblemInDual().

00493 {
00494   //work space
00495   CoinIndexedVector  * workSpace = rowArray_[0];
00496 
00497   CoinIndexedVector arrayVector;
00498   arrayVector.reserve(numberRows_+1);
00499   CoinIndexedVector previousVector;
00500   previousVector.reserve(numberRows_+1);
00501 
00502 
00503   int iRow;
00504 #ifdef CLP_DEBUG
00505   workSpace->checkClear();
00506 #endif
00507   double * array = arrayVector.denseVector();
00508   int * index = arrayVector.getIndices();
00509   int number=0;
00510   if (!givenDjs) {
00511     for (iRow=0;iRow<numberRows_;iRow++) {
00512       int iPivot=pivotVariable_[iRow];
00513       double value = cost_[iPivot];
00514       if (value) {
00515         array[iRow]=value;
00516         index[number++]=iRow;
00517       }
00518     }
00519   } else {
00520     // dual values pass - djs may not be zero
00521     for (iRow=0;iRow<numberRows_;iRow++) {
00522       int iPivot=pivotVariable_[iRow];
00523       // make sure zero if done
00524       if (!pivoted(iPivot))
00525         givenDjs[iPivot]=0.0;
00526       double value =cost_[iPivot]-givenDjs[iPivot];
00527       if (value) {
00528         array[iRow]=value;
00529         index[number++]=iRow;
00530       }
00531     }
00532   }
00533   arrayVector.setNumElements(number);
00534 
00535   // Btran basic costs and get as accurate as possible
00536   double lastError=COIN_DBL_MAX;
00537   int iRefine;
00538   double * work = workSpace->denseVector();
00539   CoinIndexedVector * thisVector = &arrayVector;
00540   CoinIndexedVector * lastVector = &previousVector;
00541   factorization_->updateColumnTranspose(workSpace,thisVector);
00542 
00543   for (iRefine=0;iRefine<numberRefinements_+1;iRefine++) {
00544     // check basic reduced costs zero
00545     largestDualError_=0.0;
00546     // would be faster to do just for basic but this reduces code
00547     ClpDisjointCopyN(objectiveWork_,numberColumns_,reducedCostWork_);
00548     transposeTimes(-1.0,array,reducedCostWork_);
00549     if (!givenDjs) {
00550       for (iRow=0;iRow<numberRows_;iRow++) {
00551         int iPivot=pivotVariable_[iRow];
00552         double value;
00553         if (iPivot>=numberColumns_) {
00554           // slack
00555           value = rowObjectiveWork_[iPivot-numberColumns_]
00556             + array[iPivot-numberColumns_];
00557         } else {
00558           // column
00559           value = reducedCostWork_[iPivot];
00560         }
00561         work[iRow]=value;
00562         if (fabs(value)>largestDualError_) {
00563           largestDualError_=fabs(value);
00564         }
00565       }
00566     } else {
00567       for (iRow=0;iRow<numberRows_;iRow++) {
00568         int iPivot=pivotVariable_[iRow];
00569         if (iPivot>=numberColumns_) {
00570           // slack
00571           work[iRow] = rowObjectiveWork_[iPivot-numberColumns_]
00572             + array[iPivot-numberColumns_]-givenDjs[iPivot];
00573         } else {
00574           // column
00575           work[iRow] = reducedCostWork_[iPivot]- givenDjs[iPivot];
00576         }
00577         if (fabs(work[iRow])>largestDualError_) {
00578           largestDualError_=fabs(work[iRow]);
00579           //assert (largestDualError_<1.0e-7);
00580           //if (largestDualError_>1.0e-7)
00581           //printf("large dual error %g\n",largestDualError_);
00582         }
00583       }
00584     }
00585     if (largestDualError_>=lastError) {
00586       // restore
00587       CoinIndexedVector * temp = thisVector;
00588       thisVector = lastVector;
00589       lastVector=temp;
00590       break;
00591     }
00592     if (iRefine<numberRefinements_&&largestDualError_>1.0e-10
00593         &&!givenDjs) {
00594       // try and make better
00595       // save this
00596       CoinIndexedVector * temp = thisVector;
00597       thisVector = lastVector;
00598       lastVector=temp;
00599       int * indexOut = thisVector->getIndices();
00600       int number=0;
00601       array = thisVector->denseVector();
00602       thisVector->clear();
00603       double multiplier = 131072.0;
00604       for (iRow=0;iRow<numberRows_;iRow++) {
00605         double value = multiplier*work[iRow];
00606         if (value) {
00607           array[iRow]=value;
00608           indexOut[number++]=iRow;
00609           work[iRow]=0.0;
00610         }
00611         work[iRow]=0.0;
00612       }
00613       thisVector->setNumElements(number);
00614       lastError=largestDualError_;
00615       factorization_->updateColumnTranspose(workSpace,thisVector);
00616       multiplier = 1.0/multiplier;
00617       double * previous = lastVector->denseVector();
00618       number=0;
00619       for (iRow=0;iRow<numberRows_;iRow++) {
00620         double value = previous[iRow] + multiplier*array[iRow];
00621         if (value) {
00622           array[iRow]=value;
00623           indexOut[number++]=iRow;
00624         } else {
00625           array[iRow]=0.0;
00626         }
00627       }
00628       thisVector->setNumElements(number);
00629     } else {
00630       break;
00631     }
00632   }
00633   ClpFillN(work,numberRows_,0.0);
00634   // now look at dual solution
00635   array = thisVector->denseVector();
00636   for (iRow=0;iRow<numberRows_;iRow++) {
00637     // slack
00638     double value = array[iRow];
00639     dual_[iRow]=value;
00640     value += rowObjectiveWork_[iRow];
00641     rowReducedCost_[iRow]=value;
00642   }
00643   ClpDisjointCopyN(objectiveWork_,numberColumns_,reducedCostWork_);
00644   transposeTimes(-1.0,dual_,reducedCostWork_);
00645   // If necessary - override results
00646   if (givenDjs) {
00647     // restore accurate duals
00648     memcpy(givenDjs,dj_,(numberRows_+numberColumns_)*sizeof(double));
00649   }
00650 
00651 }

int ClpSimplex::crash double  gap,
int  pivot
 

Crash - at present just aimed at dual, returns -2 if dual preferred and crash basis created -1 if dual preferred and all slack basis preferred 0 if basis going in was not all slack 1 if primal preferred and all slack basis preferred 2 if primal preferred and crash basis created.

if gap between bounds <="gap" variables can be flipped

If "pivot" is 0 No pivoting (so will just be choice of algorithm) 1 Simple pivoting e.g. gub 2 Mini iterations

Definition at line 3711 of file ClpSimplex.cpp.

References createStatus(), ClpModel::matrix(), CoinMessageHandler::message(), ClpModel::objective(), and solution().

03712 {
03713   assert(!rowObjective_); // not coded
03714   int iColumn;
03715   int numberBad=0;
03716   int numberBasic=0;
03717   double dualTolerance=dblParam_[ClpDualTolerance];
03718   //double primalTolerance=dblParam_[ClpPrimalTolerance];
03719   int returnCode=0;
03720   // If no basis then make all slack one
03721   if (!status_)
03722     createStatus();
03723   
03724   for (iColumn=0;iColumn<numberColumns_;iColumn++) {
03725     if (getColumnStatus(iColumn)==basic)
03726       numberBasic++;
03727   }
03728   if (!numberBasic) {
03729     // all slack
03730     double * dj = new double [numberColumns_];
03731     double * solution = columnActivity_;
03732     const double * linearObjective = objective();
03733     //double objectiveValue=0.0;
03734     int iColumn;
03735     double direction = optimizationDirection_;
03736     // direction is actually scale out not scale in
03737     if (direction)
03738       direction = 1.0/direction;
03739     for (iColumn=0;iColumn<numberColumns_;iColumn++)
03740       dj[iColumn] = direction*linearObjective[iColumn];
03741     for (iColumn=0;iColumn<numberColumns_;iColumn++) {
03742       // assume natural place is closest to zero
03743       double lowerBound = columnLower_[iColumn];
03744       double upperBound = columnUpper_[iColumn];
03745       if (lowerBound>-1.0e20||upperBound<1.0e20) {
03746         bool atLower;
03747         if (fabs(upperBound)<fabs(lowerBound)) {
03748           atLower=false;
03749           setColumnStatus(iColumn,atUpperBound);
03750           solution[iColumn]=upperBound;
03751         } else {
03752           atLower=true;
03753           setColumnStatus(iColumn,atLowerBound);
03754           solution[iColumn]=lowerBound;
03755         }
03756         if (dj[iColumn]<0.0) {
03757           // should be at upper bound
03758           if (atLower) {
03759             // can we flip
03760             if (upperBound-lowerBound<=gap) {
03761               columnActivity_[iColumn]=upperBound;
03762               setColumnStatus(iColumn,atUpperBound);
03763             } else if (dj[iColumn]<-dualTolerance) {
03764               numberBad++;
03765             }
03766           }
03767         } else if (dj[iColumn]>0.0) {
03768           // should be at lower bound
03769           if (!atLower) {
03770             // can we flip
03771             if (upperBound-lowerBound<=gap) {
03772               columnActivity_[iColumn]=lowerBound;
03773               setColumnStatus(iColumn,atLowerBound);
03774             } else if (dj[iColumn]>dualTolerance) {
03775               numberBad++;
03776             }
03777           }
03778         }
03779       } else {
03780         // free
03781         setColumnStatus(iColumn,isFree);
03782         if (fabs(dj[iColumn])>dualTolerance) 
03783           numberBad++;
03784       }
03785     }
03786     if (numberBad||pivot) {
03787       if (!pivot) {
03788         delete [] dj;
03789         returnCode = 1;
03790       } else {
03791         // see if can be made dual feasible with gubs etc
03792         double * pi = new double[numberRows_];
03793         memset (pi,0,numberRows_*sizeof(double));
03794         int * way = new int[numberColumns_];
03795         int numberIn = 0;
03796 
03797         // Get column copy
03798         CoinPackedMatrix * columnCopy = matrix();
03799         // Get a row copy in standard format
03800         CoinPackedMatrix copy;
03801         copy.reverseOrderedCopyOf(*columnCopy);
03802         // get matrix data pointers
03803         const int * column = copy.getIndices();
03804         const CoinBigIndex * rowStart = copy.getVectorStarts();
03805         const int * rowLength = copy.getVectorLengths(); 
03806         const double * elementByRow = copy.getElements();
03807         //const int * row = columnCopy->getIndices();
03808         //const CoinBigIndex * columnStart = columnCopy->getVectorStarts();
03809         //const int * columnLength = columnCopy->getVectorLengths(); 
03810         //const double * element = columnCopy->getElements();
03811 
03812 
03813         // if equality row and bounds mean artificial in basis bad
03814         // then do anyway
03815 
03816         for (iColumn=0;iColumn<numberColumns_;iColumn++) {
03817           // - if we want to reduce dj, + if we want to increase
03818           int thisWay = 100;
03819           double lowerBound = columnLower_[iColumn];
03820           double upperBound = columnUpper_[iColumn];
03821           if (upperBound>lowerBound) {
03822             switch(getColumnStatus(iColumn)) {
03823               
03824             case basic:
03825               thisWay=0;
03826             case ClpSimplex::isFixed:
03827               break;
03828             case isFree:
03829             case superBasic:
03830               if (dj[iColumn]<-dualTolerance) 
03831                 thisWay = 1;
03832               else if (dj[iColumn]>dualTolerance) 
03833                 thisWay = -1;
03834               else
03835                 thisWay =0;
03836               break;
03837             case atUpperBound:
03838               if (dj[iColumn]>dualTolerance) 
03839                 thisWay = -1;
03840               else if (dj[iColumn]<-dualTolerance) 
03841                 thisWay = -3;
03842               else
03843                 thisWay = -2;
03844               break;
03845             case atLowerBound:
03846               if (dj[iColumn]<-dualTolerance) 
03847                 thisWay = 1;
03848               else if (dj[iColumn]>dualTolerance) 
03849                 thisWay = 3;
03850               else
03851                 thisWay = 2;
03852               break;
03853             }
03854           }
03855           way[iColumn] = thisWay;
03856         }
03857         /*if (!numberBad)
03858           printf("Was dual feasible before passes - rows %d\n",
03859           numberRows_);*/
03860         int lastNumberIn = -100000;
03861         int numberPasses=5;
03862         while (numberIn>lastNumberIn+numberRows_/100) {
03863           lastNumberIn = numberIn;
03864           // we need to maximize chance of doing good
03865           int iRow;
03866           for (iRow=0;iRow<numberRows_;iRow++) {
03867             double lowerBound = rowLower_[iRow];
03868             double upperBound = rowUpper_[iRow];
03869             if (getRowStatus(iRow)==basic) {
03870               // see if we can find a column to pivot on
03871               int j;
03872               // down is amount pi can go down
03873               double maximumDown = COIN_DBL_MAX;
03874               double maximumUp = COIN_DBL_MAX;
03875               double minimumDown =0.0;
03876               double minimumUp =0.0;
03877               int iUp=-1;
03878               int iDown=-1;
03879               int iUpB=-1;
03880               int iDownB=-1;
03881               if (lowerBound<-1.0e20)
03882                 maximumUp = -1.0;
03883               if (upperBound>1.0e20)
03884                 maximumDown = -1.0;
03885               for (j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
03886                 int iColumn = column[j];
03887                 double value = elementByRow[j];
03888                 double djValue = dj[iColumn];
03889                 /* way -
03890                    -3 - okay at upper bound with negative dj
03891                    -2 - marginal at upper bound with zero dj - can only decrease
03892                    -1 - bad at upper bound
03893                    0 - we can never pivot on this row
03894                    1 - bad at lower bound
03895                    2 - marginal at lower bound with zero dj - can only increase
03896                    3 - okay at lower bound with positive dj
03897                    100 - fine we can just ignore
03898                 */
03899                 if (way[iColumn]!=100) {
03900                   switch(way[iColumn]) {
03901                     
03902                   case -3:
03903                     if (value>0.0) {
03904                       if (maximumDown*value>-djValue) {
03905                         maximumDown = -djValue/value;
03906                         iDown = iColumn;
03907                       }
03908                     } else {
03909                       if (-maximumUp*value>-djValue) {
03910                         maximumUp = djValue/value;
03911                         iUp = iColumn;
03912                       }
03913                     }
03914                     break;
03915                   case -2:
03916                     if (value>0.0) {
03917                       maximumDown = 0.0;
03918                     } else {
03919                       maximumUp = 0.0;
03920                     }
03921                     break;
03922                   case -1:
03923                     // see if could be satisfied
03924                     // dj value > 0
03925                     if (value>0.0) {
03926                       maximumDown=0.0;
03927                       if (maximumUp*value<djValue-dualTolerance) {
03928                         maximumUp = 0.0; // would improve but not enough
03929                       } else {
03930                         if (minimumUp*value<djValue) {
03931                           minimumUp = djValue/value;
03932                           iUpB = iColumn;
03933                         }
03934                       }
03935                     } else {
03936                       maximumUp=0.0;
03937                       if (-maximumDown*value<djValue-dualTolerance) {
03938                         maximumDown = 0.0; // would improve but not enough
03939                       } else {
03940                         if (-minimumDown*value<djValue) {
03941                           minimumDown = -djValue/value;
03942                           iDownB = iColumn;
03943                         }
03944                       }
03945                     }
03946                     
03947                     break;
03948                   case 0:
03949                     maximumDown = -1.0;
03950                     maximumUp=-1.0;
03951                     break;
03952                   case 1:
03953                     // see if could be satisfied
03954                     // dj value < 0
03955                     if (value>0.0) {
03956                       maximumUp=0.0;
03957                       if (maximumDown*value<-djValue-dualTolerance) {
03958                         maximumDown = 0.0; // would improve but not enough
03959                       } else {
03960                         if (minimumDown*value<-djValue) {
03961                           minimumDown = -djValue/value;
03962                           iDownB = iColumn;
03963                         }
03964                       }
03965                     } else {
03966                       maximumDown=0.0;
03967                       if (-maximumUp*value<-djValue-dualTolerance) {
03968                         maximumUp = 0.0; // would improve but not enough
03969                       } else {
03970                         if (-minimumUp*value<-djValue) {
03971                           minimumUp = djValue/value;
03972                           iUpB = iColumn;
03973                         }
03974                       }
03975                     }
03976                     
03977                     break;
03978                   case 2:
03979                     if (value>0.0) {
03980                       maximumUp = 0.0;
03981                     } else {
03982                       maximumDown = 0.0;
03983                     }
03984                     
03985                     break;
03986                   case 3:
03987                     if (value>0.0) {
03988                       if (maximumUp*value>djValue) {
03989                         maximumUp = djValue/value;
03990                         iUp = iColumn;
03991                       }
03992                     } else {
03993                       if (-maximumDown*value>djValue) {
03994                         maximumDown = -djValue/value;
03995                         iDown = iColumn;
03996                       }
03997                     }
03998                     
03999                     break;
04000                   default:
04001                     break;
04002                   }
04003                 }
04004               }
04005               if (iUpB>=0)
04006                 iUp=iUpB;
04007               if (maximumUp<=dualTolerance||maximumUp<minimumUp)
04008                 iUp=-1;
04009               if (iDownB>=0)
04010                 iDown=iDownB;
04011               if (maximumDown<=dualTolerance||maximumDown<minimumDown)
04012                 iDown=-1;
04013               if (iUp>=0||iDown>=0) {
04014                 // do something
04015                 if (iUp>=0&&iDown>=0) {
04016                   if (maximumDown>maximumUp)
04017                     iUp=-1;
04018                 }
04019                 double change;
04020                 int kColumn;
04021                 if (iUp>=0) {
04022                   kColumn=iUp;
04023                   change=maximumUp;
04024                   // just do minimum if was dual infeasible
04025                   // ? only if maximum large?
04026                   if (minimumUp>0.0)
04027                     change=minimumUp;
04028                   setRowStatus(iRow,atUpperBound);
04029                 } else {
04030                   kColumn=iDown;
04031                   change=-maximumDown;
04032                   // just do minimum if was dual infeasible
04033                   // ? only if maximum large?
04034                   if (minimumDown>0.0)
04035                     change=-minimumDown;
04036                   setRowStatus(iRow,atLowerBound);
04037                 }
04038                 assert (fabs(change)<1.0e20);
04039                 setColumnStatus(kColumn,basic);
04040                 numberIn++;
04041                 pi[iRow]=change;
04042                 for (j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
04043                   int iColumn = column[j];
04044                   double value = elementByRow[j];
04045                   double djValue = dj[iColumn]-change*value;
04046                   dj[iColumn]=djValue;
04047                   if (abs(way[iColumn])==1) {
04048                     numberBad--;
04049                     /*if (!numberBad)
04050                       printf("Became dual feasible at row %d out of %d\n",
04051                       iRow, numberRows_);*/
04052                     lastNumberIn=-1000000;
04053                   }
04054                   int thisWay = 100;
04055                   double lowerBound = columnLower_[iColumn];
04056                   double upperBound = columnUpper_[iColumn];
04057                   if (upperBound>lowerBound) {
04058                     switch(getColumnStatus(iColumn)) {
04059                       
04060                     case basic:
04061                       thisWay=0;
04062                     case isFixed:
04063                       break;
04064                     case isFree:
04065                     case superBasic:
04066                       if (djValue<-dualTolerance) 
04067                         thisWay = 1;
04068                       else if (djValue>dualTolerance) 
04069                         thisWay = -1;
04070                       else
04071                         { thisWay =0; abort();}
04072                       break;
04073                     case atUpperBound:
04074                       if (djValue>dualTolerance) 
04075                         { thisWay =-1; abort();}
04076                       else if (djValue<-dualTolerance) 
04077                         thisWay = -3;
04078                       else
04079                         thisWay = -2;
04080                       break;
04081                     case atLowerBound:
04082                       if (djValue<-dualTolerance) 
04083                         { thisWay =1; abort();}
04084                       else if (djValue>dualTolerance) 
04085                         thisWay = 3;
04086                       else
04087                         thisWay = 2;
04088                       break;
04089                     }
04090                   }
04091                   way[iColumn] = thisWay;
04092                 }
04093               }
04094             }
04095           }
04096           if (numberIn==lastNumberIn||numberBad||pivot<2)
04097             break;
04098           if (!(--numberPasses))
04099             break;
04100           //printf("%d put in so far\n",numberIn);
04101         }
04102         // last attempt to flip
04103         for (iColumn=0;iColumn<numberColumns_;iColumn++) {
04104           double lowerBound = columnLower_[iColumn];
04105           double upperBound = columnUpper_[iColumn];
04106           if (upperBound-lowerBound<=gap&&upperBound>lowerBound) {
04107             double djValue=dj[iColumn];
04108             switch(getColumnStatus(iColumn)) {
04109               
04110             case basic:
04111             case ClpSimplex::isFixed:
04112               break;
04113             case isFree:
04114             case superBasic:
04115               break;
04116             case atUpperBound:
04117               if (djValue>dualTolerance) {
04118                 setColumnStatus(iColumn,atUpperBound);
04119                 solution[iColumn]=upperBound;
04120               } 
04121               break;
04122             case atLowerBound:
04123               if (djValue<-dualTolerance) {
04124                 setColumnStatus(iColumn,atUpperBound);
04125                 solution[iColumn]=upperBound;
04126               }
04127               break;
04128             }
04129           }
04130         }
04131         delete [] pi;
04132         delete [] dj;
04133         delete [] way;
04134         handler_->message(CLP_CRASH,messages_)
04135           <<numberIn
04136           <<numberBad
04137           <<CoinMessageEol;
04138         returnCode =  -1;
04139       }
04140     } else {
04141       delete [] dj;
04142       returnCode =  -1;
04143     }
04144     //cleanStatus();
04145   }
04146   return returnCode;
04147 }

int ClpSimplex::createPiecewiseLinearCosts const int *  starts,
const double *  lower,
const double *  gradient
 

Constructs a non linear cost from list of non-linearities (columns only) First lower of each column is taken as real lower Last lower is taken as real upper and cost ignored

Returns nonzero if bad data e.g. lowers not monotonic

Definition at line 4577 of file ClpSimplex.cpp.

References nonLinearCost_, and specialOptions_.

04579 {
04580   delete nonLinearCost_;
04581   // Set up feasible bounds and check monotonicity
04582   int iColumn;
04583   int returnCode=0;
04584 
04585   for (iColumn=0;iColumn<numberColumns_;iColumn++) {
04586     int iIndex = starts[iColumn];
04587     int end = starts[iColumn+1]-1;
04588     columnLower_[iColumn] = lower[iIndex];
04589     columnUpper_[iColumn] = lower[end];
04590     double value = columnLower_[iColumn];
04591     iIndex++;
04592     for (;iIndex<end;iIndex++) {
04593       if (lower[iIndex]<value)
04594         returnCode++; // not monotonic
04595       value=lower[iIndex];
04596     }
04597   }
04598   nonLinearCost_ = new ClpNonLinearCost(this,starts,lower,gradient);
04599   specialOptions_ |= 2; // say keep
04600   return returnCode;
04601 }

bool ClpSimplex::createRim int  what,
bool  makeRowCopy = false
[protected]
 

puts in format I like (rowLower,rowUpper) also see StandardMatrix 1 bit does rows, 2 bit does column bounds, 4 bit does objective(s). 8 bit does solution scaling in 16 bit does rowArray and columnArray indexed vectors and makes row copy if wanted, also sets columnStart_ etc Also creates scaling arrays if needed. It does scaling if needed. 16 also moves solutions etc in to work arrays On 16 returns false if problem "bad" i.e. matrix or bounds bad

Definition at line 1961 of file ClpSimplex.cpp.

References ClpMatrixBase::allElementsInRange(), columnActivityWork_, columnArray_, columnLowerWork_, columnScale_, columnUpperWork_, cost_, dj_, factorization_, ClpPackedMatrix::getElements(), ClpPackedMatrix::getIndices(), ClpPackedMatrix::getVectorStarts(), CoinMessageHandler::logLevel(), lower_, ClpModel::objective(), objectiveWork_, pivotVariable_, reducedCostWork_, CoinIndexedVector::reserve(), ClpMatrixBase::reverseOrderedCopy(), rowActivityWork_, rowArray_, rowLowerWork_, rowObjectiveWork_, rowReducedCost_, rowScale_, rowUpperWork_, sanityCheck(), ClpMatrixBase::scale(), scalingFlag_, CoinMessageHandler::setLogLevel(), solution_, and upper_.

Referenced by ClpSimplexDual::changeBounds(), checkSolution(), ClpSimplex(), factorize(), getSolution(), ClpSimplexPrimal::primal(), startup(), statusOfProblem(), ClpSimplexDual::statusOfProblemInDual(), ClpSimplexPrimalQuadratic::statusOfProblemInPrimal(), ClpSimplexPrimal::statusOfProblemInPrimal(), ClpSimplexDual::strongBranching(), ClpSimplexPrimal::unPerturb(), and ClpSimplexPrimal::whileIterating().

01962 {
01963   bool goodMatrix=true;
01964   int saveLevel=handler_->logLevel();
01965   if (problemStatus_==10) {
01966     handler_->setLogLevel(0); // switch off messages
01967   } else if (factorization_) {
01968     // match up factorization messages
01969     if (handler_->logLevel()<3)
01970       factorization_->messageLevel(0);
01971     else
01972       factorization_->messageLevel(3);
01973   }
01974   int i;
01975   if ((what&(16+32))!=0) {
01976     // move information to work arrays
01977     double direction = optimizationDirection_;
01978     // direction is actually scale out not scale in
01979     if (direction)
01980       direction = 1.0/direction;
01981     if (direction!=1.0) {
01982       // reverse all dual signs
01983       for (i=0;i<numberColumns_;i++) 
01984         reducedCost_[i] *= direction;
01985       for (i=0;i<numberRows_;i++) 
01986         dual_[i] *= direction;
01987     }
01988     // row reduced costs
01989     if (!dj_) {
01990       dj_ = new double[numberRows_+numberColumns_];
01991       reducedCostWork_ = dj_;
01992       rowReducedCost_ = dj_+numberColumns_;
01993       memcpy(reducedCostWork_,reducedCost_,numberColumns_*sizeof(double));
01994       memcpy(rowReducedCost_,dual_,numberRows_*sizeof(double));
01995     }
01996     if (!solution_||(what&32)!=0) {
01997       if (!solution_)
01998         solution_ = new double[numberRows_+numberColumns_];
01999       columnActivityWork_ = solution_;
02000       rowActivityWork_ = solution_+numberColumns_;
02001       memcpy(columnActivityWork_,columnActivity_,
02002              numberColumns_*sizeof(double));
02003       memcpy(rowActivityWork_,rowActivity_,
02004              numberRows_*sizeof(double));
02005     }
02006   }
02007   if ((what&16)!=0) {
02008     //check matrix
02009     if (!matrix_)
02010       matrix_=new ClpPackedMatrix();
02011     if (!matrix_->allElementsInRange(this,smallElement_,1.0e20)) {
02012       problemStatus_=4;
02013       goodMatrix= false;
02014     }
02015     if (makeRowCopy) {
02016       delete rowCopy_;
02017       // may return NULL if can't give row copy
02018       rowCopy_ = matrix_->reverseOrderedCopy();
02019 #ifdef TAKEOUT
02020       {
02021 
02022         ClpPackedMatrix* rowCopy =
02023           dynamic_cast< ClpPackedMatrix*>(rowCopy_);
02024         const int * column = rowCopy->getIndices();
02025         const CoinBigIndex * rowStart = rowCopy->getVectorStarts();
02026         const double * element = rowCopy->getElements();
02027         int i;
02028         for (i=133;i<numberRows_;i++) {
02029           if (rowStart[i+1]-rowStart[i]==10||rowStart[i+1]-rowStart[i]==15)
02030             printf("Row %d has %d elements\n",i,rowStart[i+1]-rowStart[i]);
02031         }
02032       }  
02033 #endif
02034     }
02035   }
02036   if ((what&4)!=0) {
02037     delete [] cost_;
02038     // extra copy with original costs
02039     int nTotal = numberRows_+numberColumns_;
02040     //cost_ = new double[2*nTotal];
02041     cost_ = new double[nTotal];
02042     objectiveWork_ = cost_;
02043     rowObjectiveWork_ = cost_+numberColumns_;
02044     memcpy(objectiveWork_,objective(),numberColumns_*sizeof(double));
02045     if (rowObjective_)
02046       memcpy(rowObjectiveWork_,rowObjective_,numberRows_*sizeof(double));
02047     else
02048       memset(rowObjectiveWork_,0,numberRows_*sizeof(double));
02049     // and initialize changes to zero
02050     //memset(cost_+nTotal,0,nTotal*sizeof(double));
02051   }
02052   if ((what&1)!=0) {
02053     delete [] lower_;
02054     delete [] upper_;
02055     lower_ = new double[numberColumns_+numberRows_];
02056     upper_ = new double[numberColumns_+numberRows_];
02057     rowLowerWork_ = lower_+numberColumns_;
02058     columnLowerWork_ = lower_;
02059     rowUpperWork_ = upper_+numberColumns_;
02060     columnUpperWork_ = upper_;
02061     memcpy(rowLowerWork_,rowLower_,numberRows_*sizeof(double));
02062     memcpy(rowUpperWork_,rowUpper_,numberRows_*sizeof(double));
02063     memcpy(columnLowerWork_,columnLower_,numberColumns_*sizeof(double));
02064     memcpy(columnUpperWork_,columnUpper_,numberColumns_*sizeof(double));
02065     // clean up any mismatches on infinity
02066     for (i=0;i<numberColumns_;i++) {
02067       if (columnLowerWork_[i]<-1.0e30)
02068         columnLowerWork_[i] = -COIN_DBL_MAX;
02069       if (columnUpperWork_[i]>1.0e30)
02070         columnUpperWork_[i] = COIN_DBL_MAX;
02071     }
02072     // clean up any mismatches on infinity
02073     for (i=0;i<numberRows_;i++) {
02074       if (rowLowerWork_[i]<-1.0e30)
02075         rowLowerWork_[i] = -COIN_DBL_MAX;
02076       if (rowUpperWork_[i]>1.0e30)
02077         rowUpperWork_[i] = COIN_DBL_MAX;
02078     }
02079   }
02080   // do scaling if needed
02081   if (scalingFlag_>0&&!rowScale_) {
02082     if (matrix_->scale(this))
02083       scalingFlag_=-scalingFlag_; // not scaled after all
02084   }
02085   if ((what&4)!=0) {
02086     double direction = optimizationDirection_;
02087     // direction is actually scale out not scale in
02088     if (direction)
02089       direction = 1.0/direction;
02090     // but also scale by scale factors
02091     // not really sure about row scaling
02092     if (!rowScale_) {
02093       if (direction!=1.0) {
02094         for (i=0;i<numberRows_;i++)
02095           rowObjectiveWork_[i] *= direction;
02096         for (i=0;i<numberColumns_;i++)
02097           objectiveWork_[i] *= direction;
02098       }
02099     } else {
02100       for (i=0;i<numberRows_;i++)
02101         rowObjectiveWork_[i] *= direction/rowScale_[i];
02102       for (i=0;i<numberColumns_;i++)
02103         objectiveWork_[i] *= direction*columnScale_[i];
02104     }
02105   }
02106   if ((what&(1+32))!=0&&rowScale_) {
02107     for (i=0;i<numberColumns_;i++) {
02108       double multiplier = 1.0/columnScale_[i];
02109       if (columnLowerWork_[i]>-1.0e50)
02110         columnLowerWork_[i] *= multiplier;
02111       if (columnUpperWork_[i]<1.0e50)
02112         columnUpperWork_[i] *= multiplier;
02113       
02114     }
02115     for (i=0;i<numberRows_;i++) {
02116       if (rowLowerWork_[i]>-1.0e50)
02117         rowLowerWork_[i] *= rowScale_[i];
02118       if (rowUpperWork_[i]<1.0e50)
02119         rowUpperWork_[i] *= rowScale_[i];
02120     }
02121   }
02122   if ((what&(8+32))!=0&&rowScale_) {
02123     // on entry
02124     for (i=0;i<numberColumns_;i++) {
02125       columnActivityWork_[i] /= columnScale_[i];
02126       reducedCostWork_[i] *= columnScale_[i];
02127     }
02128     for (i=0;i<numberRows_;i++) {
02129       rowActivityWork_[i] *= rowScale_[i];
02130       dual_[i] /= rowScale_[i];
02131       rowReducedCost_[i] = dual_[i];
02132     }
02133   }
02134  
02135   if ((what&16)!=0) {
02136     // check rim of problem okay
02137     if (!sanityCheck())
02138       goodMatrix=false;
02139   } 
02140   // we need to treat matrix as if each element by rowScaleIn and columnScaleout??
02141   // maybe we need to move scales to SimplexModel for factorization?
02142   if ((what&8)!=0&&!pivotVariable_) {
02143     pivotVariable_=new int[numberRows_];
02144   }
02145 
02146   if ((what&16)!=0&&!rowArray_[2]) {
02147     // get some arrays
02148     int iRow,iColumn;
02149     // these are "indexed" arrays so we always know where nonzeros are
02150     /**********************************************************
02151       rowArray_[3] is long enough for rows+columns
02152     *********************************************************/
02153     for (iRow=0;iRow<4;iRow++) {
02154       if (!rowArray_[iRow]) {
02155         rowArray_[iRow]=new CoinIndexedVector();
02156         int length =numberRows_+factorization_->maximumPivots();
02157         if (iRow==3)
02158           length += numberColumns_;
02159         rowArray_[iRow]->reserve(length);
02160       }
02161     }
02162     
02163     for (iColumn=0;iColumn<2;iColumn++) {
02164       if (!columnArray_[iColumn]) {
02165         columnArray_[iColumn]=new CoinIndexedVector();
02166         if (!iColumn)
02167           columnArray_[iColumn]->reserve(numberColumns_);
02168         else
02169           columnArray_[iColumn]->reserve(max(numberRows_,numberColumns_));
02170       }
02171     }    
02172   }
02173   double primalTolerance=dblParam_[ClpPrimalTolerance];
02174   if ((what&1)!=0) {
02175     // fix any variables with tiny gaps
02176     for (i=0;i<numberColumns_;i++) {
02177       if (columnUpperWork_[i]-columnLowerWork_[i]<=primalTolerance) {
02178         if (columnLowerWork_[i]>=0.0) {
02179           columnUpperWork_[i] = columnLowerWork_[i];
02180         } else if (columnUpperWork_[i]<=0.0) {
02181           columnLowerWork_[i] = columnUpperWork_[i];
02182         } else {
02183           columnUpperWork_[i] = 0.0;
02184           columnLowerWork_[i] = 0.0;
02185         }
02186       }
02187     }
02188     for (i=0;i<numberRows_;i++) {
02189       if (rowUpperWork_[i]-rowLowerWork_[i]<=primalTolerance) {
02190         if (rowLowerWork_[i]>=0.0) {
02191           rowUpperWork_[i] = rowLowerWork_[i];
02192         } else if (rowUpperWork_[i]<=0.0) {
02193           rowLowerWork_[i] = rowUpperWork_[i];
02194         } else {
02195           rowUpperWork_[i] = 0.0;
02196           rowLowerWork_[i] = 0.0;
02197         }
02198       }
02199     }
02200   }
02201   if (problemStatus_==10) {
02202     problemStatus_=-1;
02203     handler_->setLogLevel(saveLevel); // switch back messages
02204   }
02205   return goodMatrix;
02206 }

void ClpSimplex::createStatus  ) 
 

Set up status array (can be used by OsiClp). Also can be used to set up all slack basis

Definition at line 3568 of file ClpSimplex.cpp.

Referenced by borrowModel(), cleanStatus(), crash(), loadProblem(), and readMps().

03569 {
03570   if(!status_)
03571     status_ = new unsigned char [numberColumns_+numberRows_];
03572   memset(status_,0,(numberColumns_+numberRows_)*sizeof(char));
03573   int i;
03574   // set column status to one nearest zero
03575   for (i=0;i<numberColumns_;i++) {
03576 #if 0
03577     if (columnLower_[i]>=0.0) {
03578       setColumnStatus(i,atLowerBound);
03579     } else if (columnUpper_[i]<=0.0) {
03580       setColumnStatus(i,atUpperBound);
03581     } else if (columnLower_[i]<-1.0e20&&columnUpper_[i]>1.0e20) {
03582       // free
03583       setColumnStatus(i,isFree);
03584     } else if (fabs(columnLower_[i])<fabs(columnUpper_[i])) {
03585       setColumnStatus(i,atLowerBound);
03586     } else {
03587       setColumnStatus(i,atUpperBound);
03588     }
03589 #else
03590     setColumnStatus(i,atLowerBound);
03591 #endif
03592   }
03593   for (i=0;i<numberRows_;i++) {
03594     setRowStatus(i,basic);
03595   }
03596 }

void ClpSimplex::deleteRim int  getRidOfFactorizationData = 2  )  [protected]
 

releases above arrays and does solution scaling out. May also get rid of factorization data - 0 get rid of nothing, 1 get rid of arrays, 2 also factorization

Definition at line 2208 of file ClpSimplex.cpp.

References columnActivityWork_, columnLowerWork_, columnScale_, columnUpperWork_, dualTolerance_, ClpModel::gutsOfDelete(), primalTolerance_, reducedCostWork_, rowActivityWork_, rowLowerWork_, rowObjectiveWork_, rowScale_, rowUpperWork_, and scalingFlag_.

Referenced by checkSolution(), factorize(), getSolution(), statusOfProblem(), and ClpSimplexDual::strongBranching().

02209 {
02210   int i;
02211   if (problemStatus_!=1&&problemStatus_!=2) {
02212     delete [] ray_;
02213     ray_=NULL;
02214   }
02215   // ray may be null if in branch and bound
02216   if (rowScale_) {
02217     // Collect infeasibilities
02218     int numberPrimalScaled=0;
02219     int numberPrimalUnscaled=0;
02220     int numberDualScaled=0;
02221     int numberDualUnscaled=0;
02222     for (i=0;i<numberColumns_;i++) {
02223       double scaleFactor = columnScale_[i];
02224       double valueScaled = columnActivityWork_[i];
02225       if (valueScaled<columnLowerWork_[i]-primalTolerance_)
02226         numberPrimalScaled++;
02227       else if (valueScaled>columnUpperWork_[i]+primalTolerance_)
02228         numberPrimalScaled++;
02229       columnActivity_[i] = valueScaled*scaleFactor;
02230       double value = columnActivity_[i];
02231       if (value<columnLower_[i]-primalTolerance_)
02232         numberPrimalUnscaled++;
02233       else if (value>columnUpper_[i]+primalTolerance_)
02234         numberPrimalUnscaled++;
02235       double valueScaledDual = reducedCostWork_[i];
02236       if (valueScaled>columnLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_)
02237         numberDualScaled++;
02238       if (valueScaled<columnUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_)
02239         numberDualScaled++;
02240       reducedCost_[i] = valueScaledDual/scaleFactor;
02241       double valueDual = reducedCost_[i];
02242       if (value>columnLower_[i]+primalTolerance_&&valueDual>dualTolerance_)
02243         numberDualUnscaled++;
02244       if (value<columnUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_)
02245         numberDualUnscaled++;
02246     }
02247     for (i=0;i<numberRows_;i++) {
02248       double scaleFactor = rowScale_[i];
02249       double valueScaled = rowActivityWork_[i];
02250       if (valueScaled<rowLowerWork_[i]-primalTolerance_)
02251         numberPrimalScaled++;
02252       else if (valueScaled>rowUpperWork_[i]+primalTolerance_)
02253         numberPrimalScaled++;
02254       rowActivity_[i] = valueScaled/scaleFactor;
02255       double value = rowActivity_[i];
02256       if (value<rowLower_[i]-primalTolerance_)
02257         numberPrimalUnscaled++;
02258       else if (value>rowUpper_[i]+primalTolerance_)
02259         numberPrimalUnscaled++;
02260       double valueScaledDual = dual_[i]+rowObjectiveWork_[i];;
02261       if (valueScaled>rowLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_)
02262         numberDualScaled++;
02263       if (valueScaled<rowUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_)
02264         numberDualScaled++;
02265       dual_[i] = valueScaledDual*scaleFactor;
02266       double valueDual = dual_[i]; 
02267       if (rowObjective_)
02268         valueDual += rowObjective_[i];
02269       if (value>rowLower_[i]+primalTolerance_&&valueDual>dualTolerance_)
02270         numberDualUnscaled++;
02271       if (value<rowUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_)
02272         numberDualUnscaled++;
02273     }
02274     if (!problemStatus_&&!secondaryStatus_) {
02275       // See if we need to set secondary status
02276       if (numberPrimalUnscaled) {
02277         if (numberDualUnscaled) 
02278           secondaryStatus_=4;
02279         else
02280           secondaryStatus_=2;
02281       } else {
02282         if (numberDualUnscaled) 
02283           secondaryStatus_=3;
02284       }
02285     }
02286     if (problemStatus_==2) {
02287       for (i=0;i<numberColumns_;i++) {
02288         ray_[i] *= columnScale_[i];
02289       }
02290     } else if (problemStatus_==1&&ray_) {
02291       for (i=0;i<numberRows_;i++) {
02292         ray_[i] *= rowScale_[i];
02293       }
02294     }
02295   } else {
02296     for (i=0;i<numberColumns_;i++) {
02297       columnActivity_[i] = columnActivityWork_[i];
02298       reducedCost_[i] = reducedCostWork_[i];
02299     }
02300     for (i=0;i<numberRows_;i++) {
02301       rowActivity_[i] = rowActivityWork_[i];
02302     }
02303   }
02304   if (optimizationDirection_!=1.0) {
02305     // and modify all dual signs
02306     for (i=0;i<numberColumns_;i++) 
02307       reducedCost_[i] *= optimizationDirection_;
02308     for (i=0;i<numberRows_;i++) 
02309       dual_[i] *= optimizationDirection_;
02310   }
02311   // scaling may have been turned off
02312   scalingFlag_ = abs(scalingFlag_);
02313   if(getRidOfFactorizationData>=0)
02314     gutsOfDelete(getRidOfFactorizationData+1);
02315 }

int ClpSimplex::directionIn  )  const [inline]
 

Return direction In or Out

Definition at line 618 of file ClpSimplex.hpp.

References directionIn_.

00619   {return directionIn_;};

int ClpSimplex::dual int  ifValuesPass = 0  ) 
 

Dual algorithm - see ClpSimplexDual.hpp for method

Reimplemented in ClpSimplexDual.

Definition at line 2880 of file ClpSimplex.cpp.

References perturbation_, and setInitialDenseFactorization().

02881 {
02882   assert (ifValuesPass>=0&&ifValuesPass<2);
02883   int returnCode = ((ClpSimplexDual *) this)->dual(ifValuesPass);
02884   if (problemStatus_==10) {
02885     //printf("Cleaning up with primal\n");
02886     int savePerturbation = perturbation_;
02887     perturbation_=100;
02888     bool denseFactorization = initialDenseFactorization();
02889     // It will be safe to allow dense
02890     setInitialDenseFactorization(true);
02891     returnCode = ((ClpSimplexPrimal *) this)->primal(1);
02892     setInitialDenseFactorization(denseFactorization);
02893     perturbation_=savePerturbation;
02894     if (problemStatus_==10) 
02895       problemStatus_=0;
02896   }
02897   return returnCode;
02898 }

int ClpSimplex::dualPivotResult  ) 
 

Pivot out a variable and choose an incoing one. Assumes dual feasible - will not go through a reduced cost. Returns step length in theta Returns ray in ray_ (or NULL if no pivot) Return codes as before but -1 means no acceptable pivot

Definition at line 4348 of file ClpSimplex.cpp.

04349 {
04350   return ((ClpSimplexDual *) this)->pivotResult();
04351 }

int ClpSimplex::getSolution  ) 
 

Given an existing factorization computes and checks primal and dual solutions. Uses current problem arrays for bounds. Returns feasibility states

Definition at line 671 of file ClpSimplex.cpp.

References columnActivityWork_, and rowActivityWork_.

00672 {
00673   double * rowActivities = new double[numberRows_];
00674   double * columnActivities = new double[numberColumns_];
00675   ClpDisjointCopyN ( rowActivityWork_, numberRows_ , rowActivities);
00676   ClpDisjointCopyN ( columnActivityWork_, numberColumns_ , columnActivities);
00677   int status = getSolution( rowActivities, columnActivities);
00678   delete [] rowActivities;
00679   delete [] columnActivities;
00680   return status;
00681 }

int ClpSimplex::getSolution const double *  rowActivities,
const double *  columnActivities
 

Given an existing factorization computes and checks primal and dual solutions. Uses input arrays for variables at bounds. Returns feasibility states

Definition at line 655 of file ClpSimplex.cpp.

References createRim(), deleteRim(), factorization_, and gutsOfSolution().

00657 {
00658   if (!factorization_->status()) {
00659     // put in standard form
00660     createRim(7+8+16+32);
00661     // do work
00662     gutsOfSolution ( NULL,NULL);
00663     // release extra memory
00664     deleteRim(0);
00665   }
00666   return factorization_->status();
00667 }

int ClpSimplex::gutsOfSolution double *  givenDuals,
const double *  givenPrimals,
bool  valuesPass = false
[protected]
 

May change basis and then returns number changed. Computation of solutions may be overriden by given pi and solution

Definition at line 244 of file ClpSimplex.cpp.

References algorithm_, ClpNonLinearCost::changeInCost(), checkDualSolution(), ClpNonLinearCost::checkInfeasibilities(), checkPrimalSolution(), columnActivityWork_, computeDuals(), computePrimals(), firstFree_, incomingInfeasibility_, largestDualError_, ClpNonLinearCost::largestInfeasibility(), largestPrimalError_, CoinMessageHandler::logLevel(), CoinMessageHandler::message(), nonLinearCost_, ClpNonLinearCost::numberInfeasibilities(), pivotVariable_, primalTolerance_, rowActivityWork_, solution_, specialOptions_, and times().

Referenced by ClpSimplexDual::dual(), ClpSimplexDual::fastDual(), getSolution(), pivot(), ClpSimplexPrimal::primal(), startup(), statusOfProblem(), ClpSimplexDual::statusOfProblemInDual(), ClpSimplexPrimalQuadratic::statusOfProblemInPrimal(), ClpSimplexPrimal::statusOfProblemInPrimal(), ClpSimplexPrimal::unPerturb(), ClpSimplexPrimal::whileIterating(), and ClpSimplexDual::whileIterating().

00247 {
00248 
00249 
00250   // if values pass, save values of basic variables
00251   double * save = NULL;
00252   double oldValue=0.0;
00253   if (valuesPass) {
00254     assert(algorithm_>0); // only primal at present
00255     assert(nonLinearCost_);
00256     int iRow;
00257     checkPrimalSolution( rowActivityWork_, columnActivityWork_);
00258     // get correct bounds on all variables
00259     nonLinearCost_->checkInfeasibilities(primalTolerance_);
00260     oldValue = nonLinearCost_->largestInfeasibility();
00261     save = new double[numberRows_];
00262     for (iRow=0;iRow<numberRows_;iRow++) {
00263       int iPivot=pivotVariable_[iRow];
00264       save[iRow] = solution_[iPivot];
00265     }
00266   }
00267   // do work
00268   computePrimals(rowActivityWork_, columnActivityWork_);
00269   // If necessary - override results
00270   if (givenPrimals) {
00271     memcpy(columnActivityWork_,givenPrimals,numberColumns_*sizeof(double));
00272     memset(rowActivityWork_,0,numberRows_*sizeof(double));
00273     times(-1.0,columnActivityWork_,rowActivityWork_);
00274   }
00275   double objectiveModification = 0.0;
00276   if (algorithm_>0&&nonLinearCost_!=NULL) {
00277     // primal algorithm
00278     // get correct bounds on all variables
00279     // If  4 bit set - Force outgoing variables to exact bound (primal)
00280     if ((specialOptions_&4)==0)
00281       nonLinearCost_->checkInfeasibilities(primalTolerance_);
00282     else
00283       nonLinearCost_->checkInfeasibilities(0.0);
00284     objectiveModification += nonLinearCost_->changeInCost();
00285     if (nonLinearCost_->numberInfeasibilities())
00286       handler_->message(CLP_SIMPLEX_NONLINEAR,messages_)
00287         <<nonLinearCost_->changeInCost()
00288         <<nonLinearCost_->numberInfeasibilities()
00289         <<CoinMessageEol;
00290   }
00291   if (valuesPass) {
00292 #ifdef CLP_DEBUG
00293     std::cout<<"Largest given infeasibility "<<oldValue
00294              <<" now "<<nonLinearCost_->largestInfeasibility()<<std::endl;
00295 #endif
00296     int numberOut=0;
00297     if (oldValue<incomingInfeasibility_
00298         &&nonLinearCost_->largestInfeasibility()>
00299         max(incomingInfeasibility_,allowedInfeasibility_)||
00300         largestPrimalError_>1.0e-3) {
00301       printf("Original largest infeas %g, now %g, primalError %g\n",
00302              oldValue,nonLinearCost_->largestInfeasibility(),
00303              largestPrimalError_);
00304       // throw out up to 1000 structurals
00305       int iRow;
00306       int * sort = new int[numberRows_];
00307       // first put back solution and store difference
00308       for (iRow=0;iRow<numberRows_;iRow++) {
00309         int iPivot=pivotVariable_[iRow];
00310         double difference = fabs(solution_[iPivot]-save[iRow]);
00311         solution_[iPivot]=save[iRow];
00312         save[iRow]=difference;
00313       }
00314       for (iRow=0;iRow<numberRows_;iRow++) {
00315         int iPivot=pivotVariable_[iRow];
00316 
00317         if (iPivot<numberColumns_) {
00318           // column
00319           double difference= save[iRow];
00320           if (difference>1.0e-4) {
00321             sort[numberOut]=iPivot;
00322             save[numberOut++]=difference;
00323           }
00324         }
00325       }
00326       CoinSort_2(save, save + numberOut, sort,
00327                  CoinFirstGreater_2<double, int>());
00328       numberOut = min(1000,numberOut);
00329       for (iRow=0;iRow<numberOut;iRow++) {
00330         int iColumn=sort[iRow];
00331         setColumnStatus(iColumn,superBasic);
00332 
00333       }
00334       delete [] sort;
00335     }
00336     delete [] save;
00337     if (numberOut)
00338       return numberOut;
00339   }
00340 
00341   computeDuals(givenDuals);
00342 
00343   // now check solutions
00344   checkPrimalSolution( rowActivityWork_, columnActivityWork_);
00345   objectiveValue_ += objectiveModification;
00346   checkDualSolution();
00347   if (handler_->logLevel()>3||(largestPrimalError_>1.0e-2||
00348                                largestDualError_>1.0e-2)) 
00349     handler_->message(CLP_SIMPLEX_ACCURACY,messages_)
00350       <<largestPrimalError_
00351       <<largestDualError_
00352       <<CoinMessageEol;
00353   // Switch off false values pass indicator
00354   if (!valuesPass&&algorithm_>0)
00355     firstFree_ = -1;
00356   return 0;
00357 }

int ClpSimplex::housekeeping double  objectiveChange  ) 
 

This does basis housekeeping and does values for in/out variables. Can also decide to re-factorize

Definition at line 1142 of file ClpSimplex.cpp.

References algorithm_, alpha_, changeMade_, ClpSimplexProgress::cycle(), directionIn_, directionOut_, dualIn_, dualOut_, factorization_, forceFactorization_, ClpModel::hitMaximumIterations(), isColumn(), lower_, CoinMessageHandler::message(), ClpModel::objectiveValue(), pivotRow_, pivotVariable_, CoinMessageHandler::printing(), progress_, progressFlag_, sequenceIn(), sequenceIn_, sequenceOut_, sequenceWithin(), setFlagged(), solution_, ClpSimplexProgress::startCheck(), theta_, upper_, valueIn_, and valueOut_.

Referenced by pivot(), ClpSimplexPrimal::pivotResult(), ClpSimplexPrimalQuadratic::whileIterating(), and ClpSimplexDual::whileIterating().

01143 {
01144   numberIterations_++;
01145   changeMade_++; // something has happened
01146   // incoming variable
01147   handler_->message(CLP_SIMPLEX_HOUSE1,messages_)
01148     <<directionOut_
01149     <<directionIn_<<theta_
01150     <<dualOut_<<dualIn_<<alpha_
01151     <<CoinMessageEol;
01152   if (getStatus(sequenceIn_)==isFree) {
01153     handler_->message(CLP_SIMPLEX_FREEIN,messages_)
01154       <<sequenceIn_
01155       <<CoinMessageEol;
01156   }
01157   // change of incoming
01158   char rowcol[]={'R','C'};
01159   if (pivotRow_>=0)
01160     pivotVariable_[pivotRow_]=sequenceIn();
01161   if (upper_[sequenceIn_]>1.0e20&&lower_[sequenceIn_]<-1.0e20)
01162     progressFlag_ |= 2; // making real progress
01163   solution_[sequenceIn_]=valueIn_;
01164   if (upper_[sequenceOut_]-lower_[sequenceOut_]<1.0e-12)
01165     progressFlag_ |= 1; // making real progress
01166   if (sequenceIn_!=sequenceOut_) {
01167     //assert( getStatus(sequenceOut_)== basic);
01168     setStatus(sequenceIn_,basic);
01169     if (upper_[sequenceOut_]-lower_[sequenceOut_]>0) {
01170       // As Nonlinear costs may have moved bounds (to more feasible)
01171       // Redo using value
01172       if (fabs(valueOut_-lower_[sequenceOut_])<fabs(valueOut_-upper_[sequenceOut_])) {
01173         // going to lower
01174         setStatus(sequenceOut_,atLowerBound);
01175       } else {
01176         // going to upper
01177         setStatus(sequenceOut_,atUpperBound);
01178       }
01179     } else {
01180       // fixed
01181       setStatus(sequenceOut_,isFixed);
01182     }
01183     solution_[sequenceOut_]=valueOut_;
01184   } else {
01185     // flip from bound to bound
01186     // As Nonlinear costs may have moved bounds (to more feasible)
01187     // Redo using value
01188     if (fabs(valueIn_-lower_[sequenceIn_])<fabs(valueIn_-upper_[sequenceIn_])) {
01189       // as if from upper bound
01190       setStatus(sequenceIn_, atLowerBound);
01191     } else {
01192       // as if from lower bound
01193       setStatus(sequenceIn_, atUpperBound);
01194     }
01195   }
01196   objectiveValue_ += objectiveChange;
01197   handler_->message(CLP_SIMPLEX_HOUSE2,messages_)
01198     <<numberIterations_<<objectiveValue()
01199     <<rowcol[isColumn(sequenceIn_)]<<sequenceWithin(sequenceIn_)
01200     <<rowcol[isColumn(sequenceOut_)]<<sequenceWithin(sequenceOut_);
01201   handler_->printing(algorithm_<0)<<theta_<<dualOut_;
01202   handler_->printing(algorithm_>0)<<dualIn_<<theta_;
01203   handler_->message()<<CoinMessageEol;
01204   if (hitMaximumIterations())
01205     return 2;
01206 #if 0
01207   // check for small cycles
01208   int cycle=progress_->cycle(sequenceIn_,sequenceOut_,
01209                             directionIn_,directionOut_);
01210   if (cycle>0) {
01211     printf("Cycle of %d\n",cycle);
01212     // reset
01213     progress_->startCheck();
01214     if (factorization_->pivots()>cycle) {
01215       forceFactorization_=cycle-1;
01216     } else {
01217       // need to reject something
01218       int iSequence;
01219       if (algorithm_<0)
01220         iSequence = sequenceIn_;
01221       else
01222         iSequence = sequenceOut_;
01223       char x = isColumn(iSequence) ? 'C' :'R';
01224       handler_->message(CLP_SIMPLEX_FLAG,messages_)
01225         <<x<<sequenceWithin(iSequence)
01226         <<CoinMessageEol;
01227       setFlagged(iSequence);
01228       printf("flagging %d\n",iSequence);
01229     }
01230     return 1;
01231   }
01232 #endif
01233   // only time to re-factorize if one before real time
01234   // this is so user won't be surprised that maximumPivots has exact meaning
01235   if (factorization_->pivots()==factorization_->maximumPivots()) {
01236     return 1;
01237   } else {
01238     if (forceFactorization_>0&&
01239         factorization_->pivots()==forceFactorization_) {
01240       // relax
01241       forceFactorization_ = (3+5*forceFactorization_)/4;
01242       if (forceFactorization_>factorization_->maximumPivots())
01243         forceFactorization_ = -1; //off
01244       return 1;
01245     } else {
01246       // carry on iterating
01247       return 0;
01248     }
01249   }
01250 }

int ClpSimplex::initialSolve ClpSolve options  ) 
 

General solve algorithm which can do presolve. See ClpSolve.hpp for options

Definition at line 53 of file ClpSolve.cpp.

References checkSolution(), Idiot::crash(), ClpModel::deleteColumns(), ClpModel::dualColumnSolution(), ClpModel::dualRowSolution(), dualTolerance_, Idiot::getDropEnoughFeasibility(), ClpSolve::getExtraInfo(), ClpPlusMinusOneMatrix::getIndices(), ClpModel::getNumElements(), ClpSolve::getPresolvePasses(), ClpSolve::getPresolveType(), ClpSolve::getSolveType(), ClpSolve::getSpecialOption(), Idiot::getStrategy(), ClpPackedMatrix::matrix(), ClpModel::maximumIterations(), CoinMessageHandler::message(), ClpModel::numberColumns_, ClpModel::numberIterations(), ClpModel::numberRows_, ClpModel::objectiveValue(), perturbation(), perturbation_, primal(), ClpModel::primalColumnSolution(), ClpInterior::primalDual(), ClpModel::primalRowSolution(), primalTolerance_, CoinMessageHandler::printing(), ClpModel::rowLower(), ClpModel::rowUpper(), scalingFlag_, ClpModel::setDblParam(), Idiot::setDropEnoughFeasibility(), Idiot::setDropEnoughWeighted(), Idiot::setLightweight(), ClpModel::setLogLevel(), setPerturbation(), Idiot::setReduceIterations(), Idiot::setStartingWeight(), Idiot::setStrategy(), solution(), and ClpModel::status().

00054 {
00055   ClpSolve::SolveType method=options.getSolveType();
00056   ClpSolve::PresolveType presolve = options.getPresolveType();
00057   int saveMaxIterations = maximumIterations();
00058   int finalStatus=-1;
00059   int numberIterations=0;
00060   double time1 = CoinCpuTime();
00061   double timeX = time1;
00062   double time2;
00063   ClpMatrixBase * saveMatrix=NULL;
00064   ClpSimplex * model2 = this;
00065   bool interrupt = (options.getSpecialOption(2)==0);
00066   CoinSighandler_t saveSignal=SIG_DFL;
00067   if (interrupt) {
00068     currentModel = model2;
00069     // register signal handler
00070     saveSignal = signal(SIGINT,signal_handler);
00071   }
00072   ClpPresolve pinfo;
00073   double timePresolve=0.0;
00074   double timeIdiot=0.0;
00075   double timeCore=0.0;
00076   int savePerturbation=perturbation_;
00077   int saveScaling = scalingFlag_;
00078   if (dynamic_cast< ClpNetworkMatrix*>(matrix_)) {
00079     // network - switch off stuff
00080     presolve = ClpSolve::presolveOff;
00081   }
00082   // For below >0 overrides
00083   // 0 means no, -1 means maybe
00084   int doIdiot=0;
00085   int doCrash=0;
00086   int doSprint=0;
00087   if (method!=ClpSolve::useDual) {
00088     switch (options.getSpecialOption(1)) {
00089     case 0:
00090       doIdiot=-1;
00091       doCrash=-1;
00092       doSprint=-1;
00093       break;
00094     case 1:
00095       doIdiot=0;
00096       doCrash=1;
00097       doSprint=0;
00098       break;
00099     case 2:
00100       doIdiot=1;
00101       doCrash=0;
00102       doSprint=0;
00103       break;
00104     case 3:
00105       doIdiot=0;
00106       doCrash=0;
00107       doSprint=1;
00108       break;
00109     case 4:
00110       doIdiot=0;
00111       doCrash=0;
00112       doSprint=0;
00113       break;
00114     case 5:
00115       doIdiot=0;
00116       doCrash=-1;
00117       doSprint=-1;
00118       break;
00119     case 6:
00120       doIdiot=-1;
00121       doCrash=-1;
00122       doSprint=0;
00123       break;
00124     case 7:
00125       doIdiot=-1;
00126       doCrash=0;
00127       doSprint=-1;
00128       break;
00129     case 8:
00130       doIdiot=-1;
00131       doCrash=0;
00132       doSprint=0;
00133       break;
00134     case 9:
00135       doIdiot=0;
00136       doCrash=0;
00137       doSprint=-1;
00138       break;
00139     default:
00140       abort();
00141     }
00142   } else {
00143     // Dual
00144     switch (options.getSpecialOption(0)) {
00145     case 0:
00146       doIdiot=0;
00147       doCrash=0;
00148       doSprint=0;
00149       break;
00150     case 1:
00151       doIdiot=0;
00152       doCrash=1;
00153       doSprint=0;
00154       break;
00155     case 2:
00156       doIdiot=-1;
00157       if (options.getExtraInfo(0)>0)
00158         doIdiot = options.getExtraInfo(0);
00159       doCrash=0;
00160       doSprint=0;
00161       break;
00162     default:
00163       abort();
00164     }
00165   }
00166   // Just do this number of passes in Sprint
00167   int maxSprintPass=100;
00168   // PreSolve to file - not fully tested
00169   bool presolveToFile=false;
00170 
00171   if (presolve!=ClpSolve::presolveOff) {
00172     int numberPasses=5;
00173     if (presolve==ClpSolve::presolveNumber) {
00174       numberPasses=options.getPresolvePasses();
00175       presolve = ClpSolve::presolveOn;
00176     }
00177     if (presolveToFile) {
00178       printf("***** temp test\n");
00179       pinfo.presolvedModelToFile(*this,"ss.sav",1.0e-8,
00180                            false,numberPasses);
00181       model2=this;
00182     } else {
00183       model2 = pinfo.presolvedModel(*this,1.0e-8,
00184                                     false,numberPasses,true);
00185     }
00186     time2 = CoinCpuTime();
00187     timePresolve = time2-timeX;
00188     handler_->message(CLP_INTERVAL_TIMING,messages_)
00189       <<"Presolve"<<timePresolve<<time2-time1
00190       <<CoinMessageEol;
00191     timeX=time2;
00192     if (model2) {
00193     } else {
00194       handler_->message(CLP_INFEASIBLE,messages_)
00195         <<CoinMessageEol;
00196       model2 = this;
00197       presolve=ClpSolve::presolveOff;
00198     }
00199     // We may be better off using original (but if dual leave because of bounds)
00200     if (presolve!=ClpSolve::presolveOff&&
00201         numberRows_<1.01*model2->numberRows_&&numberColumns_<1.01*model2->numberColumns_
00202         &&method!=ClpSolve::useDual&&model2!=this) {
00203       delete model2;
00204       model2 = this;
00205       presolve=ClpSolve::presolveOff;
00206     }
00207   }
00208   if (interrupt)
00209     currentModel = model2;
00210   // See if worth trying +- one matrix
00211   bool plusMinus=false;
00212   int numberElements=model2->getNumElements();
00213   if (dynamic_cast< ClpNetworkMatrix*>(matrix_)) {
00214     // network - switch off stuff
00215     doIdiot=0;
00216     doSprint=0;
00217   }
00218   int numberColumns = model2->numberColumns();
00219   int numberRows = model2->numberRows();
00220   // If not all slack basis - switch off all
00221   int number=0;
00222   int iRow;
00223   for (iRow=0;iRow<numberRows;iRow++)
00224     if (model2->getRowStatus(iRow)==basic)
00225       number++;
00226   if (number<numberRows) {
00227     doIdiot=0;
00228     doCrash=0;
00229     doSprint=0;
00230   }
00231   if (options.getSpecialOption(3)==0) {
00232     if(numberElements>100000)
00233       plusMinus=true;
00234     if(numberElements>10000&&(doIdiot||doSprint)) 
00235       plusMinus=true;
00236   }
00237   if (plusMinus) {
00238     saveMatrix = model2->clpMatrix();
00239     ClpPackedMatrix* clpMatrix =
00240       dynamic_cast< ClpPackedMatrix*>(saveMatrix);
00241     if (clpMatrix) {
00242       ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
00243       if (newMatrix->getIndices()) {
00244         model2->replaceMatrix(newMatrix);
00245       } else {
00246         handler_->message(CLP_MATRIX_CHANGE,messages_)
00247           <<"+- 1"
00248           <<CoinMessageEol;
00249         saveMatrix=NULL;
00250         plusMinus=false;
00251         delete newMatrix;
00252       }
00253     } else {
00254       saveMatrix=NULL;
00255       plusMinus=false;
00256     }
00257   }
00258   if (model2->factorizationFrequency()==200) {
00259     // User did not touch preset
00260     model2->setFactorizationFrequency(min(2000,100+model2->numberRows()/200));
00261   }
00262   if (method==ClpSolve::usePrimalorSprint) {
00263     if (doSprint<0) { 
00264       if (numberElements<500000) {
00265         // Small problem
00266         if(numberRows*10>numberColumns||numberColumns<6000
00267            ||(numberRows*20>numberColumns&&!plusMinus))
00268           method=ClpSolve::usePrimal; // switch off sprint
00269       } else {
00270         // larger problem
00271         if(numberRows*8>numberColumns)
00272           method=ClpSolve::usePrimal; // switch off sprint
00273         // but make lightweight
00274         if(numberRows*10>numberColumns||numberColumns<6000
00275            ||(numberRows*20>numberColumns&&!plusMinus))
00276           maxSprintPass=5;
00277       }
00278     } else if (doSprint==0) {
00279       method=ClpSolve::usePrimal; // switch off sprint
00280     }
00281   }
00282   if (method==ClpSolve::useDual) {
00283     // pick up number passes
00284     int nPasses=0;
00285     int numberNotE=0;
00286     if ((doIdiot<0&&plusMinus)||doIdiot>0) {
00287       // See if candidate for idiot
00288       nPasses=0;
00289       Idiot info(*model2);
00290       // Get average number of elements per column
00291       double ratio  = ((double) numberElements/(double) numberColumns);
00292       // look at rhs
00293       int iRow;
00294       double largest=0.0;
00295       double smallest = 1.0e30;
00296       double largestGap=0.0;
00297       for (iRow=0;iRow<numberRows;iRow++) {
00298         double value1 = model2->rowLower_[iRow];
00299         if (value1&&value1>-1.0e31) {
00300           largest = max(largest,fabs(value1));
00301           smallest=min(smallest,fabs(value1));
00302         }
00303         double value2 = model2->rowUpper_[iRow];
00304         if (value2&&value2<1.0e31) {
00305           largest = max(largest,fabs(value2));
00306           smallest=min(smallest,fabs(value2));
00307         }
00308         if (value2>value1) {
00309           numberNotE++;
00310           if (value2>1.0e31||value1<-1.0e31)
00311             largestGap = COIN_DBL_MAX;
00312           else
00313             largestGap = value2-value1;
00314         }
00315       }
00316       if (doIdiot<0) {
00317         if (numberRows>200&&numberColumns>5000&&ratio>=3.0&&
00318             largest/smallest<1.1&&!numberNotE) {
00319           nPasses = 71;
00320         }
00321       } 
00322       if (doIdiot>0) {
00323         nPasses=max(nPasses,doIdiot);
00324         if (nPasses>70) 
00325           info.setStartingWeight(1.0e3);
00326       }
00327       if (nPasses) {
00328         info.setReduceIterations(5);
00329         doCrash=0;
00330         info.crash(nPasses,model2->messageHandler(),model2->messagesPointer());
00331         time2 = CoinCpuTime();
00332         timeIdiot = time2-timeX;
00333         handler_->message(CLP_INTERVAL_TIMING,messages_)
00334           <<"Idiot Crash"<<timeIdiot<<time2-time1
00335           <<CoinMessageEol;
00336         timeX=time2;
00337       }
00338     }
00339     if (presolve==ClpSolve::presolveOn) {
00340       int numberInfeasibilities = model2->tightenPrimalBounds();
00341       if (numberInfeasibilities) {
00342         handler_->message(CLP_INFEASIBLE,messages_)
00343           <<CoinMessageEol;
00344         model2 = this;
00345         presolve=ClpSolve::presolveOff;
00346       }
00347     }
00348     if (options.getSpecialOption(0)==1)
00349       model2->crash(1000,1);
00350     if (!nPasses) {
00351       model2->dual(0);
00352     } else if (!numberNotE&&0) {
00353       // E so we can do in another way
00354       double * pi = model2->dualRowSolution();
00355       int i;
00356       int numberColumns = model2->numberColumns();
00357       int numberRows = model2->numberRows();
00358       double * saveObj = new double[numberColumns];
00359       memcpy(saveObj,model2->objective(),numberColumns*sizeof(double));
00360       memcpy(model2->dualColumnSolution(),model2->objective(),
00361              numberColumns*sizeof(double));
00362       model2->clpMatrix()->transposeTimes(-1.0,pi,model2->dualColumnSolution());
00363       memcpy(model2->objective(),model2->dualColumnSolution(),
00364              numberColumns*sizeof(double));
00365       const double * rowsol = model2->primalRowSolution();
00366       double offset=0.0;
00367       for (i=0;i<numberRows;i++) {
00368         offset += pi[i]*rowsol[i];
00369       }
00370       double value2;
00371       model2->getDblParam(ClpObjOffset,value2);
00372       printf("Offset %g %g\n",offset,value2);
00373       model2->setRowObjective(pi);
00374       // zero out pi
00375       memset(pi,0,numberRows*sizeof(double));
00376       // Could put some in basis - only partially tested
00377       model2->allSlackBasis(); 
00378       model2->factorization()->maximumPivots(200);
00379       //model2->setLogLevel(63);
00380       // solve
00381       model2->dual(1);
00382       memcpy(model2->objective(),saveObj,numberColumns*sizeof(double));
00383       // zero out pi
00384       memset(pi,0,numberRows*sizeof(double));
00385       model2->setRowObjective(pi);
00386       delete [] saveObj;
00387       model2->primal();
00388     } else {
00389       // solve
00390       model2->dual(1);
00391     }
00392     time2 = CoinCpuTime();
00393     timeCore = time2-timeX;
00394     handler_->message(CLP_INTERVAL_TIMING,messages_)
00395       <<"Dual"<<timeCore<<time2-time1
00396       <<CoinMessageEol;
00397     timeX=time2;
00398   } else if (method==ClpSolve::usePrimal) {
00399     if (doIdiot) {
00400       int nPasses=0;
00401       Idiot info(*model2);
00402       // Get average number of elements per column
00403       double ratio  = ((double) numberElements/(double) numberColumns);
00404       // look at rhs
00405       int iRow;
00406       double largest=0.0;
00407       double smallest = 1.0e30;
00408       double largestGap=0.0;
00409       int numberNotE=0;
00410       for (iRow=0;iRow<numberRows;iRow++) {
00411         double value1 = model2->rowLower_[iRow];
00412         if (value1&&value1>-1.0e31) {
00413           largest = max(largest,fabs(value1));
00414           smallest=min(smallest,fabs(value1));
00415         }
00416         double value2 = model2->rowUpper_[iRow];
00417         if (value2&&value2<1.0e31) {
00418           largest = max(largest,fabs(value2));
00419           smallest=min(smallest,fabs(value2));
00420         }
00421         if (value2>value1) {
00422           numberNotE++;
00423           if (value2>1.0e31||value1<-1.0e31)
00424             largestGap = COIN_DBL_MAX;
00425           else
00426             largestGap = value2-value1;
00427         }
00428       }
00429       if (numberRows>200&&numberColumns>5000&&numberColumns>2*numberRows) {
00430         if (plusMinus) {
00431           if (largest/smallest>2.0) {
00432             nPasses = 10+numberColumns/100000;
00433             nPasses = min(nPasses,50);
00434             nPasses = max(nPasses,15);
00435             if (numberRows>25000&&nPasses>5) {
00436               // Might as well go for it
00437               nPasses = max(nPasses,71);
00438             } else if (numberElements<3*numberColumns) {
00439               nPasses=min(nPasses,10); // probably not worh it
00440             }
00441             if (doIdiot<0)
00442               info.setLightweight(1); // say lightweight idiot
00443           } else if (largest/smallest>1.01||numberElements<=3*numberColumns) {
00444             nPasses = 10+numberColumns/1000;
00445             nPasses = min(nPasses,100);
00446             nPasses = max(nPasses,30);
00447             if (numberRows>25000) {
00448               // Might as well go for it
00449               nPasses = max(nPasses,71);
00450             }
00451             if (!largestGap)
00452               nPasses *= 2;
00453           } else {
00454             nPasses = 10+numberColumns/1000;
00455             nPasses = min(nPasses,200);
00456             nPasses = max(nPasses,100);
00457             info.setStartingWeight(1.0e-1);
00458             info.setReduceIterations(6);
00459             if (!largestGap)
00460               nPasses *= 2;
00461             //info.setFeasibilityTolerance(1.0e-7);
00462           }
00463           // If few passes - don't bother
00464           if (nPasses<=5)
00465             nPasses=0;
00466         } else {
00467           if (doIdiot<0)
00468             info.setLightweight(1); // say lightweight idiot
00469           if (largest/smallest>1.01||numberNotE) {
00470             if (numberRows>25000||numberColumns>5*numberRows) {
00471               nPasses = 50;
00472             } else if (numberColumns>4*numberRows) {
00473               nPasses = 20;
00474             } else {
00475               nPasses=5;
00476             }
00477           } else {
00478             if (numberRows>25000||numberColumns>5*numberRows) {
00479               nPasses = 50;
00480               info.setLightweight(0); // say not lightweight idiot
00481             } else if (numberColumns>4*numberRows) {
00482               nPasses = 20;
00483             } else {
00484               nPasses=15;
00485             }
00486           }
00487           if (numberElements<3*numberColumns) { 
00488             nPasses=(int) ((2.0*(double) nPasses)/ratio); // probably not worh it
00489           } else {
00490             nPasses = max(nPasses,5);
00491             nPasses = (int) (((double) nPasses)*5.0/ratio); // reduce if lots of elements per column
00492           }
00493           if (numberRows>25000&&nPasses>5) {
00494             // Might as well go for it
00495             nPasses = max(nPasses,71);
00496           } else if (plusMinus) {
00497             nPasses *= 2;
00498             nPasses=min(nPasses,71);
00499           }
00500           if (nPasses<=5)
00501             nPasses=0;
00502           //info.setStartingWeight(1.0e-1);
00503         }
00504       }
00505       if (doIdiot>0) {
00506         // pick up number passes
00507         nPasses=options.getExtraInfo(1);
00508         if (nPasses>70) {
00509           info.setStartingWeight(1.0e3);
00510           info.setReduceIterations(6);
00511           // also be more lenient on infeasibilities
00512           info.setDropEnoughFeasibility(0.5*info.getDropEnoughFeasibility());
00513           info.setDropEnoughWeighted(-2.0);
00514         } else if (nPasses>=50) {
00515           info.setStartingWeight(1.0e3);
00516           //info.setReduceIterations(6);
00517         } 
00518         // For experimenting
00519         if (nPasses<70&&(nPasses%10)>0&&(nPasses%10)<4) {
00520           info.setStartingWeight(1.0e3);
00521           info.setLightweight(nPasses%10); // special testing
00522           //info.setReduceIterations(6);
00523         }
00524       }
00525       if (nPasses) {
00526         doCrash=0;
00527 #if 0
00528         double * solution = model2->primalColumnSolution();
00529         int iColumn;
00530         double * saveLower = new double[numberColumns];
00531         memcpy(saveLower,model2->columnLower(),numberColumns*sizeof(double));
00532         double * saveUpper = new double[numberColumns];
00533         memcpy(saveUpper,model2->columnUpper(),numberColumns*sizeof(double));
00534         printf("doing tighten before idiot\n");
00535         model2->tightenPrimalBounds();
00536         // Move solution
00537         double * columnLower = model2->columnLower();
00538         double * columnUpper = model2->columnUpper();
00539         for (iColumn=0;iColumn<numberColumns;iColumn++) {
00540           if (columnLower[iColumn]>0.0)
00541             solution[iColumn]=columnLower[iColumn];
00542           else if (columnUpper[iColumn]<0.0)
00543             solution[iColumn]=columnUpper[iColumn];
00544           else
00545             solution[iColumn]=0.0;
00546         }
00547         memcpy(columnLower,saveLower,numberColumns*sizeof(double));
00548         memcpy(columnUpper,saveUpper,numberColumns*sizeof(double));
00549         delete [] saveLower;
00550         delete [] saveUpper;
00551 #else
00552         // Allow for crossover
00553         info.setStrategy(512|info.getStrategy());
00554         // Allow for scaling
00555         info.setStrategy(32|info.getStrategy());
00556         info.crash(nPasses,model2->messageHandler(),model2->messagesPointer());
00557 #endif
00558         time2 = CoinCpuTime();
00559         timeIdiot = time2-timeX;
00560         handler_->message(CLP_INTERVAL_TIMING,messages_)
00561           <<"Idiot Crash"<<timeIdiot<<time2-time1
00562           <<CoinMessageEol;
00563         timeX=time2;
00564       }
00565     }
00566     // ?
00567     if (doCrash)
00568       model2->crash(1000,1);
00569     model2->primal(1);
00570     time2 = CoinCpuTime();
00571     timeCore = time2-timeX;
00572     handler_->message(CLP_INTERVAL_TIMING,messages_)
00573       <<"Primal"<<timeCore<<time2-time1
00574       <<CoinMessageEol;
00575     timeX=time2;
00576   } else if (method==ClpSolve::usePrimalorSprint) {
00577     // Sprint
00578     /*
00579       This driver implements what I called Sprint when I introduced the idea
00580       many years ago.  Cplex calls it "sifting" which I think is just as silly.
00581       When I thought of this trivial idea
00582       it reminded me of an LP code of the 60's called sprint which after
00583       every factorization took a subset of the matrix into memory (all
00584       64K words!) and then iterated very fast on that subset.  On the
00585       problems of those days it did not work very well, but it worked very
00586       well on aircrew scheduling problems where there were very large numbers
00587       of columns all with the same flavor.
00588     */
00589     
00590     /* The idea works best if you can get feasible easily.  To make it
00591        more general we can add in costed slacks */
00592     
00593     int originalNumberColumns = model2->numberColumns();
00594     int numberRows = model2->numberRows();
00595     
00596     // We will need arrays to choose variables.  These are too big but ..
00597     double * weight = new double [numberRows+originalNumberColumns];
00598     int * sort = new int [numberRows+originalNumberColumns];
00599     int numberSort=0;
00600     // We are going to add slacks to get feasible.
00601     // initial list will just be artificials
00602     // first we will set all variables as close to zero as possible
00603     int iColumn;
00604     const double * columnLower = model2->columnLower();
00605     const double * columnUpper = model2->columnUpper();
00606     double * columnSolution = model2->primalColumnSolution();
00607     
00608     for (iColumn=0;iColumn<originalNumberColumns;iColumn++) {
00609       double value =0.0;
00610       if (columnLower[iColumn]>0.0)
00611         value = columnLower[iColumn];
00612       else if (columnUpper[iColumn]<0.0)
00613         value = columnUpper[iColumn];
00614       columnSolution[iColumn]=value;
00615     }
00616     // now see what that does to row solution
00617     double * rowSolution = model2->primalRowSolution();
00618     memset (rowSolution,0,numberRows*sizeof(double));
00619     model2->times(1.0,columnSolution,rowSolution);
00620     
00621     int * addStarts = new int [numberRows+1];
00622     int * addRow = new int[numberRows];
00623     double * addElement = new double[numberRows];
00624     const double * lower = model2->rowLower();
00625     const double * upper = model2->rowUpper();
00626     addStarts[0]=0;
00627     int numberArtificials=0;
00628     double * addCost = new double [numberRows];
00629     const double penalty=1.0e8;
00630     int iRow;
00631     for (iRow=0;iRow<numberRows;iRow++) {
00632       if (lower[iRow]>rowSolution[iRow]) {
00633         addRow[numberArtificials]=iRow;
00634         addElement[numberArtificials]=1.0;
00635         addCost[numberArtificials]=penalty;
00636         numberArtificials++;
00637         addStarts[numberArtificials]=numberArtificials;
00638       } else if (upper[iRow]<rowSolution[iRow]) {
00639         addRow[numberArtificials]=iRow;
00640         addElement[numberArtificials]=-1.0;
00641         addCost[numberArtificials]=penalty;
00642         numberArtificials++;
00643         addStarts[numberArtificials]=numberArtificials;
00644       }
00645     }
00646     model2->addColumns(numberArtificials,NULL,NULL,addCost,
00647                        addStarts,addRow,addElement);
00648     delete [] addStarts;
00649     delete [] addRow;
00650     delete [] addElement;
00651     delete [] addCost;
00652     // look at rhs to see if to perturb
00653     double largest=0.0;
00654     double smallest = 1.0e30;
00655     for (iRow=0;iRow<numberRows;iRow++) {
00656       double value;
00657       value = fabs(model2->rowLower_[iRow]);
00658       if (value&&value<1.0e30) {
00659         largest = max(largest,value);
00660         smallest=min(smallest,value);
00661       }
00662       value = fabs(model2->rowUpper_[iRow]);
00663       if (value&&value<1.0e30) {
00664         largest = max(largest,value);
00665         smallest=min(smallest,value);
00666       }
00667     }
00668     double * saveLower = NULL;
00669     double * saveUpper = NULL;
00670     if (largest<2.01*smallest) {
00671       // perturb - so switch off standard
00672       model2->setPerturbation(100);
00673       saveLower = new double[numberRows];
00674       memcpy(saveLower,model2->rowLower_,numberRows*sizeof(double));
00675       saveUpper = new double[numberRows];
00676       memcpy(saveUpper,model2->rowUpper_,numberRows*sizeof(double));
00677       double * lower = model2->rowLower();
00678       double * upper = model2->rowUpper();
00679       for (iRow=0;iRow<numberRows;iRow++) {
00680         double lowerValue=lower[iRow], upperValue=upper[iRow];
00681         double value = CoinDrand48();
00682         if (upperValue>lowerValue+primalTolerance_) {
00683           if (lowerValue>-1.0e20&&lowerValue)
00684             lowerValue -= value * 1.0e-4*fabs(lowerValue); 
00685           if (upperValue<1.0e20&&upperValue)
00686             upperValue += value * 1.0e-4*fabs(upperValue); 
00687         } else if (upperValue>0.0) {
00688           upperValue -= value * 1.0e-4*fabs(lowerValue); 
00689           lowerValue -= value * 1.0e-4*fabs(lowerValue); 
00690         } else if (upperValue<0.0) {
00691           upperValue += value * 1.0e-4*fabs(lowerValue); 
00692           lowerValue += value * 1.0e-4*fabs(lowerValue); 
00693         } else {
00694         }
00695         lower[iRow]=lowerValue;
00696         upper[iRow]=upperValue;
00697       }
00698     }
00699     int i;
00700     // Set up initial list
00701     if (numberArtificials) {
00702       numberSort=numberArtificials;
00703       for (i=0;i<numberSort;i++)
00704         sort[i] = i+originalNumberColumns;
00705     } else {
00706       numberSort = min(numberRows_,numberColumns_);
00707       for (i=0;i<numberSort;i++)
00708         sort[i] = i;
00709     }
00710     
00711     // redo as will have changed
00712     columnLower = model2->columnLower();
00713     columnUpper = model2->columnUpper();
00714     int numberColumns = model2->numberColumns();
00715     double * fullSolution = model2->primalColumnSolution();
00716     
00717     // Just do this number of passes in Sprint
00718     if (doSprint>0)
00719       maxSprintPass=options.getExtraInfo(1);
00720     int iPass;
00721     double lastObjective=1.0e31;
00722     // It will be safe to allow dense
00723     model2->setInitialDenseFactorization(true);
00724     
00725     // Just take this number of columns in small problem
00726     int smallNumberColumns = min(3*numberRows,numberColumns);
00727     smallNumberColumns = max(smallNumberColumns,3000);
00728     //int smallNumberColumns = min(12*numberRows/10,numberColumns);
00729     //smallNumberColumns = max(smallNumberColumns,3000);
00730     //smallNumberColumns = max(smallNumberColumns,numberRows+1000);
00731     // We will be using all rows
00732     int * whichRows = new int [numberRows];
00733     for (iRow=0;iRow<numberRows;iRow++)
00734       whichRows[iRow]=iRow;
00735     double originalOffset;
00736     model2->getDblParam(ClpObjOffset,originalOffset);
00737     int totalIterations=0;
00738     for (iPass=0;iPass<maxSprintPass;iPass++) {
00739       //printf("Bug until submodel new version\n");
00740       //CoinSort_2(sort,sort+numberSort,weight);
00741       // Create small problem
00742       ClpSimplex small(model2,numberRows,whichRows,numberSort,sort);
00743       small.setPerturbation(model2->perturbation());
00744       // now see what variables left out do to row solution
00745       double * rowSolution = model2->primalRowSolution();
00746       double * sumFixed = new double[numberRows];
00747       memset (sumFixed,0,numberRows*sizeof(double));
00748       int iRow,iColumn;
00749       // zero out ones in small problem
00750       for (iColumn=0;iColumn<numberSort;iColumn++) {
00751         int kColumn = sort[iColumn];
00752         fullSolution[kColumn]=0.0;
00753       }
00754       // Get objective offset
00755       double offset=0.0;
00756       const double * objective = model2->objective();
00757       for (iColumn=0;iColumn<numberColumns;iColumn++) 
00758         offset += fullSolution[iColumn]*objective[iColumn];
00759       small.setDblParam(ClpObjOffset,originalOffset-offset);
00760       model2->times(1.0,fullSolution,sumFixed);
00761       
00762       double * lower = small.rowLower();
00763       double * upper = small.rowUpper();
00764       for (iRow=0;iRow<numberRows;iRow++) {
00765         if (lower[iRow]>-1.0e50) 
00766           lower[iRow] -= sumFixed[iRow];
00767         if (upper[iRow]<1.0e50)
00768           upper[iRow] -= sumFixed[iRow];
00769         rowSolution[iRow] -= sumFixed[iRow];
00770       }
00771       delete [] sumFixed;
00772       // Solve 
00773       if (interrupt)
00774         currentModel = &small;
00775       small.primal();
00776       totalIterations += small.numberIterations();
00777       // move solution back
00778       const double * solution = small.primalColumnSolution();
00779       for (iColumn=0;iColumn<numberSort;iColumn++) {
00780         int kColumn = sort[iColumn];
00781         model2->setColumnStatus(kColumn,small.getColumnStatus(iColumn));
00782         fullSolution[kColumn]=solution[iColumn];
00783       }
00784       for (iRow=0;iRow<numberRows;iRow++) 
00785         model2->setRowStatus(iRow,small.getRowStatus(iRow));
00786       memcpy(model2->primalRowSolution(),small.primalRowSolution(),
00787              numberRows*sizeof(double));
00788       // get reduced cost for large problem
00789       memcpy(weight,model2->objective(),numberColumns*sizeof(double));
00790       model2->transposeTimes(-1.0,small.dualRowSolution(),weight);
00791       int numberNegative=0;
00792       double sumNegative = 0.0;
00793       // now massage weight so all basic in plus good djs
00794       for (iColumn=0;iColumn<numberColumns;iColumn++) {
00795         double dj = weight[iColumn]*optimizationDirection_;
00796         double value = fullSolution[iColumn];
00797         if (model2->getColumnStatus(iColumn)==ClpSimplex::basic) 
00798           dj = -1.0e50;
00799         else if (dj<0.0&&value<columnUpper[iColumn])
00800           dj = dj;
00801         else if (dj>0.0&&value>columnLower[iColumn])
00802           dj = -dj;
00803         else if (columnUpper[iColumn]>columnLower[iColumn])
00804           dj = fabs(dj);
00805         else
00806           dj = 1.0e50;
00807         weight[iColumn] = dj;
00808         if (dj<-dualTolerance_&&dj>-1.0e50) {
00809           numberNegative++;
00810           sumNegative -= dj;
00811         }
00812         sort[iColumn] = iColumn;
00813       }
00814       handler_->message(CLP_SPRINT,messages_)
00815         <<iPass+1<<small.numberIterations()<<small.objectiveValue()<<sumNegative
00816         <<numberNegative
00817         <<CoinMessageEol;
00818       if ((small.objectiveValue()*optimizationDirection_>lastObjective-1.0e-7&&iPass>5)||
00819           !small.numberIterations()||
00820           iPass==maxSprintPass-1||small.status()==3) {
00821         
00822         break; // finished
00823       } else {
00824         lastObjective = small.objectiveValue()*optimizationDirection_;
00825         // sort
00826         CoinSort_2(weight,weight+numberColumns,sort);
00827         numberSort = smallNumberColumns;
00828       }
00829     }
00830     if (interrupt) 
00831       currentModel = model2;
00832     for (i=0;i<numberArtificials;i++)
00833       sort[i] = i + originalNumberColumns;
00834     model2->deleteColumns(numberArtificials,sort);
00835     delete [] weight;
00836     delete [] sort;
00837     delete [] whichRows;
00838     if (saveLower) {
00839       // unperturb and clean
00840       for (iRow=0;iRow<numberRows;iRow++) {
00841         double diffLower = saveLower[iRow]-model2->rowLower_[iRow];
00842         double diffUpper = saveUpper[iRow]-model2->rowUpper_[iRow];
00843         model2->rowLower_[iRow]=saveLower[iRow];
00844         model2->rowUpper_[iRow]=saveUpper[iRow];
00845         if (diffLower) 
00846           assert (!diffUpper||fabs(diffLower-diffUpper)<1.0e-5);
00847         else
00848           diffLower = diffUpper;
00849         model2->rowActivity_[iRow] += diffLower;
00850       }
00851       delete [] saveLower;
00852       delete [] saveUpper;
00853     }
00854     model2->primal(0);
00855     model2->setPerturbation(savePerturbation);
00856     time2 = CoinCpuTime();
00857     timeCore = time2-timeX;
00858     handler_->message(CLP_INTERVAL_TIMING,messages_)
00859       <<"Sprint"<<timeCore<<time2-time1
00860       <<CoinMessageEol;
00861     timeX=time2;
00862     model2->setNumberIterations(model2->numberIterations()+totalIterations);
00863   } else if (method==ClpSolve::useBarrier) {
00864     printf("***** experimental pretty crude barrier\n");
00865     ClpInterior barrier(*model2);
00866     barrier.primalDual();
00867     time2 = CoinCpuTime();
00868     timeCore = time2-timeX;
00869     handler_->message(CLP_INTERVAL_TIMING,messages_)
00870       <<"Barrier"<<timeCore<<time2-time1
00871       <<CoinMessageEol;
00872     timeX=time2;
00873     printf("***** crude crossover - I will improve\n");
00874     // move solutions
00875     CoinMemcpyN(barrier.primalRowSolution(),
00876                 model2->numberRows(),model2->primalRowSolution());
00877     CoinMemcpyN(barrier.dualRowSolution(),
00878                 model2->numberRows(),model2->dualRowSolution());
00879     CoinMemcpyN(barrier.primalColumnSolution(),
00880                 model2->numberColumns(),model2->primalColumnSolution());
00881     CoinMemcpyN(barrier.dualColumnSolution(),
00882                 model2->numberColumns(),model2->dualColumnSolution());
00883     // make sure no status left
00884     model2->createStatus();
00885     // solve
00886     model2->setPerturbation(100);
00887     model2->primal(1);
00888     model2->setPerturbation(savePerturbation);
00889     time2 = CoinCpuTime();
00890     timeCore = time2-timeX;
00891     handler_->message(CLP_INTERVAL_TIMING,messages_)
00892       <<"Crossover"<<timeCore<<time2-time1
00893       <<CoinMessageEol;
00894     timeX=time2;
00895   } else {
00896     assert (method!=ClpSolve::automatic); // later
00897     time2=0.0;
00898   }
00899   if (saveMatrix) {
00900     // delete and replace
00901     delete model2->clpMatrix();
00902     model2->replaceMatrix(saveMatrix);
00903   }
00904   numberIterations = model2->numberIterations();
00905   finalStatus=model2->status();
00906   if (presolve==ClpSolve::presolveOn) {
00907     int saveLevel = logLevel();
00908     setLogLevel(1);
00909     pinfo.postsolve(true);
00910     time2 = CoinCpuTime();
00911     timePresolve += time2-timeX;
00912     handler_->message(CLP_INTERVAL_TIMING,messages_)
00913       <<"Postsolve"<<time2-timeX<<time2-time1
00914       <<CoinMessageEol;
00915     timeX=time2;
00916     if (!presolveToFile)
00917       delete model2;
00918     if (interrupt)
00919       currentModel = this;
00920     checkSolution();
00921     setLogLevel(saveLevel);
00922     if (finalStatus!=3&&(finalStatus||status()==-1)) {
00923       int savePerturbation = perturbation();
00924       setPerturbation(100);
00925       primal(1);
00926       setPerturbation(savePerturbation);
00927       numberIterations += this->numberIterations();
00928       finalStatus=status();
00929       time2 = CoinCpuTime();
00930       handler_->message(CLP_INTERVAL_TIMING,messages_)
00931       <<"Cleanup"<<time2-timeX<<time2-time1
00932       <<CoinMessageEol;
00933       timeX=time2;
00934     }
00935   }
00936   setMaximumIterations(saveMaxIterations);
00937   std::string statusMessage[]={"Unknown","Optimal","PrimalInfeasible","DualInfeasible","Stopped"};
00938   assert (finalStatus>=-1&&finalStatus<=3);
00939   handler_->message(CLP_TIMING,messages_)
00940     <<statusMessage[finalStatus+1]<<objectiveValue()<<numberIterations<<time2-time1;
00941   handler_->printing(presolve==ClpSolve::presolveOn)
00942     <<timePresolve;
00943   handler_->printing(timeIdiot)
00944     <<timeIdiot;
00945   handler_->message()<<CoinMessageEol;
00946   if (interrupt) 
00947     signal(SIGINT,saveSignal);
00948   perturbation_=savePerturbation;
00949   scalingFlag_=saveScaling;
00950   return finalStatus;
00951 }

void ClpSimplex::loadProblem const int  numcols,
const int  numrows,
const CoinBigIndex *  start,
const int *  index,
const double *  value,
const double *  collb,
const double *  colub,
const double *  obj,
const double *  rowlb,
const double *  rowub,
const double *  rowObjective = NULL
 

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

Reimplemented from ClpModel.

Definition at line 3634 of file ClpSimplex.cpp.

References createStatus(), and ClpModel::loadProblem().

03641 {
03642   ClpModel::loadProblem(numcols, numrows, start, index, value,
03643                           collb, colub, obj, rowlb, rowub,
03644                           rowObjective);
03645   createStatus();
03646 }

void ClpSimplex::loadProblem const ClpMatrixBase matrix,
const double *  collb,
const double *  colub,
const double *  obj,
const double *  rowlb,
const double *  rowub,
const double *  rowObjective = NULL
 

Loads a problem (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

Reimplemented from ClpModel.

Definition at line 3609 of file ClpSimplex.cpp.

References createStatus(), and ClpModel::loadProblem().

Referenced by ClpSimplexPrimalQuadratic::makeQuadratic().

03614 {
03615   ClpModel::loadProblem(matrix, collb, colub, obj, rowlb, rowub,
03616                         rowObjective);
03617   createStatus();
03618 }

void ClpSimplex::originalModel ClpSimplex miniModel  ) 
 

This copies back stuff from miniModel and then deletes miniModel. Only to be used with mini constructor

Definition at line 5152 of file ClpSimplex.cpp.

References ClpNonLinearCost::checkInfeasibilities(), columnActivityWork_, columnLowerWork_, columnScale_, columnUpperWork_, cost_, dj_, ClpModel::getDblParam(), getStatus(), lower_, ClpModel::matrix_, nonLinearCost_, ClpModel::numberColumns_, ClpNonLinearCost::numberInfeasibilities(), ClpModel::numberRows_, objectiveWork_, pivotVariable_, primalColumnPivot_, reducedCostWork_, rowActivityWork_, ClpModel::rowCopy_, rowLowerWork_, rowObjectiveWork_, rowReducedCost_, rowScale_, ClpModel::rowUpper_, rowUpperWork_, savedSolution_, saveStatus_, ClpPrimalColumnPivot::saveWeights(), ClpModel::setDblParam(), solution_, ClpModel::status_, ClpNonLinearCost::sumInfeasibilities(), ClpMatrixBase::times(), and upper_.

Referenced by ClpSimplexPrimal::primal().

05153 {
05154   int numberSmall = numberColumns_;
05155   numberColumns_ = miniModel->numberColumns_;
05156   int numberTotal = numberSmall+numberRows_;
05157   // copy back
05158   int iColumn;
05159   int * mapping = (int *) miniModel->rowUpper_;
05160 #ifdef CLP_DEBUG
05161   for (iColumn=0;iColumn<numberRows_+numberColumns_;iColumn++) 
05162     printf("mapb %d %d\n",iColumn,mapping[iColumn]);
05163 #endif
05164   // miniModel actually has full arrays
05165   // now see what variables left out do to row solution
05166   double * fullSolution = miniModel->solution_;
05167   double * sumFixed = new double[numberRows_];
05168   memset (sumFixed,0,numberRows_*sizeof(double));
05169   miniModel->matrix_->times(1.0,fullSolution,sumFixed,rowScale_,miniModel->columnScale_);
05170       
05171   for (iColumn=0;iColumn<numberTotal;iColumn++) {
05172     int jColumn = mapping[iColumn];
05173     miniModel->lower_[jColumn]=lower_[iColumn];
05174     miniModel->upper_[jColumn]=upper_[iColumn];
05175     miniModel->cost_[jColumn]=cost_[iColumn];
05176     miniModel->dj_[jColumn]=dj_[iColumn];
05177     miniModel->solution_[jColumn]=solution_[iColumn];
05178     miniModel->status_[jColumn]=status_[iColumn];
05179 #ifdef CLP_DEBUG
05180     printf("%d in small -> %d in original\n",iColumn,jColumn);
05181 #endif
05182   }
05183   delete [] lower_;
05184   lower_ =  miniModel->lower_;
05185   delete [] upper_;
05186   upper_ =  miniModel->upper_;
05187   delete [] cost_;
05188   cost_ =  miniModel->cost_;
05189   delete [] dj_;
05190   dj_ =  miniModel->dj_;
05191   delete [] solution_;
05192   solution_ =  miniModel->solution_;
05193   delete [] status_;
05194   status_ =  miniModel->status_;
05195   if (columnScale_) {
05196     for (iColumn=0;iColumn<numberSmall;iColumn++) {
05197       int jColumn = mapping[iColumn];
05198       miniModel->columnScale_[jColumn]=columnScale_[iColumn];
05199     }
05200     delete [] columnScale_;
05201     columnScale_ =  miniModel->columnScale_;
05202   }
05203   if (savedSolution_) {
05204     if (!miniModel->savedSolution_) {
05205       miniModel->savedSolution_ = ClpCopyOfArray(solution_,numberColumns_+numberRows_);
05206     } else {
05207       for (iColumn=0;iColumn<numberTotal;iColumn++) {
05208         int jColumn = mapping[iColumn];
05209         miniModel->savedSolution_[jColumn]=savedSolution_[iColumn];
05210       }
05211     }
05212     delete [] savedSolution_;
05213     savedSolution_ =  miniModel->savedSolution_;
05214   }
05215   if (saveStatus_) {
05216     if (!miniModel->saveStatus_) {
05217       miniModel->saveStatus_ = ClpCopyOfArray(status_,numberColumns_+numberRows_);
05218     } else {
05219       for (iColumn=0;iColumn<numberTotal;iColumn++) {
05220         int jColumn = mapping[iColumn];
05221         miniModel->saveStatus_[jColumn]=saveStatus_[iColumn];
05222       }
05223     }
05224     delete [] saveStatus_;
05225     saveStatus_ =  miniModel->saveStatus_;
05226   }
05227   // Re-define pivotVariable_
05228   int iRow;
05229   for (iRow=0;iRow<numberRows_;iRow++) {
05230     int iPivot = pivotVariable_[iRow];
05231 #ifdef CLP_DEBUG
05232     printf("pb row %d, pivot %d -> %d\n",iRow,iPivot,mapping[iPivot]);
05233 #endif
05234     pivotVariable_[iRow]=mapping[iPivot];
05235     assert (pivotVariable_[iRow]>=0);
05236   }
05237   // delete stuff and move back
05238   delete matrix_;
05239   delete rowCopy_;
05240   delete primalColumnPivot_;
05241   delete nonLinearCost_;
05242   matrix_ = miniModel->matrix_;
05243   rowCopy_ = miniModel->rowCopy_;
05244   nonLinearCost_ = miniModel->nonLinearCost_;
05245   double originalOffset;
05246   miniModel->getDblParam(ClpObjOffset,originalOffset);
05247   setDblParam(ClpObjOffset,originalOffset);
05248   // Redo some stuff
05249   reducedCostWork_ = dj_;
05250   rowReducedCost_ = dj_+numberColumns_;
05251   columnActivityWork_ = solution_;
05252   rowActivityWork_ = solution_+numberColumns_;
05253   objectiveWork_ = cost_;
05254   rowObjectiveWork_ = cost_+numberColumns_;
05255   rowLowerWork_ = lower_+numberColumns_;
05256   columnLowerWork_ = lower_;
05257   rowUpperWork_ = upper_+numberColumns_;
05258   columnUpperWork_ = upper_;
05259   // Cleanup
05260   for (iRow=0;iRow<numberRows_;iRow++) {
05261     double value = rowActivityWork_[iRow] + sumFixed[iRow];
05262     rowActivityWork_[iRow] = value;
05263     switch(getRowStatus(iRow)) {
05264       
05265     case basic:
05266       break;
05267     case atUpperBound:
05268       //rowActivityWork_[iRow]=rowUpperWork_[iRow];
05269       break;
05270     case ClpSimplex::isFixed:
05271     case atLowerBound:
05272       //rowActivityWork_[iRow]=rowLowerWork_[iRow];
05273       break;
05274     case isFree:
05275       break;
05276       // superbasic
05277     case superBasic:
05278       break;
05279     }
05280   }
05281   delete [] sumFixed;
05282   nonLinearCost_->checkInfeasibilities();
05283   printf("in original %d infeasibilities summing to %g\n",
05284          nonLinearCost_->numberInfeasibilities(),nonLinearCost_->sumInfeasibilities());
05285   // Initialize weights
05286   primalColumnPivot_ = new ClpPrimalColumnSteepest(10);
05287   primalColumnPivot_->saveWeights(this,2);
05288 #ifndef NDEBUG
05289   // Check status
05290   ClpSimplex * xxxx = this;
05291   int nBasic=0;
05292   for (iColumn=0;iColumn<xxxx->numberRows_+xxxx->numberColumns_;iColumn++)
05293     if (xxxx->getStatus(iColumn)==basic)
05294       nBasic++;
05295   assert (nBasic==xxxx->numberRows_);
05296   for (iRow=0;iRow<xxxx->numberRows_;iRow++) {
05297     int iPivot=xxxx->pivotVariable_[iRow];
05298     assert (xxxx->getStatus(iPivot)==basic);
05299   }
05300 #endif
05301 }

int ClpSimplex::perturbation  )  const [inline]
 

Perturbation: 50 - switch on perturbation 100 - auto perturb if takes too long (1.0e-6 largest nonzero) 101 - we are perturbed 102 - don't try perturbing again default is 100 others are for playing

Definition at line 301 of file ClpSimplex.hpp.

References perturbation_.

Referenced by initialSolve(), and ClpItem::intParameter().

00302     { return perturbation_;};

int ClpSimplex::pivot  ) 
 

Pivot in a variable and out a variable. Returns 0 if okay, 1 if inaccuracy forced re-factorization, -1 if would be singular. Also updates primal/dual infeasibilities. Assumes sequenceIn_ and pivotRow_ set and also directionIn and Out.

Definition at line 4153 of file ClpSimplex.cpp.

References algorithm_, alpha_, CoinIndexedVector::clear(), columnArray_, CoinIndexedVector::denseVector(), directionIn_, directionOut_, dj_, dualIn_, dualOut_, factorization_, CoinIndexedVector::getIndices(), gutsOfSolution(), housekeeping(), lastGoodIteration_, lower_, lowerIn_, lowerOut_, pivotRow_, pivotVariable_, rowArray_, scalingFlag_, sequenceIn_, sequenceOut_, solution_, statusOfProblem(), ClpMatrixBase::transposeTimes(), unpack(), upper_, upperIn_, upperOut_, valueIn_, and valueOut_.

04154 {
04155   // scaling not allowed
04156   assert (!scalingFlag_);
04157   // assume In_ and Out_ are correct and directionOut_ set
04158   // (or In_ if flip
04159   lowerIn_ = lower_[sequenceIn_];
04160   valueIn_ = solution_[sequenceIn_];
04161   upperIn_ = upper_[sequenceIn_];
04162   dualIn_ = dj_[sequenceIn_];
04163   if (sequenceOut_>=0&&sequenceIn_!=sequenceIn_) {
04164     assert (pivotRow_>=0&&pivotRow_<numberRows_);
04165     assert (pivotVariable_[pivotRow_]==sequenceOut_);
04166     lowerOut_ = lower_[sequenceOut_];
04167     valueOut_ = solution_[sequenceOut_];
04168     upperOut_ = upper_[sequenceOut_];
04169     // for now assume primal is feasible (or in dual)
04170     dualOut_ = dj_[sequenceOut_];
04171     assert(fabs(dualOut_)<1.0e-6);
04172   } else {
04173     assert (pivotRow_<0);
04174   }
04175   bool roundAgain = true;
04176   int returnCode=0;
04177   while (roundAgain) {
04178     roundAgain=false;
04179     unpack(rowArray_[1]);
04180     factorization_->updateColumnFT(rowArray_[2],rowArray_[1]);
04181     // we are going to subtract movement from current basic
04182     double movement;
04183     // see where incoming will go to
04184     if (sequenceOut_<0||sequenceIn_==sequenceOut_) {
04185       // flip so go to bound
04186       movement  = ((directionIn_>0) ? upperIn_ : lowerIn_) - valueIn_;
04187     } else {
04188       // get where outgoing needs to get to
04189       double outValue = (directionOut_>0) ? upperOut_ : lowerOut_;
04190       // solutionOut_ - movement*alpha_ == outValue
04191       movement = (outValue-valueOut_)/alpha_;
04192       // set directionIn_ correctly
04193       directionIn_ = (movement>0) ? 1 :-1;
04194     }
04195     // update primal solution
04196     {
04197       int i;
04198       int * index = rowArray_[1]->getIndices();
04199       int number = rowArray_[1]->getNumElements();
04200       double * element = rowArray_[1]->denseVector();
04201       for (i=0;i<number;i++) {
04202         int ii = index[i];
04203         // get column
04204         ii = pivotVariable_[ii];
04205         solution_[ii] -= movement*element[i];
04206         element[i]=0.0;
04207       }
04208       // see where something went to
04209       if (sequenceOut_<0) {
04210         if (directionIn_<0) {
04211           assert (fabs(solution_[sequenceIn_]-upperIn_)<1.0e-7);
04212           solution_[sequenceIn_]=upperIn_;
04213         } else {
04214           assert (fabs(solution_[sequenceIn_]-lowerIn_)<1.0e-7);
04215           solution_[sequenceIn_]=lowerIn_;
04216         }
04217       } else {
04218         if (directionOut_<0) {
04219           assert (fabs(solution_[sequenceOut_]-upperOut_)<1.0e-7);
04220           solution_[sequenceOut_]=upperOut_;
04221         } else {
04222           assert (fabs(solution_[sequenceOut_]-lowerOut_)<1.0e-7);
04223           solution_[sequenceOut_]=lowerOut_;
04224         }
04225         solution_[sequenceIn_]=valueIn_+movement;
04226       }
04227     }    
04228     double objectiveChange = dualIn_*movement;
04229     // update duals
04230     if (pivotRow_>=0) {
04231       alpha_ = rowArray_[1]->denseVector()[pivotRow_];
04232       assert (fabs(alpha_)>1.0e-8);
04233       double multiplier = dualIn_/alpha_;
04234       rowArray_[0]->insert(pivotRow_,multiplier);
04235       factorization_->updateColumnTranspose(rowArray_[2],rowArray_[0]);
04236       // put row of tableau in rowArray[0] and columnArray[0]
04237       matrix_->transposeTimes(this,-1.0,
04238                               rowArray_[0],columnArray_[1],columnArray_[0]);
04239       // update column djs
04240       int i;
04241       int * index = columnArray_[0]->getIndices();
04242       int number = columnArray_[0]->getNumElements();
04243       double * element = columnArray_[0]->denseVector();
04244       for (i=0;i<number;i++) {
04245         int ii = index[i];
04246         dj_[ii] += element[ii];
04247         element[ii]=0.0;
04248       }
04249       columnArray_[0]->setNumElements(0);
04250       // and row djs
04251       index = rowArray_[0]->getIndices();
04252       number = rowArray_[0]->getNumElements();
04253       element = rowArray_[0]->denseVector();
04254       for (i=0;i<number;i++) {
04255         int ii = index[i];
04256         dj_[ii+numberColumns_] += element[ii];
04257         dual_[ii] = dj_[ii+numberColumns_];
04258         element[ii]=0.0;
04259       }
04260       rowArray_[0]->setNumElements(0);
04261       // check incoming
04262       assert (fabs(dj_[sequenceIn_])<1.0e-6);
04263     }
04264     
04265     // if stable replace in basis
04266     int updateStatus = factorization_->replaceColumn(rowArray_[2],
04267                                                    pivotRow_,
04268                                                      alpha_);
04269     bool takePivot=true;
04270     // if no pivots, bad update but reasonable alpha - take and invert
04271     if (updateStatus==2&&
04272         lastGoodIteration_==numberIterations_&&fabs(alpha_)>1.0e-5)
04273       updateStatus=4;
04274     if (updateStatus==1||updateStatus==4) {
04275       // slight error
04276       if (factorization_->pivots()>5||updateStatus==4) {
04277         returnCode=-1;
04278       }
04279     } else if (updateStatus==2) {
04280       // major error
04281       rowArray_[1]->clear();
04282       takePivot=false;
04283       if (factorization_->pivots()) {
04284         // refactorize here
04285         statusOfProblem();
04286         roundAgain=true;
04287       } else {
04288         returnCode=1;
04289       }
04290     } else if (updateStatus==3) {
04291       // out of memory
04292       // increase space if not many iterations
04293       if (factorization_->pivots()<
04294           0.5*factorization_->maximumPivots()&&
04295           factorization_->pivots()<200)
04296         factorization_->areaFactor(
04297                                    factorization_->areaFactor() * 1.1);
04298       returnCode =-1; // factorize now
04299     }
04300     if (takePivot) {
04301       int save = algorithm_;
04302       // make simple so always primal
04303       algorithm_=1;
04304       housekeeping(objectiveChange);
04305       algorithm_=save;
04306     }
04307   }
04308   if (returnCode == -1) {
04309     // refactorize here
04310     statusOfProblem();
04311   } else {
04312     // just for now - recompute anyway
04313     gutsOfSolution(NULL,NULL);
04314   }
04315   return returnCode;
04316 }

int ClpSimplex::primal int  ifValuesPass = 0  ) 
 

Primal algorithm - see ClpSimplexPrimal.hpp for method

Reimplemented in ClpSimplexPrimal.

Definition at line 2900 of file ClpSimplex.cpp.

References perturbation_, and setInitialDenseFactorization().

Referenced by initialSolve().

02901 {
02902   assert (ifValuesPass>=0&&ifValuesPass<2);
02903   int returnCode = ((ClpSimplexPrimal *) this)->primal(ifValuesPass);
02904   if (problemStatus_==10) {
02905     //printf("Cleaning up with dual\n");
02906     int savePerturbation = perturbation_;
02907     perturbation_=100;
02908     bool denseFactorization = initialDenseFactorization();
02909     // It will be safe to allow dense
02910     setInitialDenseFactorization(true);
02911     returnCode = ((ClpSimplexDual *) this)->dual(0);
02912     setInitialDenseFactorization(denseFactorization);
02913     perturbation_=savePerturbation;
02914     if (problemStatus_==10) 
02915       problemStatus_=0;
02916   }
02917   return returnCode;
02918 }

int ClpSimplex::primalPivotResult  ) 
 

Pivot in a variable and choose an outgoing one. Assumes primal feasible - will not go through a bound. Returns step length in theta Returns ray in ray_ (or NULL if no pivot) Return codes as before but -1 means no acceptable pivot

Definition at line 4323 of file ClpSimplex.cpp.

References dj_, dualIn_, lower_, lowerIn_, sequenceIn_, solution_, upper_, upperIn_, and valueIn_.

04324 {
04325   assert (sequenceIn_>=0);
04326   valueIn_=solution_[sequenceIn_];
04327   lowerIn_=lower_[sequenceIn_];
04328   upperIn_=upper_[sequenceIn_];
04329   dualIn_=dj_[sequenceIn_];
04330 
04331   int returnCode = ((ClpSimplexPrimal *) this)->pivotResult();
04332   if (returnCode<0&&returnCode>-4) {
04333     return 0;
04334   } else {
04335     printf("Return code of %d from ClpSimplexPrimal::pivotResult\n",
04336            returnCode);
04337     return -1;
04338   }
04339 }

int ClpSimplex::quadraticSLP int  numberPasses,
double  deltaTolerance
 

Solves quadratic problem using SLP - may be used as crash for other algorithms when number of iterations small. Also exits if all problematical variables are changing less than deltaTolerance

Definition at line 2924 of file ClpSimplex.cpp.

02925 {
02926   return ((ClpSimplexPrimalQuadratic *) this)->primalSLP(numberPasses,deltaTolerance);
02927 }

int ClpSimplex::restoreModel const char *  fileName  ) 
 

Restore model from file, returns 0 if success, deletes current model

Definition at line 3197 of file ClpSimplex.cpp.

References algorithm_, columnArray_, dualBound_, dualRowPivot_, dualTolerance_, factorization_, ClpModel::gutsOfDelete(), infeasibilityCost_, numberDualInfeasibilities_, numberDualInfeasibilitiesWithoutFree_, numberPrimalInfeasibilities_, numberRefinements_, primalColumnPivot_, primalTolerance_, rowArray_, scalingFlag_, specialOptions_, sumDualInfeasibilities_, and sumPrimalInfeasibilities_.

03198 {
03199   FILE * fp = fopen(fileName,"rb");
03200   if (fp) {
03201     // Get rid of current model
03202     ClpModel::gutsOfDelete();
03203     gutsOfDelete(0);
03204     int i;
03205     for (i=0;i<6;i++) {
03206       rowArray_[i]=NULL;
03207       columnArray_[i]=NULL;
03208     }
03209     // get an empty factorization so we can set tolerances etc
03210     factorization_ = new ClpFactorization();
03211     // Say sparse
03212     factorization_->sparseThreshold(1);
03213     Clp_scalars scalars;
03214     CoinBigIndex numberRead;
03215 
03216     // get scalars
03217     numberRead = fread(&scalars,sizeof(Clp_scalars),1,fp);
03218     if (numberRead!=1)
03219       return 1;
03220     // Fill in scalars
03221     optimizationDirection_ = scalars.optimizationDirection;
03222     memcpy(dblParam_, scalars.dblParam, ClpLastDblParam * sizeof(double));
03223     objectiveValue_ = scalars.objectiveValue;
03224     dualBound_ = scalars.dualBound;
03225     dualTolerance_ = scalars.dualTolerance;
03226     primalTolerance_ = scalars.primalTolerance;
03227     sumDualInfeasibilities_ = scalars.sumDualInfeasibilities;
03228     sumPrimalInfeasibilities_ = scalars.sumPrimalInfeasibilities;
03229     infeasibilityCost_ = scalars.infeasibilityCost;
03230     numberRows_ = scalars.numberRows;
03231     numberColumns_ = scalars.numberColumns;
03232     memcpy(intParam_, scalars.intParam,ClpLastIntParam * sizeof(double));
03233     numberIterations_ = scalars.numberIterations;
03234     problemStatus_ = scalars.problemStatus;
03235     setMaximumIterations(scalars.maximumIterations);
03236     lengthNames_ = scalars.lengthNames;
03237     numberDualInfeasibilities_ = scalars.numberDualInfeasibilities;
03238     numberDualInfeasibilitiesWithoutFree_ 
03239       = scalars.numberDualInfeasibilitiesWithoutFree;
03240     numberPrimalInfeasibilities_ = scalars.numberPrimalInfeasibilities;
03241     numberRefinements_ = scalars.numberRefinements;
03242     scalingFlag_ = scalars.scalingFlag;
03243     algorithm_ = scalars.algorithm;
03244     specialOptions_ = scalars.specialOptions;
03245     // strings
03246     CoinBigIndex length;
03247     for (i=0;i<ClpLastStrParam;i++) {
03248       numberRead = fread(&length,sizeof(int),1,fp);
03249       if (numberRead!=1)
03250         return 1;
03251       if (length) {
03252         char * array = new char[length+1];
03253         numberRead = fread(array,length,1,fp);
03254         if (numberRead!=1)
03255           return 1;
03256         array[length]='\0';
03257         strParam_[i]=array;
03258         delete [] array;
03259       }
03260     }
03261     // arrays - in no particular order
03262     if (inDoubleArray(rowActivity_,numberRows_,fp))
03263         return 1;
03264     if (inDoubleArray(columnActivity_,numberColumns_,fp))
03265         return 1;
03266     if (inDoubleArray(dual_,numberRows_,fp))
03267         return 1;
03268     if (inDoubleArray(reducedCost_,numberColumns_,fp))
03269         return 1;
03270     if (inDoubleArray(rowLower_,numberRows_,fp))
03271         return 1;
03272     if (inDoubleArray(rowUpper_,numberRows_,fp))
03273         return 1;
03274     double * objective;
03275     if (inDoubleArray(objective,numberColumns_,fp))
03276         return 1;
03277     delete objective_;
03278     objective_ = new ClpLinearObjective(objective,numberColumns_);
03279     delete [] objective;
03280     if (inDoubleArray(rowObjective_,numberRows_,fp))
03281         return 1;
03282     if (inDoubleArray(columnLower_,numberColumns_,fp))
03283         return 1;
03284     if (inDoubleArray(columnUpper_,numberColumns_,fp))
03285         return 1;
03286     if (problemStatus_==1) {
03287       if (inDoubleArray(ray_,numberRows_,fp))
03288         return 1;
03289     } else if (problemStatus_==2) {
03290       if (inDoubleArray(ray_,numberColumns_,fp))
03291         return 1;
03292     } else {
03293       // ray should be null
03294       numberRead = fread(&length,sizeof(int),1,fp);
03295       if (numberRead!=1)
03296         return 1;
03297       if (length)
03298         return 2;
03299     }
03300     delete [] status_;
03301     status_=NULL;
03302     // status region
03303     numberRead = fread(&length,sizeof(int),1,fp);
03304     if (numberRead!=1)
03305         return 1;
03306     if (length) {
03307       if (length!=numberRows_+numberColumns_)
03308         return 1;
03309       status_ = new char unsigned[length];
03310       numberRead = fread(status_,sizeof(char),length, fp);
03311       if (numberRead!=length)
03312         return 1;
03313     }
03314     if (lengthNames_) {
03315       char * array = 
03316         new char[max(numberRows_,numberColumns_)*(lengthNames_+1)];
03317       char * get = array;
03318       numberRead = fread(array,lengthNames_+1,numberRows_,fp);
03319       if (numberRead!=numberRows_)
03320         return 1;
03321       rowNames_ = std::vector<std::string> ();
03322       rowNames_.resize(numberRows_);
03323       for (i=0;i<numberRows_;i++) {
03324         rowNames_.push_back(get);
03325         get += lengthNames_+1;
03326       }
03327       get = array;
03328       numberRead = fread(array,lengthNames_+1,numberColumns_,fp);
03329       if (numberRead!=numberColumns_)
03330         return 1;
03331       columnNames_ = std::vector<std::string> ();
03332       columnNames_.resize(numberColumns_);
03333       for (i=0;i<numberColumns_;i++) {
03334         columnNames_.push_back(get);
03335         get += lengthNames_+1;
03336       }
03337       delete [] array;
03338     }
03339     // Pivot choices
03340     assert(scalars.dualPivotChoice>0&&(scalars.dualPivotChoice&63)<3);
03341     delete dualRowPivot_;
03342     switch ((scalars.dualPivotChoice&63)) {
03343     default:
03344       printf("Need another dualPivot case %d\n",scalars.dualPivotChoice&63);
03345     case 1:
03346       // Dantzig
03347       dualRowPivot_ = new ClpDualRowDantzig();
03348       break;
03349     case 2:
03350       // Steepest - use mode
03351       dualRowPivot_ = new ClpDualRowSteepest(scalars.dualPivotChoice>>6);
03352       break;
03353     }
03354     assert(scalars.primalPivotChoice>0&&(scalars.primalPivotChoice&63)<3);
03355     delete primalColumnPivot_;
03356     switch ((scalars.primalPivotChoice&63)) {
03357     default:
03358       printf("Need another primalPivot case %d\n",
03359              scalars.primalPivotChoice&63);
03360     case 1:
03361       // Dantzig
03362       primalColumnPivot_ = new ClpPrimalColumnDantzig();
03363       break;
03364     case 2:
03365       // Steepest - use mode
03366       primalColumnPivot_ 
03367         = new ClpPrimalColumnSteepest(scalars.primalPivotChoice>>6);
03368       break;
03369     }
03370     assert(scalars.matrixStorageChoice==1);
03371     delete matrix_;
03372     // get arrays
03373     numberRead = fread(&length,sizeof(int),1,fp);
03374     if (numberRead!=1)
03375       return 1;
03376     double * elements = new double[length];
03377     int * indices = new int[length];
03378     CoinBigIndex * starts = new CoinBigIndex[numberColumns_+1];
03379     int * lengths = new int[numberColumns_];
03380     numberRead = fread(elements, sizeof(double),length,fp);
03381     if (numberRead!=length)
03382       return 1;
03383     numberRead = fread(indices, sizeof(int),length,fp);
03384     if (numberRead!=length)
03385       return 1;
03386     numberRead = fread(starts, sizeof(int),numberColumns_+1,fp);
03387     if (numberRead!=numberColumns_+1)
03388       return 1;
03389     numberRead = fread(lengths, sizeof(int),numberColumns_,fp);
03390     if (numberRead!=numberColumns_)
03391       return 1;
03392     // assign matrix
03393     CoinPackedMatrix * matrix = new CoinPackedMatrix();
03394     matrix->assignMatrix(true, numberRows_, numberColumns_,
03395                          length, elements, indices, starts, lengths);
03396     // and transfer to Clp
03397     matrix_ = new ClpPackedMatrix(matrix);
03398     // finished
03399     fclose(fp);
03400     return 0;
03401   } else {
03402     return -1;
03403   }
03404   return 0;
03405 }

void ClpSimplex::returnModel ClpSimplex otherModel  ) 
 

Return model - updates any scalars

Definition at line 4529 of file ClpSimplex.cpp.

References alpha_, columnDualInfeasibility_, columnDualSequence_, columnPrimalInfeasibility_, columnPrimalSequence_, directionIn_, directionOut_, dualIn_, dualOut_, largestDualError_, largestPrimalError_, largestSolutionError_, lowerIn_, lowerOut_, numberDualInfeasibilities_, numberDualInfeasibilitiesWithoutFree_, numberPrimalInfeasibilities_, numberTimesOptimal_, pivotRow_, primalToleranceToGetOptimal_, remainingDualInfeasibility_, ClpModel::returnModel(), rowDualInfeasibility_, rowDualSequence_, rowPrimalInfeasibility_, rowPrimalSequence_, sequenceIn_, sequenceOut_, sumDualInfeasibilities_, sumOfRelaxedDualInfeasibilities_, sumOfRelaxedPrimalInfeasibilities_, sumPrimalInfeasibilities_, theta_, upperIn_, upperOut_, valueIn_, and valueOut_.

04530 {
04531   ClpModel::returnModel(otherModel);
04532   otherModel.columnPrimalInfeasibility_ = columnPrimalInfeasibility_;
04533   otherModel.columnPrimalSequence_ = columnPrimalSequence_;
04534   otherModel.rowPrimalInfeasibility_ = rowPrimalInfeasibility_;
04535   otherModel.rowPrimalSequence_ = rowPrimalSequence_;
04536   otherModel.columnDualInfeasibility_ = columnDualInfeasibility_;
04537   otherModel.columnDualSequence_ = columnDualSequence_;
04538   otherModel.rowDualInfeasibility_ = rowDualInfeasibility_;
04539   otherModel.rowDualSequence_ = rowDualSequence_;
04540   otherModel.primalToleranceToGetOptimal_ = primalToleranceToGetOptimal_;
04541   otherModel.remainingDualInfeasibility_ = remainingDualInfeasibility_;
04542   otherModel.largestPrimalError_ = largestPrimalError_;
04543   otherModel.largestDualError_ = largestDualError_;
04544   otherModel.largestSolutionError_ = largestSolutionError_;
04545   otherModel.alpha_ = alpha_;
04546   otherModel.theta_ = theta_;
04547   otherModel.lowerIn_ = lowerIn_;
04548   otherModel.valueIn_ = valueIn_;
04549   otherModel.upperIn_ = upperIn_;
04550   otherModel.dualIn_ = dualIn_;
04551   otherModel.sequenceIn_ = sequenceIn_;
04552   otherModel.directionIn_ = directionIn_;
04553   otherModel.lowerOut_ = lowerOut_;
04554   otherModel.valueOut_ = valueOut_;
04555   otherModel.upperOut_ = upperOut_;
04556   otherModel.dualOut_ = dualOut_;
04557   otherModel.sequenceOut_ = sequenceOut_;
04558   otherModel.directionOut_ = directionOut_;
04559   otherModel.pivotRow_ = pivotRow_;
04560   otherModel.sumDualInfeasibilities_ = sumDualInfeasibilities_;
04561   otherModel.numberDualInfeasibilities_ = numberDualInfeasibilities_;
04562   otherModel.numberDualInfeasibilitiesWithoutFree_ = 
04563     numberDualInfeasibilitiesWithoutFree_;
04564   otherModel.sumPrimalInfeasibilities_ = sumPrimalInfeasibilities_;
04565   otherModel.numberPrimalInfeasibilities_ = numberPrimalInfeasibilities_;
04566   otherModel.numberTimesOptimal_ = numberTimesOptimal_;
04567   otherModel.sumOfRelaxedDualInfeasibilities_ = sumOfRelaxedDualInfeasibilities_;
04568   otherModel.sumOfRelaxedPrimalInfeasibilities_ = sumOfRelaxedPrimalInfeasibilities_;
04569 }

ClpDataSave ClpSimplex::saveData  ) 
 

Save data.

Factorizes using current basis. solveType - 1 iterating, 0 initial, -1 external If 10 added then in primal values pass Return codes are as from ClpFactorization unless initial factorization when total number of singularities is returned

Definition at line 4486 of file ClpSimplex.cpp.

References dualBound_, ClpDataSave::dualBound_, factorization_, infeasibilityCost_, ClpDataSave::infeasibilityCost_, perturbation_, ClpDataSave::perturbation_, progress_, and ClpDataSave::sparseThreshold_.

Referenced by ClpSimplexDual::dual(), ClpSimplexDual::fastDual(), ClpSimplexPrimal::primal(), and ClpSimplexPrimalQuadratic::primalQuadratic2().

04487 {
04488   ClpDataSave saved;
04489   saved.dualBound_ = dualBound_;
04490   saved.infeasibilityCost_ = infeasibilityCost_;
04491   saved.sparseThreshold_ = factorization_->sparseThreshold();
04492   saved.perturbation_ = perturbation_;
04493   // Progress indicator
04494   delete progress_;
04495   progress_ = new ClpSimplexProgress (this);
04496   return saved;
04497 }

int ClpSimplex::saveModel const char *  fileName  ) 
 

Save model to file, returns 0 if success. This is designed for use outside algorithms so does not save iterating arrays etc. It does not save any messaging information. Does not save scaling values. It does not know about all types of virtual functions.

Definition at line 3015 of file ClpSimplex.cpp.

References algorithm_, dualBound_, dualRowPivot_, dualTolerance_, ClpMatrixBase::getElements(), ClpMatrixBase::getIndices(), ClpMatrixBase::getNumCols(), ClpMatrixBase::getNumRows(), ClpMatrixBase::getVectorLengths(), ClpMatrixBase::getVectorStarts(), infeasibilityCost_, ClpModel::maximumIterations(), numberDualInfeasibilities_, numberDualInfeasibilitiesWithoutFree_, numberPrimalInfeasibilities_, numberRefinements_, ClpModel::objective(), primalColumnPivot_, primalTolerance_, scalingFlag_, specialOptions_, sumDualInfeasibilities_, sumPrimalInfeasibilities_, ClpMatrixBase::type(), ClpPrimalColumnPivot::type(), and ClpDualRowPivot::type().

03016 {
03017   FILE * fp = fopen(fileName,"wb");
03018   if (fp) {
03019     Clp_scalars scalars;
03020     int i;
03021     CoinBigIndex numberWritten;
03022     // Fill in scalars
03023     scalars.optimizationDirection = optimizationDirection_;
03024     memcpy(scalars.dblParam, dblParam_,ClpLastDblParam * sizeof(double));
03025     scalars.objectiveValue = objectiveValue_;
03026     scalars.dualBound = dualBound_;
03027     scalars.dualTolerance = dualTolerance_;
03028     scalars.primalTolerance = primalTolerance_;
03029     scalars.sumDualInfeasibilities = sumDualInfeasibilities_;
03030     scalars.sumPrimalInfeasibilities = sumPrimalInfeasibilities_;
03031     scalars.infeasibilityCost = infeasibilityCost_;
03032     scalars.numberRows = numberRows_;
03033     scalars.numberColumns = numberColumns_;
03034     memcpy(scalars.intParam, intParam_,ClpLastIntParam * sizeof(double));
03035     scalars.numberIterations = numberIterations_;
03036     scalars.problemStatus = problemStatus_;
03037     scalars.maximumIterations = maximumIterations();
03038     scalars.lengthNames = lengthNames_;
03039     scalars.numberDualInfeasibilities = numberDualInfeasibilities_;
03040     scalars.numberDualInfeasibilitiesWithoutFree 
03041       = numberDualInfeasibilitiesWithoutFree_;
03042     scalars.numberPrimalInfeasibilities = numberPrimalInfeasibilities_;
03043     scalars.numberRefinements = numberRefinements_;
03044     scalars.scalingFlag = scalingFlag_;
03045     scalars.algorithm = algorithm_;
03046     scalars.specialOptions = specialOptions_;
03047     scalars.dualPivotChoice = dualRowPivot_->type();
03048     scalars.primalPivotChoice = primalColumnPivot_->type();
03049     scalars.matrixStorageChoice = matrix_->type();
03050 
03051     // put out scalars
03052     numberWritten = fwrite(&scalars,sizeof(Clp_scalars),1,fp);
03053     if (numberWritten!=1)
03054       return 1;
03055     // strings
03056     CoinBigIndex length;
03057     for (i=0;i<ClpLastStrParam;i++) {
03058       length = strParam_[i].size();
03059       numberWritten = fwrite(&length,sizeof(int),1,fp);
03060       if (numberWritten!=1)
03061         return 1;
03062       if (length) {
03063         numberWritten = fwrite(strParam_[i].c_str(),length,1,fp);
03064         if (numberWritten!=1)
03065           return 1;
03066       }
03067     }
03068     // arrays - in no particular order
03069     if (outDoubleArray(rowActivity_,numberRows_,fp))
03070         return 1;
03071     if (outDoubleArray(columnActivity_,numberColumns_,fp))
03072         return 1;
03073     if (outDoubleArray(dual_,numberRows_,fp))
03074         return 1;
03075     if (outDoubleArray(reducedCost_,numberColumns_,fp))
03076         return 1;
03077     if (outDoubleArray(rowLower_,numberRows_,fp))
03078         return 1;
03079     if (outDoubleArray(rowUpper_,numberRows_,fp))
03080         return 1;
03081     if (outDoubleArray(objective(),numberColumns_,fp))
03082         return 1;
03083     if (outDoubleArray(rowObjective_,numberRows_,fp))
03084         return 1;
03085     if (outDoubleArray(columnLower_,numberColumns_,fp))
03086         return 1;
03087     if (outDoubleArray(columnUpper_,numberColumns_,fp))
03088         return 1;
03089     if (ray_) {
03090       if (problemStatus_==1)
03091         if (outDoubleArray(ray_,numberRows_,fp))
03092           return 1;
03093       else if (problemStatus_==2)
03094         if (outDoubleArray(ray_,numberColumns_,fp))
03095           return 1;
03096       else
03097         if (outDoubleArray(NULL,0,fp))
03098           return 1;
03099     } else {
03100       if (outDoubleArray(NULL,0,fp))
03101         return 1;
03102     }
03103     if (status_&&(numberRows_+numberColumns_)>0) {
03104       length = numberRows_+numberColumns_;
03105       numberWritten = fwrite(&length,sizeof(int),1,fp);
03106       if (numberWritten!=1)
03107         return 1;
03108       numberWritten = fwrite(status_,sizeof(char),length, fp);
03109       if (numberWritten!=length)
03110         return 1;
03111     } else {
03112       length = 0;
03113       numberWritten = fwrite(&length,sizeof(int),1,fp);
03114       if (numberWritten!=1)
03115         return 1;
03116     }
03117     if (lengthNames_) {
03118       char * array = 
03119         new char[max(numberRows_,numberColumns_)*(lengthNames_+1)];
03120       char * put = array;
03121       assert (numberRows_ == (int) rowNames_.size());
03122       for (i=0;i<numberRows_;i++) {
03123         assert((int)rowNames_[i].size()<=lengthNames_);
03124         strcpy(put,rowNames_[i].c_str());
03125         put += lengthNames_+1;
03126       }
03127       numberWritten = fwrite(array,lengthNames_+1,numberRows_,fp);
03128       if (numberWritten!=numberRows_)
03129         return 1;
03130       put=array;
03131       assert (numberColumns_ == (int) columnNames_.size());
03132       for (i=0;i<numberColumns_;i++) {
03133         assert((int) columnNames_[i].size()<=lengthNames_);
03134         strcpy(put,columnNames_[i].c_str());
03135         put += lengthNames_+1;
03136       }
03137       numberWritten = fwrite(array,lengthNames_+1,numberColumns_,fp);
03138       if (numberWritten!=numberColumns_)
03139         return 1;
03140       delete [] array;
03141     }
03142     // just standard type at present
03143     assert (matrix_->type()==1);
03144     assert (matrix_->getNumCols() == numberColumns_);
03145     assert (matrix_->getNumRows() == numberRows_);
03146     // we are going to save with gaps
03147     length = matrix_->getVectorStarts()[numberColumns_-1]
03148       + matrix_->getVectorLengths()[numberColumns_-1];
03149     numberWritten = fwrite(&length,sizeof(int),1,fp);
03150     if (numberWritten!=1)
03151       return 1;
03152     numberWritten = fwrite(matrix_->getElements(),
03153                            sizeof(double),length,fp);
03154     if (numberWritten!=length)
03155       return 1;
03156     numberWritten = fwrite(matrix_->getIndices(),
03157                            sizeof(int),length,fp);
03158     if (numberWritten!=length)
03159       return 1;
03160     numberWritten = fwrite(matrix_->getVectorStarts(),
03161                            sizeof(int),numberColumns_+1,fp);
03162     if (numberWritten!=numberColumns_+1)
03163       return 1;
03164     numberWritten = fwrite(matrix_->getVectorLengths(),
03165                            sizeof(int),numberColumns_,fp);
03166     if (numberWritten!=numberColumns_)
03167       return 1;
03168     // finished
03169     fclose(fp);
03170     return 0;
03171   } else {
03172     return -1;
03173   }
03174 }

int ClpSimplex::sequenceIn  )  const [inline]
 

Return sequence In or Out

Definition at line 608 of file ClpSimplex.hpp.

References sequenceIn_.

Referenced by housekeeping(), and ClpNetworkBasis::replaceColumn().

00609   {return sequenceIn_;};

void ClpSimplex::setDirectionIn int  direction  )  [inline]
 

Set directionIn or Out

Definition at line 623 of file ClpSimplex.hpp.

References directionIn_.

00624   { directionIn_=direction;};

void ClpSimplex::setInitialDenseFactorization bool  onOff  ) 
 

Normally the first factorization does sparse coding because the factorization could be singular. This allows initial dense factorization when it is known to be safe

Definition at line 4929 of file ClpSimplex.cpp.

References specialOptions_.

Referenced by dual(), and primal().

04930 {
04931   if (onOff)
04932     specialOptions_ |= 8;
04933   else
04934     specialOptions_ &= ~8;
04935 }

void ClpSimplex::setSequenceIn int  sequence  )  [inline]
 

Set sequenceIn or Out

Definition at line 613 of file ClpSimplex.hpp.

References sequenceIn_.

00614   { sequenceIn_=sequence;};

void ClpSimplex::setValuesPassAction float  incomingInfeasibility,
float  allowedInfeasibility
 

For advanced use. When doing iterative solves things can get nasty so on values pass if incoming solution has largest infeasibility < incomingInfeasibility throw out variables from basis until largest infeasibility < allowedInfeasibility or incoming largest infeasibility. If allowedInfeasibility>= incomingInfeasibility this is always possible altough you may end up with an all slack basis.

Defaults are 1.0,10.0

Definition at line 4613 of file ClpSimplex.cpp.

References incomingInfeasibility_.

04615 {
04616   incomingInfeasibility_=incomingInfeasibility;
04617   allowedInfeasibility_=allowedInfeasibility;
04618   assert(incomingInfeasibility_>=0.0);
04619   assert(allowedInfeasibility_>=incomingInfeasibility_);
04620 }

double* ClpSimplex::solutionRegion int  section  )  [inline]
 

Return row or column sections - not as much needed as it once was. These just map into single arrays

Definition at line 572 of file ClpSimplex.hpp.

References columnActivityWork_, and rowActivityWork_.

Referenced by ClpNonLinearCost::checkInfeasibilities(), and ClpQuadraticInfo::createGradient().

00573   { if (!section) return rowActivityWork_; else return columnActivityWork_;};

int ClpSimplex::startup int  ifValuesPass  ) 
 

Common bits of coding for dual and primal. Return s0 if okay, 1 if bad matrix, 2 if very bad factorization

Definition at line 4369 of file ClpSimplex.cpp.

References algorithm_, createRim(), dualTolerance_, factorization_, ClpMatrixBase::getNumElements(), gutsOfSolution(), CoinMessageHandler::message(), nonLinearCost_, numberTimesOptimal_, perturbation_, pivotRow_, primalTolerance_, sequenceIn_, and sequenceOut_.

Referenced by ClpSimplexDual::dual(), ClpSimplexPrimal::primal(), and ClpSimplexPrimalQuadratic::primalQuadratic2().

04370 {
04371   // sanity check
04372   // bad if empty (trap here to avoid using bad matrix_)
04373   if (!matrix_||!matrix_->getNumElements()) {
04374     handler_->message(CLP_EMPTY_PROBLEM,messages_)
04375       <<numberRows_
04376       <<numberColumns_
04377       <<0
04378       <<CoinMessageEol;
04379     problemStatus_=4;
04380     return 2;
04381   }
04382   pivotRow_=-1;
04383   sequenceIn_=-1;
04384   sequenceOut_=-1;
04385   secondaryStatus_=0;
04386 
04387   primalTolerance_=dblParam_[ClpPrimalTolerance];
04388   dualTolerance_=dblParam_[ClpDualTolerance];
04389   if (problemStatus_!=10)
04390     numberIterations_=0;
04391 
04392   // put in standard form (and make row copy)
04393   // create modifiable copies of model rim and do optional scaling
04394   bool goodMatrix=createRim(7+8+16,true);
04395 
04396   if (goodMatrix) {
04397     // Model looks okay
04398     // Do initial factorization
04399     // and set certain stuff
04400     // We can either set increasing rows so ...IsBasic gives pivot row
04401     // or we can just increment iBasic one by one
04402     // for now let ...iBasic give pivot row
04403     factorization_->increasingRows(2);
04404     // row activities have negative sign
04405     factorization_->slackValue(-1.0);
04406     factorization_->zeroTolerance(1.0e-13);
04407     // Switch off dense (unless special option set)
04408     int saveThreshold = factorization_->denseThreshold();
04409     factorization_->setDenseThreshold(0);
04410     // If values pass then perturb (otherwise may be optimal so leave a bit)
04411     if (ifValuesPass) {
04412       // do perturbation if asked for
04413       
04414       if (perturbation_<100) {
04415         if (algorithm_>0) {
04416           ((ClpSimplexPrimal *) this)->perturb(0);
04417         } else if (algorithm_<0) {
04418         ((ClpSimplexDual *) this)->perturb();
04419         }
04420       }
04421     }
04422     // for primal we will change bounds using infeasibilityCost_
04423     if (nonLinearCost_==NULL&&algorithm_>0) {
04424       // get a valid nonlinear cost function
04425       delete nonLinearCost_;
04426       nonLinearCost_= new ClpNonLinearCost(this);
04427     }
04428     
04429     // loop round to clean up solution if values pass
04430     int numberThrownOut = -1;
04431     int totalNumberThrownOut=0;
04432     while(numberThrownOut) {
04433       int status = internalFactorize(0+10*ifValuesPass);
04434       if (status<0)
04435         return 1; // some error
04436       else
04437         numberThrownOut = status;
04438       
04439       // for this we need clean basis so it is after factorize
04440       if (!numberThrownOut)
04441         numberThrownOut = gutsOfSolution(  NULL,NULL,
04442                                          ifValuesPass!=0);
04443       totalNumberThrownOut+= numberThrownOut;
04444       
04445     }
04446     
04447     if (totalNumberThrownOut)
04448       handler_->message(CLP_SINGULARITIES,messages_)
04449         <<totalNumberThrownOut
04450         <<CoinMessageEol;
04451     // Switch back dense
04452     factorization_->setDenseThreshold(saveThreshold);
04453     
04454     problemStatus_ = -1;
04455     
04456     // number of times we have declared optimality
04457     numberTimesOptimal_=0;
04458 
04459     return 0;
04460   } else {
04461     // bad matrix
04462     return 2;
04463   }
04464     
04465 }

bool ClpSimplex::statusOfProblem  ) 
 

Factorizes and returns true if optimal. Used by user

Definition at line 4511 of file ClpSimplex.cpp.

References createRim(), deleteRim(), dualFeasible(), gutsOfSolution(), and primalFeasible().

Referenced by pivot().

04512 {
04513   // is factorization okay?
04514   assert (internalFactorize(1)==0);
04515   // put back original costs and then check
04516   // also move to work arrays
04517   createRim(4+32);
04518   //memcpy(rowActivityWork_,rowActivity_,numberRows_*sizeof(double));
04519   //memcpy(columnActivityWork_,columnActivity_,numberColumns_*sizeof(double));
04520   gutsOfSolution(NULL,NULL);
04521   //memcpy(rowActivity_,rowActivityWork_,numberRows_*sizeof(double));
04522   //memcpy(columnActivity_,columnActivityWork_,numberColumns_*sizeof(double));
04523   //memcpy(reducedCost_,dj_,numberColumns_*sizeof(double));
04524   deleteRim(-1);
04525   return (primalFeasible()&&dualFeasible());
04526 }

int ClpSimplex::strongBranching int  numberVariables,
const int *  variables,
double *  newLower,
double *  newUpper,
double **  outputSolution,
int *  outputStatus,
int *  outputIterations,
bool  stopOnFirstInfeasible = true,
bool  alwaysFinish = false
 

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 in ClpSimplexDual.

Definition at line 2939 of file ClpSimplex.cpp.

02945 {
02946   return ((ClpSimplexDual *) this)->strongBranching(numberVariables,variables,
02947                                                     newLower,  newUpper,outputSolution,
02948                                                     outputStatus, outputIterations,
02949                                                     stopOnFirstInfeasible,
02950                                                     alwaysFinish);
02951 }

int ClpSimplex::tightenPrimalBounds double  factor = 0.0  ) 
 

Tightens primal bounds to make dual faster. Unless fixed, bounds are slightly looser than they could be. This is to make dual go faster and is probably not needed with a presolve. Returns non-zero if problem infeasible.

Fudge for branch and bound - put bounds on columns of factor * largest value (at continuous) - should improve stability in branch and bound on infeasible branches (0.0 is off)

Definition at line 2485 of file ClpSimplex.cpp.

References largeValue(), ClpModel::matrix(), CoinMessageHandler::message(), and ClpModel::primalTolerance().

02486 {
02487   
02488   // Get a row copy in standard format
02489   CoinPackedMatrix copy;
02490   copy.reverseOrderedCopyOf(*matrix());
02491   // get matrix data pointers
02492   const int * column = copy.getIndices();
02493   const CoinBigIndex * rowStart = copy.getVectorStarts();
02494   const int * rowLength = copy.getVectorLengths(); 
02495   const double * element = copy.getElements();
02496   int numberChanged=1,iPass=0;
02497   double large = largeValue(); // treat bounds > this as infinite
02498 #ifndef NDEBUG
02499   double large2= 1.0e10*large;
02500 #endif
02501   int numberInfeasible=0;
02502   int totalTightened = 0;
02503 
02504   double tolerance = primalTolerance();
02505 
02506 
02507   // Save column bounds
02508   double * saveLower = new double [numberColumns_];
02509   memcpy(saveLower,columnLower_,numberColumns_*sizeof(double));
02510   double * saveUpper = new double [numberColumns_];
02511   memcpy(saveUpper,columnUpper_,numberColumns_*sizeof(double));
02512 
02513   int iRow, iColumn;
02514 
02515   // If wanted - tighten column bounds using solution
02516   if (factor) {
02517     assert (factor>1.0);
02518     double largest=0.0;
02519     for (iColumn=0;iColumn<numberColumns_;iColumn++) {
02520       if (columnUpper_[iColumn]-columnLower_[iColumn]>tolerance) {
02521         largest = max(largest,fabs(columnActivity_[iColumn]));
02522       }
02523     }
02524     largest *= factor;
02525     for (iColumn=0;iColumn<numberColumns_;iColumn++) {
02526       if (columnUpper_[iColumn]-columnLower_[iColumn]>tolerance) {
02527         columnUpper_[iColumn] = min(columnUpper_[iColumn],largest);
02528         columnLower_[iColumn] = max(columnLower_[iColumn],-largest);
02529       }
02530     }
02531   }
02532 #define MAXPASS 10
02533 
02534   // Loop round seeing if we can tighten bounds
02535   // Would be faster to have a stack of possible rows
02536   // and we put altered rows back on stack
02537   int numberCheck=-1;
02538   while(numberChanged>numberCheck) {
02539 
02540     numberChanged = 0; // Bounds tightened this pass
02541     
02542     if (iPass==MAXPASS) break;
02543     iPass++;
02544     
02545     for (iRow = 0; iRow < numberRows_; iRow++) {
02546 
02547       if (rowLower_[iRow]>-large||rowUpper_[iRow]<large) {
02548 
02549         // possible row
02550         int infiniteUpper = 0;
02551         int infiniteLower = 0;
02552         double maximumUp = 0.0;
02553         double maximumDown = 0.0;
02554         double newBound;
02555         CoinBigIndex rStart = rowStart[iRow];
02556         CoinBigIndex rEnd = rowStart[iRow]+rowLength[iRow];
02557         CoinBigIndex j;
02558         // Compute possible lower and upper ranges
02559       
02560         for (j = rStart; j < rEnd; ++j) {
02561           double value=element[j];
02562           iColumn = column[j];
02563           if (value > 0.0) {
02564             if (columnUpper_[iColumn] >= large) {
02565               ++infiniteUpper;
02566             } else {
02567               maximumUp += columnUpper_[iColumn] * value;
02568             }
02569             if (columnLower_[iColumn] <= -large) {
02570               ++infiniteLower;
02571             } else {
02572               maximumDown += columnLower_[iColumn] * value;
02573             }
02574           } else if (value<0.0) {
02575             if (columnUpper_[iColumn] >= large) {
02576               ++infiniteLower;
02577             } else {
02578               maximumDown += columnUpper_[iColumn] * value;
02579             }
02580             if (columnLower_[iColumn] <= -large) {
02581               ++infiniteUpper;
02582             } else {
02583               maximumUp += columnLower_[iColumn] * value;
02584             }
02585           }
02586         }
02587         // Build in a margin of error
02588         maximumUp += 1.0e-8*fabs(maximumUp);
02589         maximumDown -= 1.0e-8*fabs(maximumDown);
02590         double maxUp = maximumUp+infiniteUpper*1.0e31;
02591         double maxDown = maximumDown-infiniteLower*1.0e31;
02592         if (maxUp <= rowUpper_[iRow] + tolerance && 
02593             maxDown >= rowLower_[iRow] - tolerance) {
02594           
02595           // Row is redundant - make totally free
02596           // NO - can't do this for postsolve
02597           // rowLower_[iRow]=-COIN_DBL_MAX;
02598           // rowUpper_[iRow]=COIN_DBL_MAX;
02599           //printf("Redundant row in presolveX %d\n",iRow);
02600 
02601         } else {
02602           if (maxUp < rowLower_[iRow] -100.0*tolerance ||
02603               maxDown > rowUpper_[iRow]+100.0*tolerance) {
02604             // problem is infeasible - exit at once
02605             numberInfeasible++;
02606             break;
02607           }
02608           double lower = rowLower_[iRow];
02609           double upper = rowUpper_[iRow];
02610           for (j = rStart; j < rEnd; ++j) {
02611             double value=element[j];
02612             iColumn = column[j];
02613             double nowLower = columnLower_[iColumn];
02614             double nowUpper = columnUpper_[iColumn];
02615             if (value > 0.0) {
02616               // positive value
02617               if (lower>-large) {
02618                 if (!infiniteUpper) {
02619                   assert(nowUpper < large2);
02620                   newBound = nowUpper + 
02621                     (lower - maximumUp) / value;
02622                   // relax if original was large
02623                   if (fabs(maximumUp)>1.0e8)
02624                     newBound -= 1.0e-12*fabs(maximumUp);
02625                 } else if (infiniteUpper==1&&nowUpper>large) {
02626                   newBound = (lower -maximumUp) / value;
02627                   // relax if original was large
02628                   if (fabs(maximumUp)>1.0e8)
02629                     newBound -= 1.0e-12*fabs(maximumUp);
02630                 } else {
02631                   newBound = -COIN_DBL_MAX;
02632                 }
02633                 if (newBound > nowLower + 1.0e-12&&newBound>-large) {
02634                   // Tighten the lower bound 
02635                   columnLower_[iColumn] = newBound;
02636                   numberChanged++;
02637                   // check infeasible (relaxed)
02638                   if (nowUpper - newBound < 
02639                       -100.0*tolerance) {
02640                     numberInfeasible++;
02641                   }
02642                   // adjust
02643                   double now;
02644                   if (nowLower<-large) {
02645                     now=0.0;
02646                     infiniteLower--;
02647                   } else {
02648                     now = nowLower;
02649                   }
02650                   maximumDown += (newBound-now) * value;
02651                   nowLower = newBound;
02652 #ifdef DEBUG
02653                   checkCorrect(this,iRow,
02654                                element, rowStart, rowLength,
02655                                column,
02656                                columnLower_,  columnUpper_,
02657                                infiniteUpper,
02658                                infiniteLower,
02659                                maximumUp,
02660                                maximumDown);
02661 #endif
02662                 }
02663               } 
02664               if (upper <large) {
02665                 if (!infiniteLower) {
02666                   assert(nowLower >- large2);
02667                   newBound = nowLower + 
02668                     (upper - maximumDown) / value;
02669                   // relax if original was large
02670                   if (fabs(maximumDown)>1.0e8)
02671                     newBound += 1.0e-12*fabs(maximumDown);
02672                 } else if (infiniteLower==1&&nowLower<-large) {
02673                   newBound =   (upper - maximumDown) / value;
02674                   // relax if original was large
02675                   if (fabs(maximumDown)>1.0e8)
02676                     newBound += 1.0e-12*fabs(maximumDown);
02677                 } else {
02678                   newBound = COIN_DBL_MAX;
02679                 }
02680                 if (newBound < nowUpper - 1.0e-12&&newBound<large) {
02681                   // Tighten the upper bound 
02682                   columnUpper_[iColumn] = newBound;
02683                   numberChanged++;
02684                   // check infeasible (relaxed)
02685                   if (newBound - nowLower < 
02686                       -100.0*tolerance) {
02687                     numberInfeasible++;
02688                   }
02689                   // adjust 
02690                   double now;
02691                   if (nowUpper>large) {
02692                     now=0.0;
02693                     infiniteUpper--;
02694                   } else {
02695                     now = nowUpper;
02696                   }
02697                   maximumUp += (newBound-now) * value;
02698                   nowUpper = newBound;
02699 #ifdef DEBUG
02700                   checkCorrect(this,iRow,
02701                                element, rowStart, rowLength,
02702                                column,
02703                                columnLower_,  columnUpper_,
02704                                infiniteUpper,
02705                                infiniteLower,
02706                                maximumUp,
02707                                maximumDown);
02708 #endif
02709                 }
02710               }
02711             } else {
02712               // negative value
02713               if (lower>-large) {
02714                 if (!infiniteUpper) {
02715                   assert(nowLower < large2);
02716                   newBound = nowLower + 
02717                     (lower - maximumUp) / value;
02718                   // relax if original was large
02719                   if (fabs(maximumUp)>1.0e8)
02720                     newBound += 1.0e-12*fabs(maximumUp);
02721                 } else if (infiniteUpper==1&&nowLower<-large) {
02722                   newBound = (lower -maximumUp) / value;
02723                   // relax if original was large
02724                   if (fabs(maximumUp)>1.0e8)
02725                     newBound += 1.0e-12*fabs(maximumUp);
02726                 } else {
02727                   newBound = COIN_DBL_MAX;
02728                 }
02729                 if (newBound < nowUpper - 1.0e-12&&newBound<large) {
02730                   // Tighten the upper bound 
02731                   columnUpper_[iColumn] = newBound;
02732                   numberChanged++;
02733                   // check infeasible (relaxed)
02734                   if (newBound - nowLower < 
02735                       -100.0*tolerance) {
02736                     numberInfeasible++;
02737                   }
02738                   // adjust
02739                   double now;
02740                   if (nowUpper>large) {
02741                     now=0.0;
02742                     infiniteLower--;
02743                   } else {
02744                     now = nowUpper;
02745                   }
02746                   maximumDown += (newBound-now) * value;
02747                   nowUpper = newBound;
02748 #ifdef DEBUG
02749                   checkCorrect(this,iRow,
02750                                element, rowStart, rowLength,
02751                                column,
02752                                columnLower_,  columnUpper_,
02753                                infiniteUpper,
02754                                infiniteLower,
02755                                maximumUp,
02756                                maximumDown);
02757 #endif
02758                 }
02759               }
02760               if (upper <large) {
02761                 if (!infiniteLower) {
02762                   assert(nowUpper < large2);
02763                   newBound = nowUpper + 
02764                     (upper - maximumDown) / value;
02765                   // relax if original was large
02766                   if (fabs(maximumDown)>1.0e8)
02767                     newBound -= 1.0e-12*fabs(maximumDown);
02768                 } else if (infiniteLower==1&&nowUpper>large) {
02769                   newBound =   (upper - maximumDown) / value;
02770                   // relax if original was large
02771                   if (fabs(maximumDown)>1.0e8)
02772                     newBound -= 1.0e-12*fabs(maximumDown);
02773                 } else {
02774                   newBound = -COIN_DBL_MAX;
02775                 }
02776                 if (newBound > nowLower + 1.0e-12&&newBound>-large) {
02777                   // Tighten the lower bound 
02778                   columnLower_[iColumn] = newBound;
02779                   numberChanged++;
02780                   // check infeasible (relaxed)
02781                   if (nowUpper - newBound < 
02782                       -100.0*tolerance) {
02783                     numberInfeasible++;
02784                   }
02785                   // adjust
02786                   double now;
02787                   if (nowLower<-large) {
02788                     now=0.0;
02789                     infiniteUpper--;
02790                   } else {
02791                     now = nowLower;
02792                   }
02793                   maximumUp += (newBound-now) * value;
02794                   nowLower = newBound;
02795 #ifdef DEBUG
02796                   checkCorrect(this,iRow,
02797                                element, rowStart, rowLength,
02798                                column,
02799                                columnLower_,  columnUpper_,
02800                                infiniteUpper,
02801                                infiniteLower,
02802                                maximumUp,
02803                                maximumDown);
02804 #endif
02805                 }
02806               }
02807             }
02808           }
02809         }
02810       }
02811     }
02812     totalTightened += numberChanged;
02813     if (iPass==1)
02814       numberCheck=numberChanged>>4;
02815     if (numberInfeasible) break;
02816   }
02817   if (!numberInfeasible) {
02818     handler_->message(CLP_SIMPLEX_BOUNDTIGHTEN,messages_)
02819       <<totalTightened
02820       <<CoinMessageEol;
02821     // Set bounds slightly loose
02822     double useTolerance = 1.0e-3;
02823     for (iColumn=0;iColumn<numberColumns_;iColumn++) {
02824       if (saveUpper[iColumn]>saveLower[iColumn]+useTolerance) {
02825         if (columnUpper_[iColumn]-columnLower_[iColumn]<useTolerance+1.0e8) {
02826           // relax enough so will have correct dj
02827 #if 1
02828           columnLower_[iColumn]=max(saveLower[iColumn],
02829                                     columnLower_[iColumn]-100.0*useTolerance);
02830           columnUpper_[iColumn]=min(saveUpper[iColumn],
02831                                     columnUpper_[iColumn]+100.0*useTolerance);
02832 #else
02833           if (fabs(columnUpper_[iColumn])<fabs(columnLower_[iColumn])) {
02834             if (columnUpper_[iColumn]- 100.0*useTolerance>saveLower[iColumn]) {
02835               columnLower_[iColumn]=columnUpper_[iColumn]-100.0*useTolerance;
02836             } else {
02837               columnLower_[iColumn]=saveLower[iColumn];
02838               columnUpper_[iColumn]=min(saveUpper[iColumn],
02839                                         saveLower[iColumn]+100.0*useTolerance);
02840             }
02841           } else {
02842             if (columnLower_[iColumn]+100.0*useTolerance<saveUpper[iColumn]) {
02843               columnUpper_[iColumn]=columnLower_[iColumn]+100.0*useTolerance;
02844             } else {
02845               columnUpper_[iColumn]=saveUpper[iColumn];
02846               columnLower_[iColumn]=max(saveLower[iColumn],
02847                                         saveUpper[iColumn]-100.0*useTolerance);
02848             }
02849           }
02850 #endif
02851         } else {
02852           if (columnUpper_[iColumn]<saveUpper[iColumn]) {
02853             // relax a bit
02854             columnUpper_[iColumn] = min(columnUpper_[iColumn]+100.0*useTolerance,
02855                                         saveUpper[iColumn]);
02856           }
02857           if (columnLower_[iColumn]>saveLower[iColumn]) {
02858             // relax a bit
02859             columnLower_[iColumn] = max(columnLower_[iColumn]-100.0*useTolerance,
02860                                         saveLower[iColumn]);
02861           }
02862         }
02863       }
02864     }
02865   } else {
02866     handler_->message(CLP_SIMPLEX_INFEASIBILITIES,messages_)
02867       <<numberInfeasible
02868       <<CoinMessageEol;
02869     // restore column bounds
02870     memcpy(columnLower_,saveLower,numberColumns_*sizeof(double));
02871     memcpy(columnUpper_,saveUpper,numberColumns_*sizeof(double));
02872   }
02873   delete [] saveLower;
02874   delete [] saveUpper;
02875   return (numberInfeasible);
02876 }

void ClpSimplex::times double  scalar,
const double *  x,
double *  y
const
 

Return y + A * x * scalar in y.

Precondition:
x must be of size numColumns()

y must be of size numRows()

Definition at line 2369 of file ClpSimplex.cpp.

References columnScale_, rowScale_, and ClpMatrixBase::times().

Referenced by cleanStatus(), computePrimals(), ClpSimplexPrimalQuadratic::endQuadratic(), gutsOfSolution(), and ClpSimplexPrimalQuadratic::makeQuadratic().

02371 {
02372   if (rowScale_)
02373     matrix_->times(scalar,x,y,rowScale_,columnScale_);
02374   else
02375     matrix_->times(scalar,x,y);
02376 }

void ClpSimplex::transposeTimes double  scalar,
const double *  x,
double *  y
const
 

Return y + x * scalar * A in y.

Precondition:
x must be of size numRows()

y must be of size numColumns()

Definition at line 2378 of file ClpSimplex.cpp.

References columnScale_, rowScale_, and ClpMatrixBase::transposeTimes().

Referenced by computeDuals(), and ClpSimplexDual::dual().

02380 {
02381   if (rowScale_)
02382     matrix_->transposeTimes(scalar,x,y,rowScale_,columnScale_);
02383   else
02384     matrix_->transposeTimes(scalar,x,y);
02385 }

void ClpSimplex::unpack CoinIndexedVector rowArray,
int  sequence
const
 

Unpacks one column of the matrix into indexed array Slack if sequence>= numberColumns Also applies scaling if needed

Definition at line 1912 of file ClpSimplex.cpp.

References CoinIndexedVector::clear(), CoinIndexedVector::insert(), and ClpMatrixBase::unpack().

01913 {
01914   rowArray->clear();
01915   if (sequence>=numberColumns_) {
01916     //slack
01917     rowArray->insert(sequence-numberColumns_,-1.0);
01918   } else {
01919     // column
01920     matrix_->unpack(this,rowArray,sequence);
01921   }
01922 }

void ClpSimplex::unpack CoinIndexedVector rowArray  )  const
 

Unpacks one column of the matrix into indexed array Uses sequenceIn_ Also applies scaling if needed

Definition at line 1900 of file ClpSimplex.cpp.

References CoinIndexedVector::clear(), CoinIndexedVector::insert(), sequenceIn_, and ClpMatrixBase::unpack().

Referenced by ClpSimplexDual::dualRow(), pivot(), ClpSimplexPrimal::pivotResult(), ClpNetworkBasis::replaceColumn(), ClpSimplexDual::statusOfProblemInDual(), ClpSimplexPrimalQuadratic::whileIterating(), and ClpSimplexDual::whileIterating().

01901 {
01902   rowArray->clear();
01903   if (sequenceIn_>=numberColumns_) {
01904     //slack
01905     rowArray->insert(sequenceIn_-numberColumns_,-1.0);
01906   } else {
01907     // column
01908     matrix_->unpack(this,rowArray,sequenceIn_);
01909   }
01910 }

void ClpSimplex::unpackPacked CoinIndexedVector rowArray,
int  sequence
 

Unpacks one column of the matrix into indexed array as packed vector Slack if sequence>= numberColumns Also applies scaling if needed

Definition at line 1944 of file ClpSimplex.cpp.

References CoinIndexedVector::clear(), CoinIndexedVector::denseVector(), CoinIndexedVector::getIndices(), CoinIndexedVector::setNumElements(), CoinIndexedVector::setPackedMode(), and ClpMatrixBase::unpackPacked().

01945 {
01946   rowArray->clear();
01947   if (sequence>=numberColumns_) {
01948     //slack
01949     int * index = rowArray->getIndices();
01950     double * array = rowArray->denseVector();
01951     array[0]=-1.0;
01952     index[0]=sequence-numberColumns_;
01953     rowArray->setNumElements(1);
01954     rowArray->setPackedMode(true);
01955   } else {
01956     // column
01957     matrix_->unpackPacked(this,rowArray,sequence);
01958   }
01959 }

void ClpSimplex::unpackPacked CoinIndexedVector rowArray  ) 
 

Unpacks one column of the matrix into indexed array as packed vector Uses sequenceIn_ Also applies scaling if needed

Definition at line 1927 of file ClpSimplex.cpp.

References CoinIndexedVector::clear(), CoinIndexedVector::denseVector(), CoinIndexedVector::getIndices(), sequenceIn_, CoinIndexedVector::setNumElements(), CoinIndexedVector::setPackedMode(), and ClpMatrixBase::unpackPacked().

Referenced by ClpSimplexPrimal::pivotResult(), and ClpSimplexDual::whileIterating().

01928 {
01929   rowArray->clear();
01930   if (sequenceIn_>=numberColumns_) {
01931     //slack
01932     int * index = rowArray->getIndices();
01933     double * array = rowArray->denseVector();
01934     array[0]=-1.0;
01935     index[0]=sequenceIn_-numberColumns_;
01936     rowArray->setNumElements(1);
01937     rowArray->setPackedMode(true);
01938   } else {
01939     // column
01940     matrix_->unpackPacked(this,rowArray,sequenceIn_);
01941   }
01942 }


Friends And Related Function Documentation

void ClpSimplexUnitTest const std::string &  mpsDir,
const std::string &  netlibDir
[friend]
 

A function that tests the methods in the ClpSimplex 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.

It also does some testing of ClpFactorization class

Definition at line 371 of file unitTest.cpp.

00373 {
00374   
00375   CoinRelFltEq eq(0.000001);
00376 
00377   {
00378     ClpSimplex solution;
00379   
00380     // matrix data
00381     //deliberate hiccup of 2 between 0 and 1
00382     CoinBigIndex start[5]={0,4,7,8,9};
00383     int length[5]={2,3,1,1,1};
00384     int rows[11]={0,2,-1,-1,0,1,2,0,1,2};
00385     double elements[11]={7.0,2.0,1.0e10,1.0e10,-2.0,1.0,-2.0,1,1,1};
00386     CoinPackedMatrix matrix(true,3,5,8,elements,rows,start,length);
00387     
00388     // rim data
00389     double objective[7]={-4.0,1.0,0.0,0.0,0.0,0.0,0.0};
00390     double rowLower[5]={14.0,3.0,3.0,1.0e10,1.0e10};
00391     double rowUpper[5]={14.0,3.0,3.0,-1.0e10,-1.0e10};
00392     double colLower[7]={0.0,0.0,0.0,0.0,0.0,0.0,0.0};
00393     double colUpper[7]={100.0,100.0,100.0,100.0,100.0,100.0,100.0};
00394     
00395     // basis 1
00396     int rowBasis1[3]={-1,-1,-1};
00397     int colBasis1[5]={1,1,-1,-1,1};
00398     solution.loadProblem(matrix,colLower,colUpper,objective,
00399                          rowLower,rowUpper);
00400     int i;
00401     solution.createStatus();
00402     for (i=0;i<3;i++) {
00403       if (rowBasis1[i]<0) {
00404         solution.setRowStatus(i,ClpSimplex::atLowerBound);
00405       } else {
00406         solution.setRowStatus(i,ClpSimplex::basic);
00407       }
00408     }
00409     for (i=0;i<5;i++) {
00410       if (colBasis1[i]<0) {
00411         solution.setColumnStatus(i,ClpSimplex::atLowerBound);
00412       } else {
00413         solution.setColumnStatus(i,ClpSimplex::basic);
00414       }
00415     }
00416     solution.setLogLevel(3+4+8+16+32);
00417     solution.primal();
00418     for (i=0;i<3;i++) {
00419       if (rowBasis1[i]<0) {
00420         solution.setRowStatus(i,ClpSimplex::atLowerBound);
00421       } else {
00422         solution.setRowStatus(i,ClpSimplex::basic);
00423       }
00424     }
00425     for (i=0;i<5;i++) {
00426       if (colBasis1[i]<0) {
00427         solution.setColumnStatus(i,ClpSimplex::atLowerBound);
00428       } else {
00429         solution.setColumnStatus(i,ClpSimplex::basic);
00430       }
00431     }
00432     // intricate stuff does not work with scaling
00433     solution.scaling(0);
00434     assert(!solution.factorize ( ));
00435     const double * colsol = solution.primalColumnSolution();
00436     const double * rowsol = solution.primalRowSolution();
00437     solution.getSolution(rowsol,colsol);
00438     double colsol1[5]={20.0/7.0,3.0,0.0,0.0,23.0/7.0};
00439     for (i=0;i<5;i++) {
00440       assert(eq(colsol[i],colsol1[i]));
00441     }
00442     // now feed in again without actually doing factorization
00443     ClpFactorization factorization2 = *solution.factorization();
00444     ClpSimplex solution2 = solution;
00445     solution2.setFactorization(factorization2);
00446     solution2.createStatus();
00447     for (i=0;i<3;i++) {
00448       if (rowBasis1[i]<0) {
00449         solution2.setRowStatus(i,ClpSimplex::atLowerBound);
00450       } else {
00451         solution2.setRowStatus(i,ClpSimplex::basic);
00452       }
00453     }
00454     for (i=0;i<5;i++) {
00455       if (colBasis1[i]<0) {
00456         solution2.setColumnStatus(i,ClpSimplex::atLowerBound);
00457       } else {
00458         solution2.setColumnStatus(i,ClpSimplex::basic);
00459       }
00460     }
00461     // intricate stuff does not work with scaling
00462     solution2.scaling(0);
00463     solution2.getSolution(rowsol,colsol);
00464     colsol = solution2.primalColumnSolution();
00465     rowsol = solution2.primalRowSolution();
00466     for (i=0;i<5;i++) {
00467       assert(eq(colsol[i],colsol1[i]));
00468     }
00469     solution2.setDualBound(0.1);
00470     solution2.dual();
00471     objective[2]=-1.0;
00472     objective[3]=-0.5;
00473     objective[4]=10.0;
00474     solution.dual();
00475     for (i=0;i<3;i++) {
00476       rowLower[i]=-1.0e50;
00477       colUpper[i+2]=0.0;
00478     }
00479     solution.setLogLevel(3);
00480     solution.dual();
00481     double rowObjective[]={1.0,0.5,-10.0};
00482     solution.loadProblem(matrix,colLower,colUpper,objective,
00483                          rowLower,rowUpper,rowObjective);
00484     solution.dual();
00485   }
00486   {    
00487     CoinMpsIO m;
00488     std::string fn = mpsDir+"exmip1";
00489     m.readMps(fn.c_str(),"mps");
00490     ClpSimplex solution;
00491     solution.loadProblem(*m.getMatrixByCol(),m.getColLower(),m.getColUpper(),
00492                          m.getObjCoefficients(),
00493                          m.getRowLower(),m.getRowUpper());
00494     solution.dual();
00495   }
00496   // Test Message handler
00497   {    
00498     CoinMpsIO m;
00499     std::string fn = mpsDir+"exmip1";
00500     //fn = "Test/subGams4";
00501     m.readMps(fn.c_str(),"mps");
00502     ClpSimplex model;
00503     model.loadProblem(*m.getMatrixByCol(),m.getColLower(),m.getColUpper(),
00504                          m.getObjCoefficients(),
00505                          m.getRowLower(),m.getRowUpper());
00506     // Message handler
00507     MyMessageHandler messageHandler(&model);
00508     std::cout<<"Testing derived message handler"<<std::endl;
00509     model.passInMessageHandler(&messageHandler);
00510     model.messagesPointer()->setDetailMessage(1,102);
00511     model.setFactorizationFrequency(10);
00512     model.primal();
00513 
00514     // Write saved solutions
00515     int nc = model.getNumCols();
00516     int s; 
00517     std::deque<StdVectorDouble> fep = messageHandler.getFeasibleExtremePoints();
00518     int numSavedSolutions = fep.size();
00519     for ( s=0; s<numSavedSolutions; ++s ) {
00520       const StdVectorDouble & solnVec = fep[s];
00521       for ( int c=0; c<nc; ++c ) {
00522         if (fabs(solnVec[c])>1.0e-8)
00523           std::cout <<"Saved Solution: " <<s <<" ColNum: " <<c <<" Value: " <<solnVec[c] <<std::endl;
00524       }
00525     }
00526     // Solve again without scaling
00527     // and maximize then minimize
00528     messageHandler.clearFeasibleExtremePoints();
00529     model.scaling(0);
00530     model.setOptimizationDirection(-1);
00531     model.primal();
00532     model.setOptimizationDirection(1);
00533     model.primal();
00534     fep = messageHandler.getFeasibleExtremePoints();
00535     numSavedSolutions = fep.size();
00536     for ( s=0; s<numSavedSolutions; ++s ) {
00537       const StdVectorDouble & solnVec = fep[s];
00538       for ( int c=0; c<nc; ++c ) {
00539         if (fabs(solnVec[c])>1.0e-8)
00540           std::cout <<"Saved Solution: " <<s <<" ColNum: " <<c <<" Value: " <<solnVec[c] <<std::endl;
00541       }
00542     }
00543   }
00544   // test steepest edge
00545   {    
00546     CoinMpsIO m;
00547     std::string fn = netlibDir+"finnis";
00548     m.readMps(fn.c_str(),"mps");
00549     ClpModel model;
00550     model.loadProblem(*m.getMatrixByCol(),m.getColLower(),
00551                     m.getColUpper(),
00552                     m.getObjCoefficients(),
00553                     m.getRowLower(),m.getRowUpper());
00554     ClpSimplex solution(model);
00555 
00556     solution.scaling(1); 
00557     solution.setDualBound(1.0e8);
00558     //solution.factorization()->maximumPivots(1);
00559     //solution.setLogLevel(3);
00560     solution.setDualTolerance(1.0e-7);
00561     // set objective sense,
00562     ClpDualRowSteepest steep;
00563     solution.setDualRowPivotAlgorithm(steep);
00564     solution.setDblParam(ClpObjOffset,m.objectiveOffset());
00565     solution.dual();
00566   }
00567   // test normal solution
00568   {    
00569     CoinMpsIO m;
00570     std::string fn = netlibDir+"afiro";
00571     m.readMps(fn.c_str(),"mps");
00572     ClpSimplex solution;
00573     ClpModel model;
00574     // do twice - without and with scaling
00575     int iPass;
00576     for (iPass=0;iPass<2;iPass++) {
00577       // explicit row objective for testing
00578       int nr = m.getNumRows();
00579       double * rowObj = new double[nr];
00580       CoinFillN(rowObj,nr,0.0);
00581       model.loadProblem(*m.getMatrixByCol(),m.getColLower(),m.getColUpper(),
00582                       m.getObjCoefficients(),
00583                       m.getRowLower(),m.getRowUpper(),rowObj);
00584       delete [] rowObj;
00585       solution = ClpSimplex(model);
00586       if (iPass) {
00587         solution.scaling();
00588       }
00589       solution.dual();
00590       solution.dual();
00591       // test optimal
00592       assert (solution.status()==0);
00593       int numberColumns = solution.numberColumns();
00594       int numberRows = solution.numberRows();
00595       CoinPackedVector colsol(numberColumns,solution.primalColumnSolution());
00596       double * objective = solution.objective();
00597       double objValue = colsol.dotProduct(objective);
00598       CoinRelFltEq eq(1.0e-8);
00599       assert(eq(objValue,-4.6475314286e+02));
00600       double * lower = solution.columnLower();
00601       double * upper = solution.columnUpper();
00602       double * sol = solution.primalColumnSolution();
00603       double * result = new double[numberColumns];
00604       CoinFillN ( result, numberColumns,0.0);
00605       solution.matrix()->transposeTimes(solution.dualRowSolution(), result);
00606       int iRow , iColumn;
00607       // see if feasible and dual feasible
00608       for (iColumn=0;iColumn<numberColumns;iColumn++) {
00609         double value = sol[iColumn];
00610         assert(value<upper[iColumn]+1.0e-8);
00611         assert(value>lower[iColumn]-1.0e-8);
00612         value = objective[iColumn]-result[iColumn];
00613         assert (value>-1.0e-5);
00614         if (sol[iColumn]>1.0e-5)
00615           assert (value<1.0e-5);
00616       }
00617       delete [] result;
00618       result = new double[numberRows];
00619       CoinFillN ( result, numberRows,0.0);
00620       solution.matrix()->times(colsol, result);
00621       lower = solution.rowLower();
00622       upper = solution.rowUpper();
00623       sol = solution.primalRowSolution();
00624       for (iRow=0;iRow<numberRows;iRow++) {
00625         double value = result[iRow];
00626         assert(eq(value,sol[iRow]));
00627         assert(value<upper[iRow]+1.0e-8);
00628         assert(value>lower[iRow]-1.0e-8);
00629       }
00630       delete [] result;
00631       // test row objective
00632       double * rowObjective = solution.rowObjective();
00633       CoinDisjointCopyN(solution.dualRowSolution(),numberRows,rowObjective);
00634       CoinDisjointCopyN(solution.dualColumnSolution(),numberColumns,objective);
00635       // this sets up all slack basis
00636       solution.createStatus();
00637       solution.dual();
00638       CoinFillN(rowObjective,numberRows,0.0);
00639       CoinDisjointCopyN(m.getObjCoefficients(),numberColumns,objective);
00640       solution.dual();
00641     }
00642   }
00643   // test unbounded
00644   {    
00645     CoinMpsIO m;
00646     std::string fn = netlibDir+"brandy";
00647     m.readMps(fn.c_str(),"mps");
00648     ClpSimplex solution;
00649     // do twice - without and with scaling
00650     int iPass;
00651     for (iPass=0;iPass<2;iPass++) {
00652       solution.loadProblem(*m.getMatrixByCol(),m.getColLower(),m.getColUpper(),
00653                       m.getObjCoefficients(),
00654                       m.getRowLower(),m.getRowUpper());
00655       if (iPass)
00656         solution.scaling();
00657       solution.setOptimizationDirection(-1);
00658       // test unbounded and ray
00659 #ifdef DUAL
00660       solution.setDualBound(100.0);
00661       solution.dual();
00662 #else
00663       solution.primal();
00664 #endif
00665       assert (solution.status()==2);
00666       int numberColumns = solution.numberColumns();
00667       int numberRows = solution.numberRows();
00668       double * lower = solution.columnLower();
00669       double * upper = solution.columnUpper();
00670       double * sol = solution.primalColumnSolution();
00671       double * ray = solution.unboundedRay();
00672       double * objective = solution.objective();
00673       double objChange=0.0;
00674       int iRow , iColumn;
00675       // make sure feasible and columns form ray
00676       for (iColumn=0;iColumn<numberColumns;iColumn++) {
00677         double value = sol[iColumn];
00678         assert(value<upper[iColumn]+1.0e-8);
00679         assert(value>lower[iColumn]-1.0e-8);
00680         value = ray[iColumn];
00681         if (value>0.0)
00682           assert(upper[iColumn]>1.0e30);
00683         else if (value<0.0)
00684           assert(lower[iColumn]<-1.0e30);
00685         objChange += value*objective[iColumn];
00686       }
00687       // make sure increasing objective
00688       assert(objChange>0.0);
00689       double * result = new double[numberRows];
00690       CoinFillN ( result, numberRows,0.0);
00691       solution.matrix()->times(sol, result);
00692       lower = solution.rowLower();
00693       upper = solution.rowUpper();
00694       sol = solution.primalRowSolution();
00695       for (iRow=0;iRow<numberRows;iRow++) {
00696         double value = result[iRow];
00697         assert(eq(value,sol[iRow]));
00698         assert(value<upper[iRow]+2.0e-8);
00699         assert(value>lower[iRow]-2.0e-8);
00700       }
00701       CoinFillN ( result, numberRows,0.0);
00702       solution.matrix()->times(ray, result);
00703       // there may be small differences (especially if scaled)
00704       for (iRow=0;iRow<numberRows;iRow++) {
00705         double value = result[iRow];
00706         if (value>1.0e-8)
00707           assert(upper[iRow]>1.0e30);
00708         else if (value<-1.0e-8)
00709           assert(lower[iRow]<-1.0e30);
00710       }
00711       delete [] result;
00712       delete [] ray;
00713     }
00714   }
00715   // test infeasible
00716   {    
00717     CoinMpsIO m;
00718     std::string fn = netlibDir+"brandy";
00719     m.readMps(fn.c_str(),"mps");
00720     ClpSimplex solution;
00721     // do twice - without and with scaling
00722     int iPass;
00723     for (iPass=0;iPass<2;iPass++) {
00724       solution.loadProblem(*m.getMatrixByCol(),m.getColLower(),m.getColUpper(),
00725                       m.getObjCoefficients(),
00726                       m.getRowLower(),m.getRowUpper());
00727       if (iPass)
00728         solution.scaling();
00729       // test infeasible and ray
00730       solution.columnUpper()[0]=0.0;
00731 #ifdef DUAL
00732       solution.setDualBound(100.0);
00733       solution.dual();
00734 #else
00735       solution.primal();
00736 #endif
00737       assert (solution.status()==1);
00738       int numberColumns = solution.numberColumns();
00739       int numberRows = solution.numberRows();
00740       double * lower = solution.rowLower();
00741       double * upper = solution.rowUpper();
00742       double * ray = solution.infeasibilityRay();
00743       assert(ray);
00744       // construct proof of infeasibility
00745       int iRow , iColumn;
00746       double lo=0.0,up=0.0;
00747       int nl=0,nu=0;
00748       for (iRow=0;iRow<numberRows;iRow++) {
00749         if (lower[iRow]>-1.0e20) {
00750           lo += ray[iRow]*lower[iRow];
00751         } else {
00752           if (ray[iRow]>1.0e-8) 
00753             nl++;
00754         }
00755         if (upper[iRow]<1.0e20) {
00756           up += ray[iRow]*upper[iRow];
00757         } else {
00758           if (ray[iRow]>1.0e-8) 
00759             nu++;
00760         }
00761       }
00762       if (nl)
00763         lo=-1.0e100;
00764       if (nu)
00765         up=1.0e100;
00766       double * result = new double[numberColumns];
00767       double lo2=0.0,up2=0.0;
00768       CoinFillN ( result, numberColumns,0.0);
00769       solution.matrix()->transposeTimes(ray, result);
00770       lower = solution.columnLower();
00771       upper = solution.columnUpper();
00772       nl=nu=0;
00773       for (iColumn=0;iColumn<numberColumns;iColumn++) {
00774         if (result[iColumn]>1.0e-8) {
00775           if (lower[iColumn]>-1.0e20)
00776             lo2 += result[iColumn]*lower[iColumn];
00777           else
00778             nl++;
00779           if (upper[iColumn]<1.0e20)
00780             up2 += result[iColumn]*upper[iColumn];
00781           else
00782             nu++;
00783         } else if (result[iColumn]<-1.0e-8) {
00784           if (lower[iColumn]>-1.0e20)
00785             up2 += result[iColumn]*lower[iColumn];
00786           else
00787             nu++;
00788           if (upper[iColumn]<1.0e20)
00789             lo2 += result[iColumn]*upper[iColumn];
00790           else
00791             nl++;
00792         }
00793       }
00794       if (nl)
00795         lo2=-1.0e100;
00796       if (nu)
00797         up2=1.0e100;
00798       // make sure inconsistency
00799       assert(lo2>up||up2<lo);
00800       delete [] result;
00801       delete [] ray;
00802     }
00803   }
00804   // test delete and add
00805   {    
00806     CoinMpsIO m;
00807     std::string fn = netlibDir+"brandy";
00808     m.readMps(fn.c_str(),"mps");
00809     ClpSimplex solution;
00810     solution.loadProblem(*m.getMatrixByCol(),m.getColLower(),m.getColUpper(),
00811                          m.getObjCoefficients(),
00812                          m.getRowLower(),m.getRowUpper());
00813     solution.dual();
00814     CoinRelFltEq eq(1.0e-8);
00815     assert(eq(solution.objectiveValue(),1.5185098965e+03));
00816 
00817     int numberColumns = solution.numberColumns();
00818     int numberRows = solution.numberRows();
00819     double * saveObj = new double [numberColumns];
00820     double * saveLower = new double[numberRows+numberColumns];
00821     double * saveUpper = new double[numberRows+numberColumns];
00822     int * which = new int [numberRows+numberColumns];
00823 
00824     int numberElements = m.getMatrixByCol()->getNumElements();
00825     int * starts = new int[numberRows+numberColumns];
00826     int * index = new int[numberElements];
00827     double * element = new double[numberElements];
00828 
00829     const int * startM;
00830     const int * lengthM;
00831     const int * indexM;
00832     const double * elementM;
00833 
00834     int n,nel;
00835 
00836     // delete non basic columns
00837     n=0;
00838     nel=0;
00839     int iRow , iColumn;
00840     double * lower = solution.columnLower();
00841     double * upper = solution.columnUpper();
00842     double * objective = solution.objective();
00843     startM = m.getMatrixByCol()->getVectorStarts();
00844     lengthM = m.getMatrixByCol()->getVectorLengths();
00845     indexM = m.getMatrixByCol()->getIndices();
00846     elementM = m.getMatrixByCol()->getElements();
00847     starts[0]=0;
00848     for (iColumn=0;iColumn<numberColumns;iColumn++) {
00849       if (solution.getColumnStatus(iColumn)!=ClpSimplex::basic) {
00850         saveObj[n]=objective[iColumn];
00851         saveLower[n]=lower[iColumn];
00852         saveUpper[n]=upper[iColumn];
00853         int j;
00854         for (j=startM[iColumn];j<startM[iColumn]+lengthM[iColumn];j++) {
00855           index[nel]=indexM[j];
00856           element[nel++]=elementM[j];
00857         }
00858         which[n++]=iColumn;
00859         starts[n]=nel;
00860       }
00861     }
00862     solution.deleteColumns(n,which);
00863     solution.dual();
00864     // Put back
00865     solution.addColumns(n,saveLower,saveUpper,saveObj,
00866                         starts,index,element);
00867     solution.dual();
00868     assert(eq(solution.objectiveValue(),1.5185098965e+03));
00869 
00870     // reload with original
00871     solution.loadProblem(*m.getMatrixByCol(),m.getColLower(),m.getColUpper(),
00872                          m.getObjCoefficients(),
00873                          m.getRowLower(),m.getRowUpper());
00874     // delete half rows
00875     n=0;
00876     nel=0;
00877     lower = solution.rowLower();
00878     upper = solution.rowUpper();
00879     startM = m.getMatrixByRow()->getVectorStarts();
00880     lengthM = m.getMatrixByRow()->getVectorLengths();
00881     indexM = m.getMatrixByRow()->getIndices();
00882     elementM = m.getMatrixByRow()->getElements();
00883     starts[0]=0;
00884     for (iRow=0;iRow<numberRows;iRow++) {
00885       if ((iRow&1)==0) {
00886         saveLower[n]=lower[iRow];
00887         saveUpper[n]=upper[iRow];
00888         int j;
00889         for (j=startM[iRow];j<startM[iRow]+lengthM[iRow];j++) {
00890           index[nel]=indexM[j];
00891           element[nel++]=elementM[j];
00892         }
00893         which[n++]=iRow;
00894         starts[n]=nel;
00895       }
00896     }
00897     solution.deleteRows(n,which);
00898     solution.dual();
00899     // Put back
00900     solution.addRows(n,saveLower,saveUpper,
00901                         starts,index,element);
00902     solution.dual();
00903     assert(eq(solution.objectiveValue(),1.5185098965e+03));
00904     // Zero out status array to give some interest
00905     memset(solution.statusArray()+numberColumns,0,numberRows);
00906     solution.primal(1);
00907     assert(eq(solution.objectiveValue(),1.5185098965e+03));
00908 
00909     delete [] saveObj;
00910     delete [] saveLower;
00911     delete [] saveUpper;
00912     delete [] which;
00913     delete [] starts;
00914     delete [] index;
00915     delete [] element;
00916   }
00917 #if 0
00918   // Test barrier
00919   {
00920     CoinMpsIO m;
00921     std::string fn = mpsDir+"exmip1";
00922     m.readMps(fn.c_str(),"mps");
00923     ClpInterior solution;
00924     solution.loadProblem(*m.getMatrixByCol(),m.getColLower(),m.getColUpper(),
00925                          m.getObjCoefficients(),
00926                          m.getRowLower(),m.getRowUpper());
00927     solution.primalDual();
00928   }
00929 #endif
00930   // test network 
00931   //#define QUADRATIC
00932 #ifndef QUADRATIC
00933   if (1) {    
00934     std::string fn = mpsDir+"input.130";
00935     int numberColumns;
00936     int numberRows;
00937     
00938     FILE * fp = fopen(fn.c_str(),"r");
00939     if (!fp) {
00940       // Try in Samples
00941       fn = "Samples/input.130";
00942       fp = fopen(fn.c_str(),"r");
00943     }
00944     if (!fp) {
00945       fprintf(stderr,"Unable to open file input.130 in mpsDir or Samples directory\n");
00946     } else {
00947       int problem;
00948       char temp[100];
00949       // read and skip 
00950       fscanf(fp,"%s",temp);
00951       assert (!strcmp(temp,"BEGIN"));
00952       fscanf(fp,"%*s %*s %d %d %*s %*s %d %*s",&problem, &numberRows, 
00953              &numberColumns);
00954       // scan down to SUPPLY
00955       while (fgets(temp,100,fp)) {
00956         if (!strncmp(temp,"SUPPLY",6))
00957           break;
00958       }
00959       if (strncmp(temp,"SUPPLY",6)) {
00960         fprintf(stderr,"Unable to find SUPPLY\n");
00961         exit(2);
00962       }
00963       // get space for rhs
00964       double * lower = new double[numberRows];
00965       double * upper = new double[numberRows];
00966       int i;
00967       for (i=0;i<numberRows;i++) {
00968         lower[i]=0.0;
00969         upper[i]=0.0;
00970       }
00971       // ***** Remember to convert to C notation
00972       while (fgets(temp,100,fp)) {
00973         int row;
00974         int value;
00975         if (!strncmp(temp,"ARCS",4))
00976           break;
00977         sscanf(temp,"%d %d",&row,&value);
00978         upper[row-1]=-value;
00979         lower[row-1]=-value;
00980       }
00981       if (strncmp(temp,"ARCS",4)) {
00982         fprintf(stderr,"Unable to find ARCS\n");
00983         exit(2);
00984       }
00985       // number of columns may be underestimate
00986       int * head = new int[2*numberColumns];
00987       int * tail = new int[2*numberColumns];
00988       int * ub = new int[2*numberColumns];
00989       int * cost = new int[2*numberColumns];
00990       // ***** Remember to convert to C notation
00991       numberColumns=0;
00992       while (fgets(temp,100,fp)) {
00993         int iHead;
00994         int iTail;
00995         int iUb;
00996         int iCost;
00997         if (!strncmp(temp,"DEMAND",6))
00998           break;
00999         sscanf(temp,"%d %d %d %d",&iHead,&iTail,&iCost,&iUb);
01000         iHead--;
01001         iTail--;
01002         head[numberColumns]=iHead;
01003         tail[numberColumns]=iTail;
01004         ub[numberColumns]=iUb;
01005         cost[numberColumns]=iCost;
01006         numberColumns++;
01007       }
01008       if (strncmp(temp,"DEMAND",6)) {
01009         fprintf(stderr,"Unable to find DEMAND\n");
01010         exit(2);
01011       }
01012       // ***** Remember to convert to C notation
01013       while (fgets(temp,100,fp)) {
01014         int row;
01015         int value;
01016         if (!strncmp(temp,"END",3))
01017           break;
01018         sscanf(temp,"%d %d",&row,&value);
01019         upper[row-1]=value;
01020         lower[row-1]=value;
01021       }
01022       if (strncmp(temp,"END",3)) {
01023         fprintf(stderr,"Unable to find END\n");
01024         exit(2);
01025       }
01026       printf("Problem %d has %d rows and %d columns\n",problem,
01027              numberRows,numberColumns);
01028       fclose(fp);
01029       ClpSimplex  model;
01030       // now build model
01031       
01032       double * objective =new double[numberColumns];
01033       double * lowerColumn = new double[numberColumns];
01034       double * upperColumn = new double[numberColumns];
01035       
01036       double * element = new double [2*numberColumns];
01037       int * start = new int[numberColumns+1];
01038       int * row = new int[2*numberColumns];
01039       start[numberColumns]=2*numberColumns;
01040       for (i=0;i<numberColumns;i++) {
01041         start[i]=2*i;
01042         element[2*i]=-1.0;
01043         element[2*i+1]=1.0;
01044         row[2*i]=head[i];
01045         row[2*i+1]=tail[i];
01046         lowerColumn[i]=0.0;
01047         upperColumn[i]=ub[i];
01048         objective[i]=cost[i];
01049       }
01050       // Create Packed Matrix
01051       CoinPackedMatrix matrix;
01052       int * lengths = NULL;
01053       matrix.assignMatrix(true,numberRows,numberColumns,
01054                           2*numberColumns,element,row,start,lengths);
01055       // load model
01056       
01057       model.loadProblem(matrix,
01058                         lowerColumn,upperColumn,objective,
01059                         lower,upper);
01060       
01061       model.factorization()->maximumPivots(200+model.numberRows()/100);
01062       model.createStatus();
01063       double time1 = CoinCpuTime();
01064       model.dual();
01065       std::cout<<"Network problem, ClpPackedMatrix took "<<CoinCpuTime()-time1<<" seconds"<<std::endl;
01066       ClpPlusMinusOneMatrix plusMinus(matrix);
01067       assert (plusMinus.getIndices()); // would be zero if not +- one
01068       model.loadProblem(plusMinus,
01069                         lowerColumn,upperColumn,objective,
01070                         lower,upper);
01071       
01072       model.factorization()->maximumPivots(200+model.numberRows()/100);
01073       model.createStatus();
01074       time1 = CoinCpuTime();
01075       model.dual();
01076       std::cout<<"Network problem, ClpPlusMinusOneMatrix took "<<CoinCpuTime()-time1<<" seconds"<<std::endl;
01077       ClpNetworkMatrix network(numberColumns,head,tail);
01078       model.loadProblem(network,
01079                         lowerColumn,upperColumn,objective,
01080                         lower,upper);
01081       
01082       model.factorization()->maximumPivots(200+model.numberRows()/100);
01083       model.createStatus();
01084       time1 = CoinCpuTime();
01085       model.dual();
01086       std::cout<<"Network problem, ClpNetworkMatrix took "<<CoinCpuTime()-time1<<" seconds"<<std::endl;
01087       delete [] lower;
01088       delete [] upper;
01089       delete [] head;
01090       delete [] tail;
01091       delete [] ub;
01092       delete [] cost;
01093       delete [] objective;
01094       delete [] lowerColumn;
01095       delete [] upperColumn;
01096     }
01097   }
01098 #endif
01099 #ifdef QUADRATIC
01100   // Test quadratic to solve linear
01101   if (1) {    
01102     CoinMpsIO m;
01103     std::string fn = mpsDir+"exmip1";
01104     m.readMps(fn.c_str(),"mps");
01105     ClpSimplex solution;
01106     solution.loadProblem(*m.getMatrixByCol(),m.getColLower(),m.getColUpper(),
01107                          m.getObjCoefficients(),
01108                          m.getRowLower(),m.getRowUpper());
01109     //solution.dual();
01110     // get quadratic part
01111     int numberColumns=solution.numberColumns();
01112     int * start=new int [numberColumns+1];
01113     int * column = new int[numberColumns];
01114     double * element = new double[numberColumns];
01115     int i;
01116     start[0]=0;
01117     int n=0;
01118     int kk=numberColumns-1;
01119     int kk2=numberColumns-1;
01120     for (i=0;i<numberColumns;i++) {
01121       if (i>=kk) {
01122         column[n]=i;
01123         if (i>=kk2)
01124           element[n]=1.0e-1;
01125         else
01126           element[n]=0.0;
01127         n++;
01128       }
01129       start[i+1]=n;
01130     }
01131     // Load up objective
01132     solution.loadQuadraticObjective(numberColumns,start,column,element);
01133     delete [] start;
01134     delete [] column;
01135     delete [] element;
01136     //solution.quadraticSLP(50,1.0e-4);
01137     double objValue = solution.getObjValue();
01138     CoinRelFltEq eq(1.0e-4);
01139     //assert(eq(objValue,820.0));
01140     solution.setLogLevel(63);
01141     solution.quadraticPrimal(1);
01142     objValue = solution.getObjValue();
01143     //assert(eq(objValue,3.2368421));
01144     //exit(77);
01145   }
01146   // Test quadratic
01147   if (1) {    
01148     CoinMpsIO m;
01149     std::string fn = mpsDir+"share2qp";
01150     //fn = "share2qpb";
01151     m.readMps(fn.c_str(),"mps");
01152     ClpSimplex model;
01153     model.loadProblem(*m.getMatrixByCol(),m.getColLower(),m.getColUpper(),
01154                          m.getObjCoefficients(),
01155                          m.getRowLower(),m.getRowUpper());
01156     model.dual();
01157     // get quadratic part
01158     int * start=NULL;
01159     int * column = NULL;
01160     double * element = NULL;
01161     m.readQuadraticMps(NULL,start,column,element,2);
01162     int column2[200];
01163     double element2[200];
01164     int start2[80];
01165     int j;
01166     start2[0]=0;
01167     int nel=0;
01168     bool good=false;
01169     for (j=0;j<79;j++) {
01170       if (start[j]==start[j+1]) {
01171         column2[nel]=j;
01172         element2[nel]=0.0;
01173         nel++;
01174       } else {
01175         int i;
01176         for (i=start[j];i<start[j+1];i++) {
01177           column2[nel]=column[i];
01178           element2[nel++]=element[i];
01179         }
01180       }
01181       start2[j+1]=nel;
01182     }
01183     // Load up objective
01184     if (good)
01185       model.loadQuadraticObjective(model.numberColumns(),start2,column2,element2);
01186     else
01187       model.loadQuadraticObjective(model.numberColumns(),start,column,element);
01188     delete [] start;
01189     delete [] column;
01190     delete [] element;
01191     int numberColumns=model.numberColumns();
01192 #if 0
01193     model.quadraticSLP(50,1.0e-4);
01194 #else
01195     // Get feasible
01196     ClpObjective * saveObjective = model.objectiveAsObject()->clone();
01197     ClpLinearObjective zeroObjective(NULL,numberColumns);
01198     model.setObjective(&zeroObjective);
01199     model.dual();
01200     model.setObjective(saveObjective);
01201     delete saveObjective;
01202 #endif
01203     model.setLogLevel(63);
01204     //exit(77);
01205     model.setFactorizationFrequency(10);
01206     model.quadraticPrimal(1);
01207     double objValue = model.getObjValue();
01208     const double * solution = model.primalColumnSolution();
01209     int i;
01210     for (i=0;i<numberColumns;i++)
01211       if (solution[i])
01212         printf("%d %g\n",i,solution[i]);
01213     CoinRelFltEq eq(1.0e-4);
01214     assert(eq(objValue,-400.92));
01215   }
01216   if (0) {    
01217     CoinMpsIO m;
01218     std::string fn = "./beale";
01219     //fn = "./jensen";
01220     m.readMps(fn.c_str(),"mps");
01221     ClpSimplex solution;
01222     solution.loadProblem(*m.getMatrixByCol(),m.getColLower(),m.getColUpper(),
01223                          m.getObjCoefficients(),
01224                          m.getRowLower(),m.getRowUpper());
01225     solution.setDblParam(ClpObjOffset,m.objectiveOffset());
01226     solution.dual();
01227     // get quadratic part
01228     int * start=NULL;
01229     int * column = NULL;
01230     double * element = NULL;
01231     m.readQuadraticMps(NULL,start,column,element,2);
01232     // Load up objective
01233     solution.loadQuadraticObjective(solution.numberColumns(),start,column,element);
01234     delete [] start;
01235     delete [] column;
01236     delete [] element;
01237     solution.quadraticPrimal(1);
01238     solution.quadraticSLP(50,1.0e-4);
01239     double objValue = solution.getObjValue();
01240     CoinRelFltEq eq(1.0e-4);
01241     assert(eq(objValue,0.5));
01242     solution.quadraticPrimal();
01243     objValue = solution.getObjValue();
01244     assert(eq(objValue,0.5));
01245   }
01246 #endif  
01247 }


Member Data Documentation

int ClpSimplex::forceFactorization_ [protected]
 

Now for some reliability aids This forces re-factorization early

Definition at line 907 of file ClpSimplex.hpp.

Referenced by forceFactorization(), gutsOfCopy(), and housekeeping().

float ClpSimplex::incomingInfeasibility_ [protected]
 

For advanced use. When doing iterative solves things can get nasty so on values pass if incoming solution has largest infeasibility < incomingInfeasibility throw out variables from basis until largest infeasibility < allowedInfeasibility. if allowedInfeasibility>= incomingInfeasibility this is always possible altough you may end up with an all slack basis.

Defaults are 1.0,10.0

Definition at line 947 of file ClpSimplex.hpp.

Referenced by gutsOfCopy(), gutsOfSolution(), and setValuesPassAction().

ClpNonLinearCost* ClpSimplex::nonLinearCost_ [protected]
 

Very wasteful way of dealing with infeasibilities in primal. However it will allow non-linearities and use of dual analysis. If it doesn't work it can easily be replaced.

Definition at line 922 of file ClpSimplex.hpp.

Referenced by ClpSimplex(), createPiecewiseLinearCosts(), gutsOfCopy(), gutsOfDelete(), gutsOfSolution(), nonLinearCost(), operator=(), originalModel(), startup(), and ~ClpSimplex().

int ClpSimplex::perturbation_ [protected]
 

Perturbation: -50 to +50 - perturb by this power of ten (-6 sounds good) 100 - auto perturb if takes too long (1.0e-6 largest nonzero) 101 - we are perturbed 102 - don't try perturbing again default is 100

Definition at line 915 of file ClpSimplex.hpp.

Referenced by dual(), gutsOfCopy(), initialSolve(), perturbation(), primal(), restoreData(), saveData(), and startup().

unsigned int ClpSimplex::specialOptions_ [protected]
 

For advanced options 1 - Don't keep changing infeasibility weight 2 - Keep nonLinearCost round solves 4 - Force outgoing variables to exact bound (primal) 8 - Safe to use dense initial factorization

Definition at line 929 of file ClpSimplex.hpp.

Referenced by ClpSimplex(), createPiecewiseLinearCosts(), gutsOfCopy(), gutsOfDelete(), gutsOfSolution(), operator=(), restoreModel(), saveModel(), and setInitialDenseFactorization().


The documentation for this class was generated from the following files:
Generated on Wed Dec 3 14:37:45 2003 for CLP by doxygen 1.3.5