00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef ClpSimplex_H
00011 #define ClpSimplex_H
00012
00013 #include <iostream>
00014 #include <cfloat>
00015 #include "ClpModel.hpp"
00016 #include "ClpMatrixBase.hpp"
00017 #include "ClpSolve.hpp"
00018 class ClpDualRowPivot;
00019 class ClpPrimalColumnPivot;
00020 class ClpFactorization;
00021 class CoinIndexedVector;
00022 class ClpNonLinearCost;
00023 class ClpSimplexProgress;
00024
00046 class ClpSimplex : public ClpModel {
00047 friend void ClpSimplexUnitTest(const std::string & mpsDir,
00048 const std::string & netlibDir);
00049
00050 public:
00055 enum Status {
00056 isFree = 0x00,
00057 basic = 0x01,
00058 atUpperBound = 0x02,
00059 atLowerBound = 0x03,
00060 superBasic = 0x04,
00061 isFixed = 0x05
00062 };
00063
00064 enum FakeBound {
00065 noFake = 0x00,
00066 bothFake = 0x01,
00067 upperFake = 0x02,
00068 lowerFake = 0x03
00069 };
00070
00073
00074 ClpSimplex ( );
00075
00077 ClpSimplex(const ClpSimplex &);
00079 ClpSimplex(const ClpModel &);
00084 ClpSimplex (const ClpModel * wholeModel,
00085 int numberRows, const int * whichRows,
00086 int numberColumns, const int * whichColumns,
00087 bool dropNames=true, bool dropIntegers=true);
00091 ClpSimplex (ClpSimplex * wholeModel,
00092 int numberColumns, const int * whichColumns);
00095 void originalModel(ClpSimplex * miniModel);
00097 ClpSimplex & operator=(const ClpSimplex & rhs);
00099 ~ClpSimplex ( );
00100
00112 void loadProblem ( const ClpMatrixBase& matrix,
00113 const double* collb, const double* colub,
00114 const double* obj,
00115 const double* rowlb, const double* rowub,
00116 const double * rowObjective=NULL);
00117 void loadProblem ( const CoinPackedMatrix& matrix,
00118 const double* collb, const double* colub,
00119 const double* obj,
00120 const double* rowlb, const double* rowub,
00121 const double * rowObjective=NULL);
00122
00125 void loadProblem ( const int numcols, const int numrows,
00126 const CoinBigIndex* start, const int* index,
00127 const double* value,
00128 const double* collb, const double* colub,
00129 const double* obj,
00130 const double* rowlb, const double* rowub,
00131 const double * rowObjective=NULL);
00133 void loadProblem ( const int numcols, const int numrows,
00134 const CoinBigIndex* start, const int* index,
00135 const double* value,const int * length,
00136 const double* collb, const double* colub,
00137 const double* obj,
00138 const double* rowlb, const double* rowub,
00139 const double * rowObjective=NULL);
00141 int readMps(const char *filename,
00142 bool keepNames=false,
00143 bool ignoreErrors = false);
00148 void borrowModel(ClpModel & otherModel);
00150
00156 int initialSolve(ClpSolve & options);
00158 int initialSolve();
00160 int initialDualSolve();
00162 int initialPrimalSolve();
00164 int dual(int ifValuesPass=0);
00166 int primal(int ifValuesPass=0);
00172 int quadraticSLP(int numberPasses,double deltaTolerance);
00174 int quadraticPrimal(int phase=2);
00176 void setFactorization( ClpFactorization & factorization);
00178 void scaling(int mode=1);
00180 inline int scalingFlag() const {return scalingFlag_;};
00190 int tightenPrimalBounds(double factor=0.0);
00205 int crash(double gap,int pivot);
00207 void setDualRowPivotAlgorithm(ClpDualRowPivot & choice);
00209 void setPrimalColumnPivotAlgorithm(ClpPrimalColumnPivot & choice);
00218 int strongBranching(int numberVariables,const int * variables,
00219 double * newLower, double * newUpper,
00220 double ** outputSolution,
00221 int * outputStatus, int * outputIterations,
00222 bool stopOnFirstInfeasible=true,
00223 bool alwaysFinish=false);
00225
00233 int pivot();
00234
00240 int primalPivotResult();
00241
00248 int dualPivotResult();
00249
00253 int startup(int ifValuesPass);
00254 void finish();
00255
00257 bool statusOfProblem();
00259
00262
00263 inline bool primalFeasible() const
00264 { return (numberPrimalInfeasibilities_==0);};
00266 inline bool dualFeasible() const
00267 { return (numberDualInfeasibilities_==0);};
00269 inline ClpFactorization * factorization() const
00270 { return factorization_;};
00272 bool sparseFactorization() const;
00273 void setSparseFactorization(bool value);
00275 int factorizationFrequency() const;
00276 void setFactorizationFrequency(int value);
00278 inline double dualBound() const
00279 { return dualBound_;};
00280 void setDualBound(double value);
00282 inline double infeasibilityCost() const
00283 { return infeasibilityCost_;};
00284 void setInfeasibilityCost(double value);
00301 inline int perturbation() const
00302 { return perturbation_;};
00303 void setPerturbation(int value);
00305 inline int algorithm() const
00306 {return algorithm_; } ;
00308 inline void setAlgorithm(int value)
00309 {algorithm_=value; } ;
00311 inline double sumDualInfeasibilities() const
00312 { return sumDualInfeasibilities_;} ;
00314 inline int numberDualInfeasibilities() const
00315 { return numberDualInfeasibilities_;} ;
00317 inline double sumPrimalInfeasibilities() const
00318 { return sumPrimalInfeasibilities_;} ;
00319 inline void setSumPrimalInfeasibilities(double value)
00320 { sumPrimalInfeasibilities_=value;} ;
00322 inline int numberPrimalInfeasibilities() const
00323 { return numberPrimalInfeasibilities_;} ;
00330 int saveModel(const char * fileName);
00333 int restoreModel(const char * fileName);
00334
00337 void checkSolution();
00339 inline CoinIndexedVector * rowArray(int index) const
00340 { return rowArray_[index];};
00342 inline CoinIndexedVector * columnArray(int index) const
00343 { return columnArray_[index];};
00345
00346
00352 int getSolution ( const double * rowActivities,
00353 const double * columnActivities);
00357 int getSolution ();
00364 int createPiecewiseLinearCosts(const int * starts,
00365 const double * lower, const double * gradient);
00367 void returnModel(ClpSimplex & otherModel);
00374
00375 ClpDataSave saveData() ;
00377 void restoreData(ClpDataSave saved);
00378 int internalFactorize(int solveType);
00380 void cleanStatus();
00382 int factorize();
00385 void computeDuals(double * givenDjs);
00387 void computePrimals ( const double * rowActivities,
00388 const double * columnActivities);
00394 void unpack(CoinIndexedVector * rowArray) const ;
00400 void unpack(CoinIndexedVector * rowArray,int sequence) const;
00407 void unpackPacked(CoinIndexedVector * rowArray) ;
00414 void unpackPacked(CoinIndexedVector * rowArray,int sequence);
00415
00420 int housekeeping(double objectiveChange);
00423 void checkPrimalSolution(const double * rowActivities=NULL,
00424 const double * columnActivies=NULL);
00427 void checkDualSolution();
00438 void setValuesPassAction(float incomingInfeasibility,
00439 float allowedInfeasibility);
00441
00449 void times(double scalar,
00450 const double * x, double * y) const;
00454 void transposeTimes(double scalar,
00455 const double * x, double * y) const ;
00457
00460
00461 inline double columnPrimalInfeasibility() const
00462 { return columnPrimalInfeasibility_;} ;
00464 inline int columnPrimalSequence() const
00465 { return columnPrimalSequence_;} ;
00467 inline double rowPrimalInfeasibility() const
00468 { return rowPrimalInfeasibility_;} ;
00470 inline int rowPrimalSequence() const
00471 { return rowPrimalSequence_;} ;
00474 inline double columnDualInfeasibility() const
00475 { return columnDualInfeasibility_;} ;
00477 inline int columnDualSequence() const
00478 { return columnDualSequence_;} ;
00480 inline double rowDualInfeasibility() const
00481 { return rowDualInfeasibility_;} ;
00483 inline int rowDualSequence() const
00484 { return rowDualSequence_;} ;
00486 inline double primalToleranceToGetOptimal() const
00487 { return primalToleranceToGetOptimal_;} ;
00489 inline double remainingDualInfeasibility() const
00490 { return remainingDualInfeasibility_;} ;
00492 inline double largeValue() const
00493 { return largeValue_;} ;
00494 void setLargeValue( double value) ;
00496 inline double largestPrimalError() const
00497 { return largestPrimalError_;} ;
00499 inline double largestDualError() const
00500 { return largestDualError_;} ;
00502 inline double largestSolutionError() const
00503 { return largestSolutionError_;} ;
00505 inline int * pivotVariable() const
00506 { return pivotVariable_;};
00508 inline double objectiveScale() const
00509 { return objectiveScale_;} ;
00510 inline void setObjectiveScale(double value)
00511 { objectiveScale_ = value;} ;
00513 inline double currentDualTolerance() const
00514 { return dualTolerance_;} ;
00515 inline void setCurrentDualTolerance(double value)
00516 { dualTolerance_ = value;} ;
00518 inline double currentPrimalTolerance() const
00519 { return primalTolerance_;} ;
00520 inline void setCurrentPrimalTolerance(double value)
00521 { primalTolerance_ = value;} ;
00523 inline int numberRefinements() const
00524 { return numberRefinements_;} ;
00525 void setNumberRefinements( int value) ;
00527 inline double alpha() const { return alpha_;};
00529 inline double dualIn() const { return dualIn_;};
00531 inline int pivotRow() const{ return pivotRow_;};
00533 double valueIncomingDual() const;
00535
00536 protected:
00542 int gutsOfSolution ( double * givenDuals,
00543 const double * givenPrimals,
00544 bool valuesPass=false);
00546 void gutsOfDelete(int type);
00548 void gutsOfCopy(const ClpSimplex & rhs);
00558 bool createRim(int what,bool makeRowCopy=false);
00563 void deleteRim(int getRidOfFactorizationData=2);
00565 bool sanityCheck();
00567 public:
00572 inline double * solutionRegion(int section)
00573 { if (!section) return rowActivityWork_; else return columnActivityWork_;};
00574 inline double * djRegion(int section)
00575 { if (!section) return rowReducedCost_; else return reducedCostWork_;};
00576 inline double * lowerRegion(int section)
00577 { if (!section) return rowLowerWork_; else return columnLowerWork_;};
00578 inline double * upperRegion(int section)
00579 { if (!section) return rowUpperWork_; else return columnUpperWork_;};
00580 inline double * costRegion(int section)
00581 { if (!section) return rowObjectiveWork_; else return objectiveWork_;};
00583 inline double * solutionRegion()
00584 { return solution_;};
00585 inline double * djRegion()
00586 { return dj_;};
00587 inline double * lowerRegion()
00588 { return lower_;};
00589 inline double * upperRegion()
00590 { return upper_;};
00591 inline double * costRegion()
00592 { return cost_;};
00593 inline Status getStatus(int sequence) const
00594 {return static_cast<Status> (status_[sequence]&7);};
00595 inline void setStatus(int sequence, Status status)
00596 {
00597 unsigned char & st_byte = status_[sequence];
00598 st_byte &= ~7;
00599 st_byte |= status;
00600 };
00605 void setInitialDenseFactorization(bool onOff);
00606 bool initialDenseFactorization() const;
00608 inline int sequenceIn() const
00609 {return sequenceIn_;};
00610 inline int sequenceOut() const
00611 {return sequenceOut_;};
00613 inline void setSequenceIn(int sequence)
00614 { sequenceIn_=sequence;};
00615 inline void setSequenceOut(int sequence)
00616 { sequenceOut_=sequence;};
00618 inline int directionIn() const
00619 {return directionIn_;};
00620 inline int directionOut() const
00621 {return directionOut_;};
00623 inline void setDirectionIn(int direction)
00624 { directionIn_=direction;};
00625 inline void setDirectionOut(int direction)
00626 { directionOut_=direction;};
00628 inline int isColumn(int sequence) const
00629 { return sequence<numberColumns_ ? 1 : 0;};
00631 inline int sequenceWithin(int sequence) const
00632 { return sequence<numberColumns_ ? sequence : sequence-numberColumns_;};
00634 inline double solution(int sequence)
00635 { return solution_[sequence];};
00637 inline double & solutionAddress(int sequence)
00638 { return solution_[sequence];};
00639 inline double reducedCost(int sequence)
00640 { return dj_[sequence];};
00641 inline double & reducedCostAddress(int sequence)
00642 { return dj_[sequence];};
00643 inline double lower(int sequence)
00644 { return lower_[sequence];};
00646 inline double & lowerAddress(int sequence)
00647 { return lower_[sequence];};
00648 inline double upper(int sequence)
00649 { return upper_[sequence];};
00651 inline double & upperAddress(int sequence)
00652 { return upper_[sequence];};
00653 inline double cost(int sequence)
00654 { return cost_[sequence];};
00656 inline double & costAddress(int sequence)
00657 { return cost_[sequence];};
00659 inline double originalLower(int iSequence) const
00660 { if (iSequence<numberColumns_) return columnLower_[iSequence]; else
00661 return rowLower_[iSequence-numberColumns_];};
00663 inline double originalUpper(int iSequence) const
00664 { if (iSequence<numberColumns_) return columnUpper_[iSequence]; else
00665 return rowUpper_[iSequence-numberColumns_];};
00667 inline double theta() const
00668 { return theta_;};
00670 const double * rowScale() const {return rowScale_;};
00671 const double * columnScale() const {return columnScale_;};
00672 void setRowScale(double * scale) { rowScale_ = scale;};
00673 void setColumnScale(double * scale) { columnScale_ = scale;};
00675 inline ClpNonLinearCost * nonLinearCost() const
00676 { return nonLinearCost_;};
00678
00680 inline void setFakeBound(int sequence, FakeBound fakeBound)
00681 {
00682 unsigned char & st_byte = status_[sequence];
00683 st_byte &= ~24;
00684 st_byte |= fakeBound<<3;
00685 };
00686 inline FakeBound getFakeBound(int sequence) const
00687 {return static_cast<FakeBound> ((status_[sequence]>>3)&3);};
00688 inline void setRowStatus(int sequence, Status status)
00689 {
00690 unsigned char & st_byte = status_[sequence+numberColumns_];
00691 st_byte &= ~7;
00692 st_byte |= status;
00693 };
00694 inline Status getRowStatus(int sequence) const
00695 {return static_cast<Status> (status_[sequence+numberColumns_]&7);};
00696 inline void setColumnStatus(int sequence, Status status)
00697 {
00698 unsigned char & st_byte = status_[sequence];
00699 st_byte &= ~7;
00700 st_byte |= status;
00701 };
00702 inline Status getColumnStatus(int sequence) const
00703 {return static_cast<Status> (status_[sequence]&7);};
00704 inline void setPivoted( int sequence)
00705 { status_[sequence] |= 32;};
00706 inline void clearPivoted( int sequence)
00707 { status_[sequence] &= ~32; };
00708 inline bool pivoted(int sequence) const
00709 {return (((status_[sequence]>>5)&1)!=0);};
00711 inline void setFlagged( int sequence)
00712 {
00713 status_[sequence] |= 64;
00714 };
00715 inline void clearFlagged( int sequence)
00716 {
00717 status_[sequence] &= ~64;
00718 };
00719 inline bool flagged(int sequence) const
00720 {return ((status_[sequence]&64)!=0);};
00722 inline void setActive( int iRow)
00723 {
00724 status_[iRow] |= 128;
00725 };
00726 inline void clearActive( int iRow)
00727 {
00728 status_[iRow] &= ~128;
00729 };
00730 inline bool active(int iRow) const
00731 {return ((status_[iRow]&128)!=0);};
00734 void createStatus() ;
00735 inline void allSlackBasis()
00736 { createStatus();};
00737
00739 inline int lastBadIteration() const
00740 {return lastBadIteration_;};
00742 inline int progressFlag() const
00743 {return progressFlag_;};
00745 inline void forceFactorization(int value)
00746 { forceFactorization_ = value;};
00748 inline double rawObjectiveValue() const
00749 { return objectiveValue_;};
00751
00753 protected:
00754
00761
00762 double columnPrimalInfeasibility_;
00764 double rowPrimalInfeasibility_;
00766 int columnPrimalSequence_;
00768 int rowPrimalSequence_;
00770 double columnDualInfeasibility_;
00772 double rowDualInfeasibility_;
00774 int columnDualSequence_;
00776 int rowDualSequence_;
00778 double primalToleranceToGetOptimal_;
00780 double remainingDualInfeasibility_;
00782 double largeValue_;
00784 double objectiveScale_;
00786 double largestPrimalError_;
00788 double largestDualError_;
00790 double largestSolutionError_;
00792 double dualBound_;
00794 double alpha_;
00796 double theta_;
00798 double lowerIn_;
00800 double valueIn_;
00802 double upperIn_;
00804 double dualIn_;
00806 double lowerOut_;
00808 double valueOut_;
00810 double upperOut_;
00812 double dualOut_;
00814 double dualTolerance_;
00816 double primalTolerance_;
00818 double sumDualInfeasibilities_;
00820 double sumPrimalInfeasibilities_;
00822 double infeasibilityCost_;
00824 double sumOfRelaxedDualInfeasibilities_;
00826 double sumOfRelaxedPrimalInfeasibilities_;
00828 double * lower_;
00830 double * rowLowerWork_;
00832 double * columnLowerWork_;
00834 double * upper_;
00836 double * rowUpperWork_;
00838 double * columnUpperWork_;
00840 double * cost_;
00842 double * rowObjectiveWork_;
00844 double * objectiveWork_;
00846 CoinIndexedVector * rowArray_[6];
00848 CoinIndexedVector * columnArray_[6];
00850 int sequenceIn_;
00852 int directionIn_;
00854 int sequenceOut_;
00856 int directionOut_;
00858 int pivotRow_;
00860 int lastGoodIteration_;
00862 double * dj_;
00864 double * rowReducedCost_;
00866 double * reducedCostWork_;
00868 double * solution_;
00870 double * rowActivityWork_;
00872 double * columnActivityWork_;
00874 int numberDualInfeasibilities_;
00876 int numberDualInfeasibilitiesWithoutFree_;
00878 int numberPrimalInfeasibilities_;
00880 int numberRefinements_;
00882 ClpDualRowPivot * dualRowPivot_;
00884 ClpPrimalColumnPivot * primalColumnPivot_;
00886 int * pivotVariable_;
00888 ClpFactorization * factorization_;
00890
00891
00892 double * rowScale_;
00894 double * savedSolution_;
00896 double * columnScale_;
00898 int scalingFlag_;
00900 int numberTimesOptimal_;
00902 int changeMade_;
00904 int algorithm_;
00907 int forceFactorization_;
00915 int perturbation_;
00917 unsigned char * saveStatus_;
00922 ClpNonLinearCost * nonLinearCost_;
00929 unsigned int specialOptions_;
00931 int lastBadIteration_;
00933 int numberFake_;
00935 int progressFlag_;
00937 int firstFree_;
00947 float incomingInfeasibility_;
00948 float allowedInfeasibility_;
00950 ClpSimplexProgress * progress_;
00952 };
00953
00962 void
00963 ClpSimplexUnitTest(const std::string & mpsDir,
00964 const std::string & netlibDir);
00965
00966
00968 class ClpSimplexProgress {
00969
00970 public:
00971
00972
00975
00976 ClpSimplexProgress ( );
00977
00979 ClpSimplexProgress ( ClpSimplex * model );
00980
00982 ClpSimplexProgress(const ClpSimplexProgress &);
00983
00985 ClpSimplexProgress & operator=(const ClpSimplexProgress & rhs);
00987 ~ClpSimplexProgress ( );
00989
00995 int looping ( );
00997 void startCheck();
00999 int cycle(int in, int out,int wayIn,int wayOut);
01000
01002 double lastObjective(int back=1) const;
01004 void modifyObjective(double value);
01006 int lastIterationNumber(int back=1) const;
01008 inline void newOddState()
01009 { oddState_= - oddState_-1;};
01010 inline void endOddState()
01011 { oddState_=abs(oddState_);};
01012 inline void clearOddState()
01013 { oddState_=0;};
01014 inline int oddState() const
01015 { return oddState_;};
01017 inline int badTimes() const
01018 { return numberBadTimes_;};
01019 inline void clearBadTimes()
01020 { numberBadTimes_=0;};
01021
01023
01024 #define CLP_PROGRESS 5
01025
01026
01027 double objective_[CLP_PROGRESS];
01029 double infeasibility_[CLP_PROGRESS];
01030 #define CLP_CYCLE 12
01031
01032 double obj_[CLP_CYCLE];
01033 int in_[CLP_CYCLE];
01034 int out_[CLP_CYCLE];
01035 char way_[CLP_CYCLE];
01037 ClpSimplex * model_;
01039 int numberInfeasibilities_[CLP_PROGRESS];
01041 int iterationNumber_[CLP_PROGRESS];
01043 int numberTimes_;
01045 int numberBadTimes_;
01047 int oddState_;
01049 };
01050 #endif