#include <ClpSimplex.hpp>
Inheritance diagram for ClpSimplex:
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) |
ClpSimplex & | operator= (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 () |
CoinIndexedVector * | rowArray (int index) const |
Useful row length arrays (0,1,2,3,4,5). | |
CoinIndexedVector * | columnArray (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) |
ClpNonLinearCost * | nonLinearCost () 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. | |
CoinIndexedVector * | rowArray_ [6] |
Useful row length arrays. | |
CoinIndexedVector * | columnArray_ [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. | |
ClpDualRowPivot * | dualRowPivot_ |
dual row pivot choice | |
ClpPrimalColumnPivot * | primalColumnPivot_ |
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. | |
ClpNonLinearCost * | nonLinearCost_ |
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_ |
ClpSimplexProgress * | progress_ |
For dealing with all issues of cycling etc. | |
Friends | |
void | ClpSimplexUnitTest (const std::string &mpsDir, const std::string &netlibDir) |
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.
|
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 }; |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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_;} ; |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
Return direction In or Out Definition at line 618 of file ClpSimplex.hpp. References directionIn_.
00619 {return directionIn_;}; |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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:
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 } |
|
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 } |
|
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_;}; |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
|
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 } |
|
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 } |
|
Return sequence In or Out Definition at line 608 of file ClpSimplex.hpp. References sequenceIn_. Referenced by housekeeping(), and ClpNetworkBasis::replaceColumn().
00609 {return sequenceIn_;}; |
|
Set directionIn or Out Definition at line 623 of file ClpSimplex.hpp. References directionIn_.
00624 { directionIn_=direction;}; |
|
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 } |
|
Set sequenceIn or Out Definition at line 613 of file ClpSimplex.hpp. References sequenceIn_.
00614 { sequenceIn_=sequence;}; |
|
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 } |
|
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_;}; |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
Return
Definition at line 2369 of file ClpSimplex.cpp. References columnScale_, rowScale_, and ClpMatrixBase::times(). Referenced by cleanStatus(), computePrimals(), ClpSimplexPrimalQuadratic::endQuadratic(), gutsOfSolution(), and ClpSimplexPrimalQuadratic::makeQuadratic().
|
|
Return
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
Now for some reliability aids This forces re-factorization early Definition at line 907 of file ClpSimplex.hpp. Referenced by forceFactorization(), gutsOfCopy(), and housekeeping(). |
|
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(). |
|
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(). |
|
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(). |
|
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(). |