00001
00002
00003 #ifndef SbbModel_H
00004 #define SbbModel_H
00005
00006 #include <string>
00007 #include <vector>
00008
00009 #include "CoinFinite.hpp"
00010 #include "CoinMessageHandler.hpp"
00011 #include "OsiSolverInterface.hpp"
00012 #include "OsiCuts.hpp"
00013 #include "CoinWarmStartBasis.hpp"
00014 #include "SbbCompareBase.hpp"
00015 #include "SbbMessage.hpp"
00016
00017
00018
00019 class SbbCutGenerator;
00020 class OsiRowCut;
00021 class OsiRowCutDebugger;
00022 class CglCutGenerator;
00023 class SbbHeuristic;
00024 class SbbObject;
00025
00026
00027
00080 class SbbModel {
00081
00082 public:
00083
00084 enum SbbIntParam {
00086 SbbMaxNumNode=0,
00088 SbbMaxNumSol,
00098 SbbFathomDiscipline,
00100 SbbLastIntParam
00101 };
00102
00103 enum SbbDblParam {
00106 SbbIntegerTolerance=0,
00109 SbbInfeasibilityWeight,
00112 SbbCutoffIncrement,
00119 SbbAllowableGap,
00122 SbbMaximumSeconds,
00124 SbbLastDblParam
00125 };
00126
00127
00128
00129 public:
00131
00132
00136 void initialSolve();
00137
00145 void branchAndBound();
00146
00154 bool solveWithCuts(OsiCuts & cuts, int numberTries,SbbNode * node,
00155 int & numberOldActiveCuts, int & numberNewCuts,
00156 int & maximumWhich, int * & whichGenerator);
00157
00162 bool resolve();
00164
00167
00179 SbbModel * findCliques(bool makeEquality, int atLeastThisMany,
00180 int lessThanThis, int defaultValue=1000);
00181
00190 SbbModel * integerPresolve(bool weak=false);
00191
00196 bool integerPresolveThisModel(OsiSolverInterface * originalSolver,bool weak=false);
00197
00198
00200 void originalModel(SbbModel * presolvedModel,bool weak);
00201
00222 bool tightenVubs(int type,bool allowMultipleBinary=false,
00223 double useCutoff=1.0e50);
00224
00230 bool tightenVubs(int numberVubs, const int * which,
00231 double useCutoff=1.0e50);
00232
00233
00235
00241
00243 inline int numberObjects() const { return numberObjects_;};
00244
00246 inline SbbObject ** objects() const { return object_;};
00247
00249 const inline SbbObject * object(int which) const { return object_[which];};
00250
00252 void deleteObjects();
00253
00258 void addObjects(int numberObjects, SbbObject ** objects);
00259
00261 void synchronizeModel() ;
00262
00271 void findIntegers(bool startAgain);
00272
00274
00275
00276
00286
00287 inline bool setIntParam(SbbIntParam key, int value) {
00288 intParam_[key] = value;
00289 return true;
00290 }
00292 inline bool setDblParam(SbbDblParam key, double value) {
00293 dblParam_[key] = value;
00294 return true;
00295 }
00297 inline int getIntParam(SbbIntParam key) const {
00298 return intParam_[key];
00299 }
00301 inline double getDblParam(SbbDblParam key) const {
00302 return dblParam_[key];
00303 }
00309 void setCutoff(double value) ;
00310
00312 inline double getCutoff() const
00313 { double value ;
00314 solver_->getDblParam(OsiDualObjectiveLimit,value) ;
00315 return value * solver_->getObjSense() ; } ;
00316
00318 inline bool setMaximumNodes( int value)
00319 { return setIntParam(SbbMaxNumNode,value); }
00320
00322 inline int getMaximumNodes() const
00323 { return getIntParam(SbbMaxNumNode); }
00324
00329 inline bool setMaximumSolutions( int value) {
00330 return setIntParam(SbbMaxNumSol,value);
00331 }
00336 inline int getMaximumSolutions() const {
00337 return getIntParam(SbbMaxNumSol);
00338 }
00339
00343 inline bool setIntegerTolerance( double value) {
00344 return setDblParam(SbbIntegerTolerance,value);
00345 }
00349 inline double getIntegerTolerance() const {
00350 return getDblParam(SbbIntegerTolerance);
00351 }
00352
00357 inline bool setInfeasibilityWeight( double value) {
00358 return setDblParam(SbbInfeasibilityWeight,value);
00359 }
00364 inline double getInfeasibilityWeight() const {
00365 return getDblParam(SbbInfeasibilityWeight);
00366 }
00367
00371 inline bool setAllowableGap( double value) {
00372 return setDblParam(SbbAllowableGap,value);
00373 }
00377 inline double getAllowableGap() const {
00378 return getDblParam(SbbAllowableGap);
00379 }
00380
00382 void setForcePriority(int value)
00383 { forcePriority_=value;};
00385 int getForcePriority() const
00386 { return forcePriority_;};
00387
00389 inline void setMinimumDrop(double value)
00390 {minimumDrop_=value;};
00392 inline double getMinimumDrop() const
00393 { return minimumDrop_;};
00394
00397 inline void setMaximumCutPassesAtRoot(int value)
00398 {maximumCutPassesAtRoot_=value;};
00400 inline int getMaximumCutPassesAtRoot() const
00401 { return maximumCutPassesAtRoot_;};
00402
00405 inline void setMaximumCutPasses(int value)
00406 {maximumCutPasses_=value;};
00408 inline int getMaximumCutPasses() const
00409 { return maximumCutPasses_;};
00410
00416 void setNumberStrong(int number);
00420 inline int numberStrong() const
00421 { return numberStrong_;};
00422
00430 void setPrintFrequency(int number)
00431 { printFrequency_=number;};
00433 inline int printFrequency() const
00434 { return printFrequency_;};
00436
00437
00439
00440
00441 bool isAbandoned() const;
00443 bool isProvenOptimal() const;
00445 bool isProvenInfeasible() const;
00447 bool isNodeLimitReached() const;
00449 bool isSolutionLimitReached() const;
00451 int getIterationCount() const
00452 { return solver_->getIterationCount();};
00454 int getNodeCount() const
00455 { return numberNodes_;};
00460 inline int status() const
00461 { return status_;};
00462
00464
00465
00478
00479 int numberRowsAtContinuous() const
00480 { return numberRowsAtContinuous_;};
00481
00483 int getNumCols() const
00484 { return solver_->getNumCols();};
00485
00487 int getNumRows() const
00488 { return solver_->getNumRows();};
00489
00491 int getNumElements() const
00492 { return solver_->getNumElements();};
00493
00495 inline int numberIntegers() const
00496 { return numberIntegers_;};
00497
00498 inline const int * integerVariable() const
00499 { return integerVariable_;};
00500
00502 const double * getColLower() const
00503 { return solver_->getColLower();};
00504
00506 const double * getColUpper() const
00507 { return solver_->getColUpper();};
00508
00518 const char * getRowSense() const
00519 { return solver_->getRowSense();};
00520
00529 const double * getRightHandSide() const
00530 { return solver_->getRightHandSide();};
00531
00540 const double * getRowRange() const
00541 { return solver_->getRowRange();};
00542
00544 const double * getRowLower() const
00545 { return solver_->getRowLower();};
00546
00548 const double * getRowUpper() const
00549 { return solver_->getRowUpper();};
00550
00552 const double * getObjCoefficients() const
00553 { return solver_->getObjCoefficients();};
00554
00556 double getObjSense() const
00557 { return solver_->getObjSense();};
00558
00560 bool isContinuous(int colIndex) const
00561 { return solver_->isContinuous(colIndex);};
00562
00564 bool isBinary(int colIndex) const
00565 { return solver_->isBinary(colIndex);};
00566
00571 bool isInteger(int colIndex) const
00572 { return solver_->isInteger(colIndex);};
00573
00575 bool isIntegerNonBinary(int colIndex) const
00576 { return solver_->isIntegerNonBinary(colIndex);};
00577
00579 bool isFreeBinary(int colIndex) const
00580 { return solver_->isFreeBinary(colIndex) ;};
00581
00583 const CoinPackedMatrix * getMatrixByRow() const
00584 { return solver_->getMatrixByRow();};
00585
00587 const CoinPackedMatrix * getMatrixByCol() const
00588 { return solver_->getMatrixByCol();};
00589
00591 double getInfinity() const
00592 { return solver_->getInfinity();};
00594
00595
00598
00599 void setBestSolution(SBB_Message how,
00600 double & objectiveValue, const double *solution,
00601 bool fixVariables=false);
00602
00608 double checkSolution(double cutoff, const double * solution,
00609 bool fixVariables);
00616 bool feasibleSolution(int & numberIntegerInfeasibilities,
00617 int & numberObjectInfeasibilities) const;
00618
00624 inline double * currentSolution() const
00625 { return currentSolution_;};
00626
00628 const double * getColSolution() const
00629 { return solver_->getColSolution();};
00630
00632 const double * getRowPrice() const
00633 { return solver_->getRowPrice();};
00634
00636 const double * getReducedCost() const
00637 { return solver_->getReducedCost();};
00638
00640 const double * getRowActivity() const
00641 { return solver_->getRowActivity();};
00642
00644 double getCurrentObjValue() const
00645 { return solver_->getObjValue();};
00646
00648 double getObjValue() const
00649 { return bestObjective_;};
00650
00657 const double * bestSolution() const
00658 { return bestSolution_;};
00659
00661 int getSolutionCount() const
00662 { return numberSolutions_;};
00663
00665 void setSolutionCount(int value)
00666 { numberSolutions_=value;};
00667
00669 int getNumberHeuristicSolutions() const { return numberHeuristicSolutions_;};
00670
00672 void setObjSense(double s) { solver_->setObjSense(s);};
00673
00675 inline double getContinuousObjective() const
00676 { return continuousObjective_;};
00677 inline void setContinuousObjective(double value)
00678 { continuousObjective_=value;};
00680 inline int getContinuousInfeasibilities() const
00681 { return continuousInfeasibilities_;};
00682 inline void setContinuousInfeasibilities(int value)
00683 { continuousInfeasibilities_=value;};
00685
00688
00689 inline SbbCompareBase * nodeComparison() const
00690 { return nodeCompare_;};
00691 inline void setNodeComparison(SbbCompareBase * compare)
00692 { nodeCompare_ = compare;};
00693 inline void setNodeComparison(SbbCompareBase & compare)
00694 { nodeCompare_ = &compare;};
00696
00702
00704 inline SbbBranchDecision * branchingMethod() const
00705 { return branchingMethod_;};
00707 inline void setBranchingMethod(SbbBranchDecision * method)
00708 { branchingMethod_ = method;};
00713 inline void setBranchingMethod(SbbBranchDecision & method)
00714 { branchingMethod_ = &method;};
00716
00719
00725 void reducedCostFix() ;
00726
00733 CoinWarmStartBasis *getEmptyBasis(int ns = 0, int na = 0) const ;
00734
00743 void takeOffCuts(OsiCuts &cuts, int *whichGenerator,
00744 int &numberOldActiveCuts, int &numberNewCuts,
00745 bool allowResolve) ;
00746
00758 int addCuts(SbbNode * node, CoinWarmStartBasis *&lastws);
00759
00774 void addCuts1(SbbNode * node, CoinWarmStartBasis *&lastws);
00775
00777 SbbCountRowCut ** addedCuts() const
00778 { return addedCuts_;};
00780 int currentNumberCuts() const
00781 { return currentNumberCuts_;};
00782
00784 inline int numberCutGenerators() const
00785 { return numberCutGenerators_;};
00787 inline SbbCutGenerator ** cutGenerators() const
00788 { return generator_;};
00790 inline SbbCutGenerator * cutGenerator(int i) const
00791 { return generator_[i];};
00799 void addCutGenerator(CglCutGenerator * generator,
00800 int howOften=1, const char * name=NULL,
00801 bool normal=true, bool atSolution=false,
00802 bool infeasible=false);
00804
00807
00808 void addHeuristic(SbbHeuristic * generator);
00809
00823 void passInPriorities(const int * priorities, bool ifClique,
00824 int defaultValue=1000);
00825
00827 inline const int * priority() const { return priority_;};
00828
00830 inline int priority(int sequence) const
00831 {
00832 if (priority_)
00833 return priority_[sequence];
00834 else
00835 return 1000;
00836 };
00838
00839
00840
00841
00844
00845 void passInMessageHandler(CoinMessageHandler * handler);
00847 void newLanguage(CoinMessages::Language language);
00848 void setLanguage(CoinMessages::Language language)
00849 {newLanguage(language);};
00851 CoinMessageHandler * messageHandler() const
00852 {return handler_;};
00854 CoinMessages messages()
00855 {return messages_;};
00857 CoinMessages * messagesPointer()
00858 {return &messages_;};
00860
00861
00862
00864
00865
00866 SbbModel();
00867
00869 SbbModel(const OsiSolverInterface &);
00870
00878 void assignSolver(OsiSolverInterface *&solver);
00879
00881 SbbModel(const SbbModel &);
00882
00884 SbbModel & operator=(const SbbModel& rhs);
00885
00887 ~SbbModel ();
00888
00890 OsiSolverInterface * solver() const
00891 { return solver_;};
00892
00894 OsiSolverInterface * continuousSolver() const
00895 { return continuousSolver_;};
00897 void gutsOfDestructor();
00899
00900
00901
00902 private:
00904
00905
00907 OsiSolverInterface * solver_;
00908
00915 bool ourSolver_ ;
00916
00918 OsiSolverInterface * continuousSolver_;
00919
00921 CoinMessageHandler * handler_;
00922
00928 bool defaultHandler_;
00929
00931 CoinMessages messages_;
00932
00934 int intParam_[SbbLastIntParam];
00935
00937 double dblParam_[SbbLastDblParam];
00938
00947 mutable CoinWarmStart *emptyWarmStart_ ;
00948
00950 CoinWarmStartBasis *basis_;
00951
00953 double bestObjective_;
00954
00956 double * bestSolution_;
00957
00962 double * currentSolution_;
00963
00965 OsiCuts globalCuts_;
00966
00968 double minimumDrop_;
00970 int numberSolutions_;
00972 int forcePriority_;
00974 int numberHeuristicSolutions_;
00976 int numberNodes_;
00978 int numberIterations_;
00980 int status_;
00982 int numberIntegers_;
00984 int numberRowsAtContinuous_;
00986 int maximumNumberCuts_;
00987
00989 int currentNumberCuts_;
00990
00995 int maximumDepth_;
01001 SbbNodeInfo ** walkback_;
01002
01010 SbbCountRowCut ** addedCuts_;
01011
01013 int * integerVariable_;
01015 int strategy_;
01017 SbbCompareBase * nodeCompare_;
01019 SbbBranchDecision * branchingMethod_;
01020
01025 int numberStrong_;
01026
01028 int printFrequency_;
01030 int numberCutGenerators_;
01031
01032 SbbCutGenerator ** generator_;
01034 int numberHeuristics_;
01035
01036 SbbHeuristic ** heuristic_;
01037
01039 int numberObjects_;
01040
01051 SbbObject ** object_;
01052
01054 int * originalColumns_;
01056 int * priority_;
01058 int howOftenGlobalScan_;
01063 double continuousObjective_;
01065 int continuousInfeasibilities_;
01067 int maximumCutPassesAtRoot_;
01069 int maximumCutPasses_;
01071 };
01072
01073 #endif