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
00080 ClpSimplex(const ClpSimplex & rhs, int scalingMode =-1);
00085 ClpSimplex(const ClpModel & rhs, int scalingMode=-1);
00090 ClpSimplex (const ClpModel * wholeModel,
00091 int numberRows, const int * whichRows,
00092 int numberColumns, const int * whichColumns,
00093 bool dropNames=true, bool dropIntegers=true);
00097 ClpSimplex (ClpSimplex * wholeModel,
00098 int numberColumns, const int * whichColumns);
00101 void originalModel(ClpSimplex * miniModel);
00103 ClpSimplex & operator=(const ClpSimplex & rhs);
00105 ~ClpSimplex ( );
00106
00118 void loadProblem ( const ClpMatrixBase& matrix,
00119 const double* collb, const double* colub,
00120 const double* obj,
00121 const double* rowlb, const double* rowub,
00122 const double * rowObjective=NULL);
00123 void loadProblem ( const CoinPackedMatrix& matrix,
00124 const double* collb, const double* colub,
00125 const double* obj,
00126 const double* rowlb, const double* rowub,
00127 const double * rowObjective=NULL);
00128
00131 void loadProblem ( const int numcols, const int numrows,
00132 const CoinBigIndex* start, const int* index,
00133 const double* value,
00134 const double* collb, const double* colub,
00135 const double* obj,
00136 const double* rowlb, const double* rowub,
00137 const double * rowObjective=NULL);
00139 void loadProblem ( const int numcols, const int numrows,
00140 const CoinBigIndex* start, const int* index,
00141 const double* value,const int * length,
00142 const double* collb, const double* colub,
00143 const double* obj,
00144 const double* rowlb, const double* rowub,
00145 const double * rowObjective=NULL);
00147 int readMps(const char *filename,
00148 bool keepNames=false,
00149 bool ignoreErrors = false);
00154 void borrowModel(ClpModel & otherModel);
00155 void borrowModel(ClpSimplex & otherModel);
00157 void passInEventHandler(const ClpEventHandler * eventHandler);
00159
00165 int initialSolve(ClpSolve & options);
00167 int initialSolve();
00169 int initialDualSolve();
00171 int initialPrimalSolve();
00174 int dual(int ifValuesPass=0);
00177 int primal(int ifValuesPass=0);
00183 int nonlinearSLP(int numberPasses,double deltaTolerance);
00186 int barrier(bool crossover=true);
00189 int reducedGradient(int phase=0);
00201 int dualRanging(int numberCheck,const int * which,
00202 double * costIncrease, int * sequenceIncrease,
00203 double * costDecrease, int * sequenceDecrease);
00214 int primalRanging(int numberCheck,const int * which,
00215 double * valueIncrease, int * sequenceIncrease,
00216 double * valueDecrease, int * sequenceDecrease);
00218 void setFactorization( ClpFactorization & factorization);
00228 int tightenPrimalBounds(double factor=0.0);
00243 int crash(double gap,int pivot);
00245 void setDualRowPivotAlgorithm(ClpDualRowPivot & choice);
00247 void setPrimalColumnPivotAlgorithm(ClpPrimalColumnPivot & choice);
00256 int strongBranching(int numberVariables,const int * variables,
00257 double * newLower, double * newUpper,
00258 double ** outputSolution,
00259 int * outputStatus, int * outputIterations,
00260 bool stopOnFirstInfeasible=true,
00261 bool alwaysFinish=false);
00263
00271 int pivot();
00272
00278 int primalPivotResult();
00279
00286 int dualPivotResult();
00287
00291 int startup(int ifValuesPass);
00292 void finish();
00293
00295 bool statusOfProblem();
00297
00300
00301 inline bool primalFeasible() const
00302 { return (numberPrimalInfeasibilities_==0);};
00304 inline bool dualFeasible() const
00305 { return (numberDualInfeasibilities_==0);};
00307 inline ClpFactorization * factorization() const
00308 { return factorization_;};
00310 bool sparseFactorization() const;
00311 void setSparseFactorization(bool value);
00313 int factorizationFrequency() const;
00314 void setFactorizationFrequency(int value);
00316 inline double dualBound() const
00317 { return dualBound_;};
00318 void setDualBound(double value);
00320 inline double infeasibilityCost() const
00321 { return infeasibilityCost_;};
00322 void setInfeasibilityCost(double value);
00339 inline int perturbation() const
00340 { return perturbation_;};
00341 void setPerturbation(int value);
00343 inline int algorithm() const
00344 {return algorithm_; } ;
00346 inline void setAlgorithm(int value)
00347 {algorithm_=value; } ;
00349 inline double sumDualInfeasibilities() const
00350 { return sumDualInfeasibilities_;} ;
00351 inline void setSumDualInfeasibilities(double value)
00352 { sumDualInfeasibilities_=value;} ;
00354 inline double sumOfRelaxedDualInfeasibilities() const
00355 { return sumOfRelaxedDualInfeasibilities_;} ;
00356 inline void setSumOfRelaxedDualInfeasibilities(double value)
00357 { sumOfRelaxedDualInfeasibilities_=value;} ;
00359 inline int numberDualInfeasibilities() const
00360 { return numberDualInfeasibilities_;} ;
00361 inline void setNumberDualInfeasibilities(int value)
00362 { numberDualInfeasibilities_=value;} ;
00364 inline double sumPrimalInfeasibilities() const
00365 { return sumPrimalInfeasibilities_;} ;
00366 inline void setSumPrimalInfeasibilities(double value)
00367 { sumPrimalInfeasibilities_=value;} ;
00369 inline double sumOfRelaxedPrimalInfeasibilities() const
00370 { return sumOfRelaxedPrimalInfeasibilities_;} ;
00371 inline void setSumOfRelaxedPrimalInfeasibilities(double value)
00372 { sumOfRelaxedPrimalInfeasibilities_=value;} ;
00374 inline int numberPrimalInfeasibilities() const
00375 { return numberPrimalInfeasibilities_;} ;
00376 inline void setNumberPrimalInfeasibilities(int value)
00377 { numberPrimalInfeasibilities_=value;} ;
00384 int saveModel(const char * fileName);
00387 int restoreModel(const char * fileName);
00388
00391 void checkSolution();
00393 inline CoinIndexedVector * rowArray(int index) const
00394 { return rowArray_[index];};
00396 inline CoinIndexedVector * columnArray(int index) const
00397 { return columnArray_[index];};
00399
00400
00406 int getSolution ( const double * rowActivities,
00407 const double * columnActivities);
00411 int getSolution ();
00418 int createPiecewiseLinearCosts(const int * starts,
00419 const double * lower, const double * gradient);
00421 void returnModel(ClpSimplex & otherModel);
00428 int internalFactorize(int solveType);
00430 ClpDataSave saveData() ;
00432 void restoreData(ClpDataSave saved);
00434 void cleanStatus();
00436 int factorize();
00439 void computeDuals(double * givenDjs);
00441 void computePrimals ( const double * rowActivities,
00442 const double * columnActivities);
00444 void add(double * array,
00445 int column, double multiplier) const;
00451 void unpack(CoinIndexedVector * rowArray) const ;
00457 void unpack(CoinIndexedVector * rowArray,int sequence) const;
00464 void unpackPacked(CoinIndexedVector * rowArray) ;
00471 void unpackPacked(CoinIndexedVector * rowArray,int sequence);
00472
00477 int housekeeping(double objectiveChange);
00480 void checkPrimalSolution(const double * rowActivities=NULL,
00481 const double * columnActivies=NULL);
00484 void checkDualSolution();
00495 void setValuesPassAction(float incomingInfeasibility,
00496 float allowedInfeasibility);
00498
00500
00501 inline double columnPrimalInfeasibility() const
00502 { return columnPrimalInfeasibility_;} ;
00504 inline int columnPrimalSequence() const
00505 { return columnPrimalSequence_;} ;
00507 inline double rowPrimalInfeasibility() const
00508 { return rowPrimalInfeasibility_;} ;
00510 inline int rowPrimalSequence() const
00511 { return rowPrimalSequence_;} ;
00514 inline double columnDualInfeasibility() const
00515 { return columnDualInfeasibility_;} ;
00517 inline int columnDualSequence() const
00518 { return columnDualSequence_;} ;
00520 inline double rowDualInfeasibility() const
00521 { return rowDualInfeasibility_;} ;
00523 inline int rowDualSequence() const
00524 { return rowDualSequence_;} ;
00526 inline double primalToleranceToGetOptimal() const
00527 { return primalToleranceToGetOptimal_;} ;
00529 inline double remainingDualInfeasibility() const
00530 { return remainingDualInfeasibility_;} ;
00532 inline double largeValue() const
00533 { return largeValue_;} ;
00534 void setLargeValue( double value) ;
00536 inline double largestPrimalError() const
00537 { return largestPrimalError_;} ;
00539 inline double largestDualError() const
00540 { return largestDualError_;} ;
00542 inline double largestSolutionError() const
00543 { return largestSolutionError_;} ;
00545 inline int * pivotVariable() const
00546 { return pivotVariable_;};
00548 inline bool automaticScaling() const
00549 { return automaticScale_!=0;};
00550 inline void setAutomaticScaling(bool onOff)
00551 { automaticScale_ = onOff ? 1: 0;};
00553 inline double currentDualTolerance() const
00554 { return dualTolerance_;} ;
00555 inline void setCurrentDualTolerance(double value)
00556 { dualTolerance_ = value;} ;
00558 inline double currentPrimalTolerance() const
00559 { return primalTolerance_;} ;
00560 inline void setCurrentPrimalTolerance(double value)
00561 { primalTolerance_ = value;} ;
00563 inline int numberRefinements() const
00564 { return numberRefinements_;} ;
00565 void setNumberRefinements( int value) ;
00567 inline double alpha() const { return alpha_;};
00568 inline void setAlpha(double value) { alpha_ = value;};
00570 inline double dualIn() const { return dualIn_;};
00572 inline int pivotRow() const{ return pivotRow_;};
00573 inline void setPivotRow(int value) { pivotRow_=value;};
00575 double valueIncomingDual() const;
00577
00578 protected:
00584 int gutsOfSolution ( double * givenDuals,
00585 const double * givenPrimals,
00586 bool valuesPass=false);
00588 void gutsOfDelete(int type);
00590 void gutsOfCopy(const ClpSimplex & rhs);
00600 bool createRim(int what,bool makeRowCopy=false);
00605 void deleteRim(int getRidOfFactorizationData=2);
00607 bool sanityCheck();
00609 public:
00614 inline double * solutionRegion(int section) const
00615 { if (!section) return rowActivityWork_; else return columnActivityWork_;};
00616 inline double * djRegion(int section) const
00617 { if (!section) return rowReducedCost_; else return reducedCostWork_;};
00618 inline double * lowerRegion(int section) const
00619 { if (!section) return rowLowerWork_; else return columnLowerWork_;};
00620 inline double * upperRegion(int section) const
00621 { if (!section) return rowUpperWork_; else return columnUpperWork_;};
00622 inline double * costRegion(int section) const
00623 { if (!section) return rowObjectiveWork_; else return objectiveWork_;};
00625 inline double * solutionRegion() const
00626 { return solution_;};
00627 inline double * djRegion() const
00628 { return dj_;};
00629 inline double * lowerRegion() const
00630 { return lower_;};
00631 inline double * upperRegion() const
00632 { return upper_;};
00633 inline double * costRegion() const
00634 { return cost_;};
00635 inline Status getStatus(int sequence) const
00636 {return static_cast<Status> (status_[sequence]&7);};
00637 inline void setStatus(int sequence, Status status)
00638 {
00639 unsigned char & st_byte = status_[sequence];
00640 st_byte &= ~7;
00641 st_byte |= status;
00642 };
00647 void setInitialDenseFactorization(bool onOff);
00648 bool initialDenseFactorization() const;
00650 inline int sequenceIn() const
00651 {return sequenceIn_;};
00652 inline int sequenceOut() const
00653 {return sequenceOut_;};
00655 inline void setSequenceIn(int sequence)
00656 { sequenceIn_=sequence;};
00657 inline void setSequenceOut(int sequence)
00658 { sequenceOut_=sequence;};
00660 inline int directionIn() const
00661 {return directionIn_;};
00662 inline int directionOut() const
00663 {return directionOut_;};
00665 inline void setDirectionIn(int direction)
00666 { directionIn_=direction;};
00667 inline void setDirectionOut(int direction)
00668 { directionOut_=direction;};
00670 inline double valueOut() const
00671 { return valueOut_;};
00673 inline int isColumn(int sequence) const
00674 { return sequence<numberColumns_ ? 1 : 0;};
00676 inline int sequenceWithin(int sequence) const
00677 { return sequence<numberColumns_ ? sequence : sequence-numberColumns_;};
00679 inline double solution(int sequence)
00680 { return solution_[sequence];};
00682 inline double & solutionAddress(int sequence)
00683 { return solution_[sequence];};
00684 inline double reducedCost(int sequence)
00685 { return dj_[sequence];};
00686 inline double & reducedCostAddress(int sequence)
00687 { return dj_[sequence];};
00688 inline double lower(int sequence)
00689 { return lower_[sequence];};
00691 inline double & lowerAddress(int sequence)
00692 { return lower_[sequence];};
00693 inline double upper(int sequence)
00694 { return upper_[sequence];};
00696 inline double & upperAddress(int sequence)
00697 { return upper_[sequence];};
00698 inline double cost(int sequence)
00699 { return cost_[sequence];};
00701 inline double & costAddress(int sequence)
00702 { return cost_[sequence];};
00704 inline double originalLower(int iSequence) const
00705 { if (iSequence<numberColumns_) return columnLower_[iSequence]; else
00706 return rowLower_[iSequence-numberColumns_];};
00708 inline double originalUpper(int iSequence) const
00709 { if (iSequence<numberColumns_) return columnUpper_[iSequence]; else
00710 return rowUpper_[iSequence-numberColumns_];};
00712 inline double theta() const
00713 { return theta_;};
00715 inline ClpNonLinearCost * nonLinearCost() const
00716 { return nonLinearCost_;};
00718
00720 inline void setFakeBound(int sequence, FakeBound fakeBound)
00721 {
00722 unsigned char & st_byte = status_[sequence];
00723 st_byte &= ~24;
00724 st_byte |= fakeBound<<3;
00725 };
00726 inline FakeBound getFakeBound(int sequence) const
00727 {return static_cast<FakeBound> ((status_[sequence]>>3)&3);};
00728 inline void setRowStatus(int sequence, Status status)
00729 {
00730 unsigned char & st_byte = status_[sequence+numberColumns_];
00731 st_byte &= ~7;
00732 st_byte |= status;
00733 };
00734 inline Status getRowStatus(int sequence) const
00735 {return static_cast<Status> (status_[sequence+numberColumns_]&7);};
00736 inline void setColumnStatus(int sequence, Status status)
00737 {
00738 unsigned char & st_byte = status_[sequence];
00739 st_byte &= ~7;
00740 st_byte |= status;
00741 };
00742 inline Status getColumnStatus(int sequence) const
00743 {return static_cast<Status> (status_[sequence]&7);};
00744 inline void setPivoted( int sequence)
00745 { status_[sequence] |= 32;};
00746 inline void clearPivoted( int sequence)
00747 { status_[sequence] &= ~32; };
00748 inline bool pivoted(int sequence) const
00749 {return (((status_[sequence]>>5)&1)!=0);};
00751 void setFlagged( int sequence);
00752 inline void clearFlagged( int sequence)
00753 {
00754 status_[sequence] &= ~64;
00755 };
00756 inline bool flagged(int sequence) const
00757 {return ((status_[sequence]&64)!=0);};
00759 inline void setActive( int iRow)
00760 {
00761 status_[iRow] |= 128;
00762 };
00763 inline void clearActive( int iRow)
00764 {
00765 status_[iRow] &= ~128;
00766 };
00767 inline bool active(int iRow) const
00768 {return ((status_[iRow]&128)!=0);};
00771 void createStatus() ;
00772 inline void allSlackBasis()
00773 { createStatus();};
00774
00776 inline int lastBadIteration() const
00777 {return lastBadIteration_;};
00779 inline int progressFlag() const
00780 {return progressFlag_;};
00782 inline void forceFactorization(int value)
00783 { forceFactorization_ = value;};
00785 inline double rawObjectiveValue() const
00786 { return objectiveValue_;};
00790 inline int numberExtraRows() const
00791 { return numberExtraRows_;};
00794 inline int maximumBasic() const
00795 { return maximumBasic_;};
00804 inline unsigned int specialOptions() const
00805 { return specialOptions_;};
00806 inline void setSpecialOptions(unsigned int value)
00807 { specialOptions_=value;};
00809
00811 protected:
00812
00819
00820 double columnPrimalInfeasibility_;
00822 double rowPrimalInfeasibility_;
00824 int columnPrimalSequence_;
00826 int rowPrimalSequence_;
00828 double columnDualInfeasibility_;
00830 double rowDualInfeasibility_;
00832 int columnDualSequence_;
00834 int rowDualSequence_;
00836 double primalToleranceToGetOptimal_;
00838 double remainingDualInfeasibility_;
00840 double largeValue_;
00842 double largestPrimalError_;
00844 double largestDualError_;
00846 double largestSolutionError_;
00848 double dualBound_;
00850 double alpha_;
00852 double theta_;
00854 double lowerIn_;
00856 double valueIn_;
00858 double upperIn_;
00860 double dualIn_;
00862 double lowerOut_;
00864 double valueOut_;
00866 double upperOut_;
00868 double dualOut_;
00870 double dualTolerance_;
00872 double primalTolerance_;
00874 double sumDualInfeasibilities_;
00876 double sumPrimalInfeasibilities_;
00878 double infeasibilityCost_;
00880 double sumOfRelaxedDualInfeasibilities_;
00882 double sumOfRelaxedPrimalInfeasibilities_;
00884 double * lower_;
00886 double * rowLowerWork_;
00888 double * columnLowerWork_;
00890 double * upper_;
00892 double * rowUpperWork_;
00894 double * columnUpperWork_;
00896 double * cost_;
00898 double * rowObjectiveWork_;
00900 double * objectiveWork_;
00902 CoinIndexedVector * rowArray_[6];
00904 CoinIndexedVector * columnArray_[6];
00906 int sequenceIn_;
00908 int directionIn_;
00910 int sequenceOut_;
00912 int directionOut_;
00914 int pivotRow_;
00916 int lastGoodIteration_;
00918 double * dj_;
00920 double * rowReducedCost_;
00922 double * reducedCostWork_;
00924 double * solution_;
00926 double * rowActivityWork_;
00928 double * columnActivityWork_;
00930 int numberDualInfeasibilities_;
00932 int numberDualInfeasibilitiesWithoutFree_;
00934 int numberPrimalInfeasibilities_;
00936 int numberRefinements_;
00938 ClpDualRowPivot * dualRowPivot_;
00940 ClpPrimalColumnPivot * primalColumnPivot_;
00942 int * pivotVariable_;
00944 ClpFactorization * factorization_;
00946 double * savedSolution_;
00948 int numberTimesOptimal_;
00950 int changeMade_;
00952 int algorithm_;
00955 int forceFactorization_;
00963 int perturbation_;
00965 unsigned char * saveStatus_;
00970 ClpNonLinearCost * nonLinearCost_;
00978 unsigned int specialOptions_;
00980 int lastBadIteration_;
00982 int lastFlaggedIteration_;
00984 int numberFake_;
00986 int progressFlag_;
00988 int firstFree_;
00992 int numberExtraRows_;
00995 int maximumBasic_;
01005 float incomingInfeasibility_;
01006 float allowedInfeasibility_;
01008 int automaticScale_;
01010 ClpSimplexProgress * progress_;
01012 };
01013
01022 void
01023 ClpSimplexUnitTest(const std::string & mpsDir,
01024 const std::string & netlibDir);
01025
01026
01028 class ClpSimplexProgress {
01029
01030 public:
01031
01032
01035
01036 ClpSimplexProgress ( );
01037
01039 ClpSimplexProgress ( ClpSimplex * model );
01040
01042 ClpSimplexProgress(const ClpSimplexProgress &);
01043
01045 ClpSimplexProgress & operator=(const ClpSimplexProgress & rhs);
01047 ~ClpSimplexProgress ( );
01049
01055 int looping ( );
01057 void startCheck();
01059 int cycle(int in, int out,int wayIn,int wayOut);
01060
01062 double lastObjective(int back=1) const;
01064 void setInfeasibility(double value);
01066 double lastInfeasibility(int back=1) const;
01068 void modifyObjective(double value);
01070 int lastIterationNumber(int back=1) const;
01072 inline void newOddState()
01073 { oddState_= - oddState_-1;};
01074 inline void endOddState()
01075 { oddState_=abs(oddState_);};
01076 inline void clearOddState()
01077 { oddState_=0;};
01078 inline int oddState() const
01079 { return oddState_;};
01081 inline int badTimes() const
01082 { return numberBadTimes_;};
01083 inline void clearBadTimes()
01084 { numberBadTimes_=0;};
01085
01087
01088 #define CLP_PROGRESS 5
01089
01090
01091 double objective_[CLP_PROGRESS];
01093 double infeasibility_[CLP_PROGRESS];
01095 double realInfeasibility_[CLP_PROGRESS];
01096 #define CLP_CYCLE 12
01097
01098
01099 int in_[CLP_CYCLE];
01100 int out_[CLP_CYCLE];
01101 char way_[CLP_CYCLE];
01103 ClpSimplex * model_;
01105 int numberInfeasibilities_[CLP_PROGRESS];
01107 int iterationNumber_[CLP_PROGRESS];
01109 int numberTimes_;
01111 int numberBadTimes_;
01113 int oddState_;
01115 };
01116 #endif