diff options
Diffstat (limited to 'build/Bonmin/include/coin/CbcModel.hpp')
-rw-r--r-- | build/Bonmin/include/coin/CbcModel.hpp | 2952 |
1 files changed, 2952 insertions, 0 deletions
diff --git a/build/Bonmin/include/coin/CbcModel.hpp b/build/Bonmin/include/coin/CbcModel.hpp new file mode 100644 index 0000000..ceef661 --- /dev/null +++ b/build/Bonmin/include/coin/CbcModel.hpp @@ -0,0 +1,2952 @@ +/* $Id: CbcModel.hpp 2206 2015-07-07 20:44:40Z stefan $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcModel_H +#define CbcModel_H +#include <string> +#include <vector> +#include "CoinMessageHandler.hpp" +#include "OsiSolverInterface.hpp" +#include "OsiBranchingObject.hpp" +#include "OsiCuts.hpp" +#include "CoinWarmStartBasis.hpp" +#include "CbcCompareBase.hpp" +#include "CbcCountRowCut.hpp" +#include "CbcMessage.hpp" +#include "CbcEventHandler.hpp" +#include "ClpDualRowPivot.hpp" + + +class CbcCutGenerator; +class CbcBaseModel; +class OsiRowCut; +class OsiBabSolver; +class OsiRowCutDebugger; +class CglCutGenerator; +class CglStored; +class CbcCutModifier; +class CglTreeProbingInfo; +class CbcHeuristic; +class OsiObject; +class CbcThread; +class CbcTree; +class CbcStrategy; +class CbcSymmetry; +class CbcFeasibilityBase; +class CbcStatistics; +class CbcFullNodeInfo; +class CbcEventHandler ; +class CglPreProcess; +class OsiClpSolverInterface; +class ClpNodeStuff; + +// #define CBC_CHECK_BASIS 1 + +//############################################################################# + +/** Simple Branch and bound class + + The initialSolve() method solves the initial LP relaxation of the MIP + problem. The branchAndBound() method can then be called to finish using + a branch and cut algorithm. + + <h3>Search Tree Traversal</h3> + + Subproblems (aka nodes) requiring additional evaluation are stored using + the CbcNode and CbcNodeInfo objects. Ancestry linkage is maintained in the + CbcNodeInfo object. Evaluation of a subproblem within branchAndBound() + proceeds as follows: + <ul> + <li> The node representing the most promising parent subproblem is popped + from the heap which holds the set of subproblems requiring further + evaluation. + <li> Using branching instructions stored in the node, and information in + its ancestors, the model and solver are adjusted to create the + active subproblem. + <li> If the parent subproblem will require further evaluation + (<i>i.e.</i>, there are branches remaining) its node is pushed back + on the heap. Otherwise, the node is deleted. This may trigger + recursive deletion of ancestors. + <li> The newly created subproblem is evaluated. + <li> If the subproblem requires further evaluation, a node is created. + All information needed to recreate the subproblem (branching + information, row and column cuts) is placed in the node and the node + is added to the set of subproblems awaiting further evaluation. + </ul> + Note that there is never a node representing the active subproblem; the model + and solver represent the active subproblem. + + <h3>Row (Constraint) Cut Handling</h3> + + For a typical subproblem, the sequence of events is as follows: + <ul> + <li> The subproblem is rebuilt for further evaluation: One result of a + call to addCuts() is a traversal of ancestors, leaving a list of all + cuts used in the ancestors in #addedCuts_. This list is then scanned + to construct a basis that includes only tight cuts. Entries for + loose cuts are set to NULL. + <li> The subproblem is evaluated: One result of a call to solveWithCuts() + is the return of a set of newly generated cuts for the subproblem. + #addedCuts_ is also kept up-to-date as old cuts become loose. + <li> The subproblem is stored for further processing: A call to + CbcNodeInfo::addCuts() adds the newly generated cuts to the + CbcNodeInfo object associated with this node. + </ul> + See CbcCountRowCut for details of the bookkeeping associated with cut + management. +*/ + +class CbcModel { + +public: + + enum CbcIntParam { + /** The maximum number of nodes before terminating */ + CbcMaxNumNode = 0, + /** The maximum number of solutions before terminating */ + CbcMaxNumSol, + /** Fathoming discipline + + Controls objective function comparisons for purposes of fathoming by bound + or determining monotonic variables. + + If 1, action is taken only when the current objective is strictly worse + than the target. Implementation is handled by adding a small tolerance to + the target. + */ + CbcFathomDiscipline, + /** Adjusts printout + 1 does different node message with number unsatisfied on last branch + */ + CbcPrinting, + /** Number of branches (may be more than number of nodes as may + include strong branching) */ + CbcNumberBranches, + /** Just a marker, so that a static sized array can store parameters. */ + CbcLastIntParam + }; + + enum CbcDblParam { + /** The maximum amount the value of an integer variable can vary from + integer and still be considered feasible. */ + CbcIntegerTolerance = 0, + /** The objective is assumed to worsen by this amount for each + integer infeasibility. */ + CbcInfeasibilityWeight, + /** The amount by which to tighten the objective function cutoff when + a new solution is discovered. */ + CbcCutoffIncrement, + /** Stop when the gap between the objective value of the best known solution + and the best bound on the objective of any solution is less than this. + + This is an absolute value. Conversion from a percentage is left to the + client. + */ + CbcAllowableGap, + /** Stop when the gap between the objective value of the best known solution + and the best bound on the objective of any solution is less than this + fraction of of the absolute value of best known solution. + + Code stops if either this test or CbcAllowableGap test succeeds + */ + CbcAllowableFractionGap, + /** \brief The maximum number of seconds before terminating. + A double should be adequate! */ + CbcMaximumSeconds, + /// Cutoff - stored for speed + CbcCurrentCutoff, + /// Optimization direction - stored for speed + CbcOptimizationDirection, + /// Current objective value + CbcCurrentObjectiveValue, + /// Current minimization objective value + CbcCurrentMinimizationObjectiveValue, + /** \brief The time at start of model. + So that other pieces of code can access */ + CbcStartSeconds, + /** Stop doing heuristics when the gap between the objective value of the + best known solution and the best bound on the objective of any solution + is less than this. + + This is an absolute value. Conversion from a percentage is left to the + client. + */ + CbcHeuristicGap, + /** Stop doing heuristics when the gap between the objective value of the + best known solution and the best bound on the objective of any solution + is less than this fraction of of the absolute value of best known + solution. + + Code stops if either this test or CbcAllowableGap test succeeds + */ + CbcHeuristicFractionGap, + /// Smallest non-zero change on a branch + CbcSmallestChange, + /// Sum of non-zero changes on a branch + CbcSumChange, + /// Largest non-zero change on a branch + CbcLargestChange, + /// Small non-zero change on a branch to be used as guess + CbcSmallChange, + /** Just a marker, so that a static sized array can store parameters. */ + CbcLastDblParam + }; + + //--------------------------------------------------------------------------- + +public: + ///@name Solve methods + //@{ + /** \brief Solve the initial LP relaxation + + Invoke the solver's %initialSolve() method. + */ + void initialSolve(); + + /** \brief Invoke the branch \& cut algorithm + + The method assumes that initialSolve() has been called to solve the + LP relaxation. It processes the root node, then proceeds to explore the + branch & cut search tree. The search ends when the tree is exhausted or + one of several execution limits is reached. + If doStatistics is 1 summary statistics are printed + if 2 then also the path to best solution (if found by branching) + if 3 then also one line per node + */ + void branchAndBound(int doStatistics = 0); +private: + + /** \brief Evaluate a subproblem using cutting planes and heuristics + + The method invokes a main loop which generates cuts, applies heuristics, + and reoptimises using the solver's native %resolve() method. + It returns true if the subproblem remains feasible at the end of the + evaluation. + */ + bool solveWithCuts(OsiCuts & cuts, int numberTries, CbcNode * node); + /** Generate one round of cuts - serial mode + returns - + 0 - normal + 1 - must keep going + 2 - set numberTries to zero + -1 - infeasible + */ + int serialCuts(OsiCuts & cuts, CbcNode * node, OsiCuts & slackCuts, int lastNumberCuts); + /** Generate one round of cuts - parallel mode + returns - + 0 - normal + 1 - must keep going + 2 - set numberTries to zero + -1 - infeasible + */ + int parallelCuts(CbcBaseModel * master, OsiCuts & cuts, CbcNode * node, OsiCuts & slackCuts, int lastNumberCuts); + /** Input one node output N nodes to put on tree and optional solution update + This should be able to operate in parallel so is given a solver and is const(ish) + However we will need to keep an array of solver_ and bases and more + status is 0 for normal, 1 if solution + Calling code should always push nodes back on tree + */ + CbcNode ** solveOneNode(int whichSolver, CbcNode * node, + int & numberNodesOutput, int & status) ; + /// Update size of whichGenerator + void resizeWhichGenerator(int numberNow, int numberAfter); +public: +#ifdef CBC_KEEP_DEPRECATED + // See if anyone is using these any more!! + /** \brief create a clean model from partially fixed problem + + The method creates a new model with given bounds and with no tree. + */ + CbcModel * cleanModel(const double * lower, const double * upper); + /** \brief Invoke the branch \& cut algorithm on partially fixed problem + + The method presolves the given model and does branch and cut. The search + ends when the tree is exhausted or maximum nodes is reached. + + If better solution found then it is saved. + + Returns 0 if search completed and solution, 1 if not completed and solution, + 2 if completed and no solution, 3 if not completed and no solution. + + Normally okay to do cleanModel immediately followed by subBranchandBound + (== other form of subBranchAndBound) + but may need to get at model for advanced features. + + Deletes model2 + */ + int subBranchAndBound(CbcModel * model2, + CbcModel * presolvedModel, + int maximumNodes); + /** \brief Invoke the branch \& cut algorithm on partially fixed problem + + The method creates a new model with given bounds, presolves it + then proceeds to explore the branch & cut search tree. The search + ends when the tree is exhausted or maximum nodes is reached. + + If better solution found then it is saved. + + Returns 0 if search completed and solution, 1 if not completed and solution, + 2 if completed and no solution, 3 if not completed and no solution. + + This is just subModel immediately followed by other version of + subBranchandBound. + + */ + int subBranchAndBound(const double * lower, const double * upper, + int maximumNodes); + + /** \brief Process root node and return a strengthened model + + The method assumes that initialSolve() has been called to solve the + LP relaxation. It processes the root node and then returns a pointer + to the strengthened model (or NULL if infeasible) + */ + OsiSolverInterface * strengthenedModel(); + /** preProcess problem - replacing solver + If makeEquality true then <= cliques converted to ==. + Presolve will be done numberPasses times. + + Returns NULL if infeasible + + If makeEquality is 1 add slacks to get cliques, + if 2 add slacks to get sos (but only if looks plausible) and keep sos info + */ + CglPreProcess * preProcess( int makeEquality = 0, int numberPasses = 5, + int tuning = 5); + /** Does postprocessing - original solver back. + User has to delete process */ + void postProcess(CglPreProcess * process); +#endif + /// Adds an update information object + void addUpdateInformation(const CbcObjectUpdateData & data); + /** Do one node - broken out for clarity? + also for parallel (when baseModel!=this) + Returns 1 if solution found + node NULL on return if no branches left + newNode NULL if no new node created + */ + int doOneNode(CbcModel * baseModel, CbcNode * & node, CbcNode * & newNode); + +public: + /** \brief Reoptimise an LP relaxation + + Invoke the solver's %resolve() method. + whereFrom - + 0 - initial continuous + 1 - resolve on branch (before new cuts) + 2 - after new cuts + 3 - obsolete code or something modified problem in unexpected way + 10 - after strong branching has fixed variables at root + 11 - after strong branching has fixed variables in tree + + returns 1 feasible, 0 infeasible, -1 feasible but skip cuts + */ + int resolve(CbcNodeInfo * parent, int whereFrom, + double * saveSolution = NULL, + double * saveLower = NULL, + double * saveUpper = NULL); + /// Make given rows (L or G) into global cuts and remove from lp + void makeGlobalCuts(int numberRows, const int * which); + /// Make given cut into a global cut + int makeGlobalCut(const OsiRowCut * cut); + /// Make given cut into a global cut + int makeGlobalCut(const OsiRowCut & cut); + /// Make given column cut into a global cut + void makeGlobalCut(const OsiColCut * cut); + /// Make given column cut into a global cut + void makeGlobalCut(const OsiColCut & cut); + /// Make partial cut into a global cut and save + void makePartialCut(const OsiRowCut * cut, const OsiSolverInterface * solver=NULL); + /// Make partial cuts into global cuts + void makeGlobalCuts(); + /// Which cut generator generated this cut + inline const int * whichGenerator() const + { return whichGenerator_;} + //@} + + /** \name Presolve methods */ + //@{ + + /** Identify cliques and construct corresponding objects. + + Find cliques with size in the range + [\p atLeastThisMany, \p lessThanThis] and construct corresponding + CbcClique objects. + If \p makeEquality is true then a new model may be returned if + modifications had to be made, otherwise \c this is returned. + If the problem is infeasible #numberObjects_ is set to -1. + A client must use deleteObjects() before a second call to findCliques(). + If priorities exist, clique priority is set to the default. + */ + CbcModel * findCliques(bool makeEquality, int atLeastThisMany, + int lessThanThis, int defaultValue = 1000); + + /** Do integer presolve, creating a new (presolved) model. + + Returns the new model, or NULL if feasibility is lost. + If weak is true then just does a normal presolve + + \todo It remains to work out the cleanest way of getting a solution to + the original problem at the end. So this is very preliminary. + */ + CbcModel * integerPresolve(bool weak = false); + + /** Do integer presolve, modifying the current model. + + Returns true if the model remains feasible after presolve. + */ + bool integerPresolveThisModel(OsiSolverInterface * originalSolver, bool weak = false); + + + /// Put back information into the original model after integer presolve. + void originalModel(CbcModel * presolvedModel, bool weak); + + /** \brief For variables involved in VUB constraints, see if we can tighten + bounds by solving lp's + + Returns false if feasibility is lost. + If CglProbing is available, it will be tried as well to see if it can + tighten bounds. + This routine is just a front end for tightenVubs(int,const int*,double). + + If <tt>type = -1</tt> all variables are processed (could be very slow). + If <tt>type = 0</tt> only variables involved in VUBs are processed. + If <tt>type = n > 0</tt>, only the n most expensive VUB variables + are processed, where it is assumed that x is at its maximum so delta + would have to go to 1 (if x not at bound). + + If \p allowMultipleBinary is true, then a VUB constraint is a row with + one continuous variable and any number of binary variables. + + If <tt>useCutoff < 1.0e30</tt>, the original objective is installed as a + constraint with \p useCutoff as a bound. + */ + bool tightenVubs(int type, bool allowMultipleBinary = false, + double useCutoff = 1.0e50); + + /** \brief For variables involved in VUB constraints, see if we can tighten + bounds by solving lp's + + This version is just handed a list of variables to be processed. + */ + bool tightenVubs(int numberVubs, const int * which, + double useCutoff = 1.0e50); + /** + Analyze problem to find a minimum change in the objective function. + */ + void analyzeObjective(); + + /** + Add additional integers. + */ + void AddIntegers(); + /** + Save copy of the model. + */ + void saveModel(OsiSolverInterface * saveSolver, double * checkCutoffForRestart, bool * feasible); + /** + Flip direction of optimization on all models + */ + void flipModel(); + + //@} + + /** \name Object manipulation routines + + See OsiObject for an explanation of `object' in the context of CbcModel. + */ + //@{ + + /// Get the number of objects + inline int numberObjects() const { + return numberObjects_; + } + /// Set the number of objects + inline void setNumberObjects(int number) { + numberObjects_ = number; + } + + /// Get the array of objects + inline OsiObject ** objects() const { + return object_; + } + + /// Get the specified object + const inline OsiObject * object(int which) const { + return object_[which]; + } + /// Get the specified object + inline OsiObject * modifiableObject(int which) const { + return object_[which]; + } + + void setOptionalInteger(int index); + + /// Delete all object information (and just back to integers if true) + void deleteObjects(bool findIntegers = true); + + /** Add in object information. + + Objects are cloned; the owner can delete the originals. + */ + void addObjects(int numberObjects, OsiObject ** objects); + + /** Add in object information. + + Objects are cloned; the owner can delete the originals. + */ + void addObjects(int numberObjects, CbcObject ** objects); + + /// Ensure attached objects point to this model. + void synchronizeModel() ; + + /** \brief Identify integer variables and create corresponding objects. + + Record integer variables and create an CbcSimpleInteger object for each + one. + If \p startAgain is true, a new scan is forced, overwriting any existing + integer variable information. + If type > 0 then 1==PseudoCost, 2 new ones low priority + */ + + void findIntegers(bool startAgain, int type = 0); + +#ifdef SWITCH_VARIABLES + /// Convert Dynamic to Switching + int findSwitching(); + /// Fix associated variables + int fixAssociated(OsiSolverInterface * solver,int cleanBasis); + /// Debug associated variables + int checkAssociated(const OsiSolverInterface * solver, + const double * solution, int printLevel); +#endif + //@} + + //--------------------------------------------------------------------------- + + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false if the value of the parameter is out of range. + + The get methods return the value of the parameter. + + */ + //@{ + /// Set an integer parameter + inline bool setIntParam(CbcIntParam key, int value) { + intParam_[key] = value; + return true; + } + /// Set a double parameter + inline bool setDblParam(CbcDblParam key, double value) { + dblParam_[key] = value; + return true; + } + /// Get an integer parameter + inline int getIntParam(CbcIntParam key) const { + return intParam_[key]; + } + /// Get a double parameter + inline double getDblParam(CbcDblParam key) const { + return dblParam_[key]; + } + /*! \brief Set cutoff bound on the objective function. + + When using strict comparison, the bound is adjusted by a tolerance to + avoid accidentally cutting off the optimal solution. + */ + void setCutoff(double value) ; + + /// Get the cutoff bound on the objective function - always as minimize + inline double getCutoff() const { //double value ; + //solver_->getDblParam(OsiDualObjectiveLimit,value) ; + //assert( dblParam_[CbcCurrentCutoff]== value * solver_->getObjSense()); + return dblParam_[CbcCurrentCutoff]; + } + + /// Set the \link CbcModel::CbcMaxNumNode maximum node limit \endlink + inline bool setMaximumNodes( int value) { + return setIntParam(CbcMaxNumNode, value); + } + + /// Get the \link CbcModel::CbcMaxNumNode maximum node limit \endlink + inline int getMaximumNodes() const { + return getIntParam(CbcMaxNumNode); + } + + /** Set the + \link CbcModel::CbcMaxNumSol maximum number of solutions \endlink + desired. + */ + inline bool setMaximumSolutions( int value) { + return setIntParam(CbcMaxNumSol, value); + } + /** Get the + \link CbcModel::CbcMaxNumSol maximum number of solutions \endlink + desired. + */ + inline int getMaximumSolutions() const { + return getIntParam(CbcMaxNumSol); + } + /// Set the printing mode + inline bool setPrintingMode( int value) { + return setIntParam(CbcPrinting, value); + } + + /// Get the printing mode + inline int getPrintingMode() const { + return getIntParam(CbcPrinting); + } + + /** Set the + \link CbcModel::CbcMaximumSeconds maximum number of seconds \endlink + desired. + */ + inline bool setMaximumSeconds( double value) { + return setDblParam(CbcMaximumSeconds, value); + } + /** Get the + \link CbcModel::CbcMaximumSeconds maximum number of seconds \endlink + desired. + */ + inline double getMaximumSeconds() const { + return getDblParam(CbcMaximumSeconds); + } + /// Current time since start of branchAndbound + double getCurrentSeconds() const ; + + /// Return true if maximum time reached + bool maximumSecondsReached() const ; + + /** Set the + \link CbcModel::CbcIntegerTolerance integrality tolerance \endlink + */ + inline bool setIntegerTolerance( double value) { + return setDblParam(CbcIntegerTolerance, value); + } + /** Get the + \link CbcModel::CbcIntegerTolerance integrality tolerance \endlink + */ + inline double getIntegerTolerance() const { + return getDblParam(CbcIntegerTolerance); + } + + /** Set the + \link CbcModel::CbcInfeasibilityWeight + weight per integer infeasibility \endlink + */ + inline bool setInfeasibilityWeight( double value) { + return setDblParam(CbcInfeasibilityWeight, value); + } + /** Get the + \link CbcModel::CbcInfeasibilityWeight + weight per integer infeasibility \endlink + */ + inline double getInfeasibilityWeight() const { + return getDblParam(CbcInfeasibilityWeight); + } + + /** Set the \link CbcModel::CbcAllowableGap allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setAllowableGap( double value) { + return setDblParam(CbcAllowableGap, value); + } + /** Get the \link CbcModel::CbcAllowableGap allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline double getAllowableGap() const { + return getDblParam(CbcAllowableGap); + } + + /** Set the \link CbcModel::CbcAllowableFractionGap fraction allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setAllowableFractionGap( double value) { + return setDblParam(CbcAllowableFractionGap, value); + } + /** Get the \link CbcModel::CbcAllowableFractionGap fraction allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline double getAllowableFractionGap() const { + return getDblParam(CbcAllowableFractionGap); + } + /** Set the \link CbcModel::CbcAllowableFractionGap percentage allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setAllowablePercentageGap( double value) { + return setDblParam(CbcAllowableFractionGap, value*0.01); + } + /** Get the \link CbcModel::CbcAllowableFractionGap percentage allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline double getAllowablePercentageGap() const { + return 100.0*getDblParam(CbcAllowableFractionGap); + } + /** Set the \link CbcModel::CbcHeuristicGap heuristic gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setHeuristicGap( double value) { + return setDblParam(CbcHeuristicGap, value); + } + /** Get the \link CbcModel::CbcHeuristicGap heuristic gap \endlink + between the best known solution and the best possible solution. + */ + inline double getHeuristicGap() const { + return getDblParam(CbcHeuristicGap); + } + + /** Set the \link CbcModel::CbcHeuristicFractionGap fraction heuristic gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setHeuristicFractionGap( double value) { + return setDblParam(CbcHeuristicFractionGap, value); + } + /** Get the \link CbcModel::CbcHeuristicFractionGap fraction heuristic gap \endlink + between the best known solution and the best possible solution. + */ + inline double getHeuristicFractionGap() const { + return getDblParam(CbcHeuristicFractionGap); + } + /** Set the + \link CbcModel::CbcCutoffIncrement \endlink + desired. + */ + inline bool setCutoffIncrement( double value) { + return setDblParam(CbcCutoffIncrement, value); + } + /** Get the + \link CbcModel::CbcCutoffIncrement \endlink + desired. + */ + inline double getCutoffIncrement() const { + return getDblParam(CbcCutoffIncrement); + } + /// See if can stop on gap + bool canStopOnGap() const; + + /** Pass in target solution and optional priorities. + If priorities then >0 means only branch if incorrect + while <0 means branch even if correct. +1 or -1 are + highest priority */ + void setHotstartSolution(const double * solution, const int * priorities = NULL) ; + + /// Set the minimum drop to continue cuts + inline void setMinimumDrop(double value) { + minimumDrop_ = value; + } + /// Get the minimum drop to continue cuts + inline double getMinimumDrop() const { + return minimumDrop_; + } + + /** Set the maximum number of cut passes at root node (default 20) + Minimum drop can also be used for fine tuning */ + inline void setMaximumCutPassesAtRoot(int value) { + maximumCutPassesAtRoot_ = value; + } + /** Get the maximum number of cut passes at root node */ + inline int getMaximumCutPassesAtRoot() const { + return maximumCutPassesAtRoot_; + } + + /** Set the maximum number of cut passes at other nodes (default 10) + Minimum drop can also be used for fine tuning */ + inline void setMaximumCutPasses(int value) { + maximumCutPasses_ = value; + } + /** Get the maximum number of cut passes at other nodes (default 10) */ + inline int getMaximumCutPasses() const { + return maximumCutPasses_; + } + /** Get current cut pass number in this round of cuts. + (1 is first pass) */ + inline int getCurrentPassNumber() const { + return currentPassNumber_; + } + /** Set current cut pass number in this round of cuts. + (1 is first pass) */ + inline void setCurrentPassNumber(int value) { + currentPassNumber_ = value; + } + + /** Set the maximum number of candidates to be evaluated for strong + branching. + + A value of 0 disables strong branching. + */ + void setNumberStrong(int number); + /** Get the maximum number of candidates to be evaluated for strong + branching. + */ + inline int numberStrong() const { + return numberStrong_; + } + /** Set global preferred way to branch + -1 down, +1 up, 0 no preference */ + inline void setPreferredWay(int value) { + preferredWay_ = value; + } + /** Get the preferred way to branch (default 0) */ + inline int getPreferredWay() const { + return preferredWay_; + } + /// Get at which depths to do cuts + inline int whenCuts() const { + return whenCuts_; + } + /// Set at which depths to do cuts + inline void setWhenCuts(int value) { + whenCuts_ = value; + } + /** Return true if we want to do cuts + If allowForTopOfTree zero then just does on multiples of depth + if 1 then allows for doing at top of tree + if 2 then says if cuts allowed anywhere apart from root + */ + bool doCutsNow(int allowForTopOfTree) const; + + /** Set the number of branches before pseudo costs believed + in dynamic strong branching. + + A value of 0 disables dynamic strong branching. + */ + void setNumberBeforeTrust(int number); + /** get the number of branches before pseudo costs believed + in dynamic strong branching. */ + inline int numberBeforeTrust() const { + return numberBeforeTrust_; + } + /** Set the number of variables for which to compute penalties + in dynamic strong branching. + + A value of 0 disables penalties. + */ + void setNumberPenalties(int number); + /** get the number of variables for which to compute penalties + in dynamic strong branching. */ + inline int numberPenalties() const { + return numberPenalties_; + } + /// Pointer to top of tree + inline const CbcFullNodeInfo * topOfTree() const + { return topOfTree_;} + /// Number of analyze iterations to do + inline void setNumberAnalyzeIterations(int number) { + numberAnalyzeIterations_ = number; + } + inline int numberAnalyzeIterations() const { + return numberAnalyzeIterations_; + } + /** Get scale factor to make penalties match strong. + Should/will be computed */ + inline double penaltyScaleFactor() const { + return penaltyScaleFactor_; + } + /** Set scale factor to make penalties match strong. + Should/will be computed */ + void setPenaltyScaleFactor(double value); + /** Problem type as set by user or found by analysis. This will be extended + 0 - not known + 1 - Set partitioning <= + 2 - Set partitioning == + 3 - Set covering + 4 - all +- 1 or all +1 and odd + */ + void inline setProblemType(int number) { + problemType_ = number; + } + inline int problemType() const { + return problemType_; + } + /// Current depth + inline int currentDepth() const { + return currentDepth_; + } + + /// Set how often to scan global cuts + void setHowOftenGlobalScan(int number); + /// Get how often to scan global cuts + inline int howOftenGlobalScan() const { + return howOftenGlobalScan_; + } + /// Original columns as created by integerPresolve or preprocessing + inline int * originalColumns() const { + return originalColumns_; + } + /// Set original columns as created by preprocessing + void setOriginalColumns(const int * originalColumns, + int numberGood=COIN_INT_MAX) ; + /// Create conflict cut (well - most of) + OsiRowCut * conflictCut(const OsiSolverInterface * solver, bool & localCuts); + + /** Set the print frequency. + + Controls the number of nodes evaluated between status prints. + If <tt>number <=0</tt> the print frequency is set to 100 nodes for large + problems, 1000 for small problems. + Print frequency has very slight overhead if small. + */ + inline void setPrintFrequency(int number) { + printFrequency_ = number; + } + /// Get the print frequency + inline int printFrequency() const { + return printFrequency_; + } + //@} + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there a numerical difficulties? + bool isAbandoned() const; + /// Is optimality proven? + bool isProvenOptimal() const; + /// Is infeasiblity proven (or none better than cutoff)? + bool isProvenInfeasible() const; + /// Was continuous solution unbounded + bool isContinuousUnbounded() const; + /// Was continuous solution unbounded + bool isProvenDualInfeasible() const; + /// Node limit reached? + bool isNodeLimitReached() const; + /// Time limit reached? + bool isSecondsLimitReached() const; + /// Solution limit reached? + bool isSolutionLimitReached() const; + /// Get how many iterations it took to solve the problem. + inline int getIterationCount() const { + return numberIterations_; + } + /// Increment how many iterations it took to solve the problem. + inline void incrementIterationCount(int value) { + numberIterations_ += value; + } + /// Get how many Nodes it took to solve the problem (including those in complete fathoming B&B inside CLP). + inline int getNodeCount() const { + return numberNodes_; + } + /// Increment how many nodes it took to solve the problem. + inline void incrementNodeCount(int value) { + numberNodes_ += value; + } + /// Get how many Nodes were enumerated in complete fathoming B&B inside CLP + inline int getExtraNodeCount() const { + return numberExtraNodes_; + } + /// Get how many times complete fathoming B&B was done + inline int getFathomCount() const { + return numberFathoms_; + } + /** Final status of problem + Some of these can be found out by is...... functions + -1 before branchAndBound + 0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found + (or check value of best solution) + 1 stopped - on maxnodes, maxsols, maxtime + 2 difficulties so run was abandoned + (5 event user programmed event occurred) + */ + inline int status() const { + return status_; + } + inline void setProblemStatus(int value) { + status_ = value; + } + /** Secondary status of problem + -1 unset (status_ will also be -1) + 0 search completed with solution + 1 linear relaxation not feasible (or worse than cutoff) + 2 stopped on gap + 3 stopped on nodes + 4 stopped on time + 5 stopped on user event + 6 stopped on solutions + 7 linear relaxation unbounded + 8 stopped on iteration limit + */ + inline int secondaryStatus() const { + return secondaryStatus_; + } + inline void setSecondaryStatus(int value) { + secondaryStatus_ = value; + } + /// Are there numerical difficulties (for initialSolve) ? + bool isInitialSolveAbandoned() const ; + /// Is optimality proven (for initialSolve) ? + bool isInitialSolveProvenOptimal() const ; + /// Is primal infeasiblity proven (for initialSolve) ? + bool isInitialSolveProvenPrimalInfeasible() const ; + /// Is dual infeasiblity proven (for initialSolve) ? + bool isInitialSolveProvenDualInfeasible() const ; + + //@} + + //--------------------------------------------------------------------------- + /**@name Problem information methods + + These methods call the solver's query routines to return + information about the problem referred to by the current object. + Querying a problem that has no data associated with it result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. + + Const pointers returned from any data-query method are valid as + long as the data is unchanged and the solver is not called. + */ + //@{ + /// Number of rows in continuous (root) problem. + inline int numberRowsAtContinuous() const { + return numberRowsAtContinuous_; + } + + /// Get number of columns + inline int getNumCols() const { + return solver_->getNumCols(); + } + + /// Get number of rows + inline int getNumRows() const { + return solver_->getNumRows(); + } + + /// Get number of nonzero elements + inline CoinBigIndex getNumElements() const { + return solver_->getNumElements(); + } + + /// Number of integers in problem + inline int numberIntegers() const { + return numberIntegers_; + } + // Integer variables + inline const int * integerVariable() const { + return integerVariable_; + } + /// Whether or not integer + inline char integerType(int i) const { + assert (integerInfo_); + assert (integerInfo_[i] == 0 || integerInfo_[i] == 1); + return integerInfo_[i]; + } + /// Whether or not integer + inline const char * integerType() const { + return integerInfo_; + } + + /// Get pointer to array[getNumCols()] of column lower bounds + inline const double * getColLower() const { + return solver_->getColLower(); + } + + /// Get pointer to array[getNumCols()] of column upper bounds + inline const double * getColUpper() const { + return solver_->getColUpper(); + } + + /** Get pointer to array[getNumRows()] of row constraint senses. + <ul> + <li>'L': <= constraint + <li>'E': = constraint + <li>'G': >= constraint + <li>'R': ranged constraint + <li>'N': free constraint + </ul> + */ + inline const char * getRowSense() const { + return solver_->getRowSense(); + } + + /** Get pointer to array[getNumRows()] of rows right-hand sides + <ul> + <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] + <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 + </ul> + */ + inline const double * getRightHandSide() const { + return solver_->getRightHandSide(); + } + + /** Get pointer to array[getNumRows()] of row ranges. + <ul> + <li> if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] + <li> if rowsense()[i] != 'R' then + rowrange()[i] is 0.0 + </ul> + */ + inline const double * getRowRange() const { + return solver_->getRowRange(); + } + + /// Get pointer to array[getNumRows()] of row lower bounds + inline const double * getRowLower() const { + return solver_->getRowLower(); + } + + /// Get pointer to array[getNumRows()] of row upper bounds + inline const double * getRowUpper() const { + return solver_->getRowUpper(); + } + + /// Get pointer to array[getNumCols()] of objective function coefficients + inline const double * getObjCoefficients() const { + return solver_->getObjCoefficients(); + } + + /// Get objective function sense (1 for min (default), -1 for max) + inline double getObjSense() const { + //assert (dblParam_[CbcOptimizationDirection]== solver_->getObjSense()); + return dblParam_[CbcOptimizationDirection]; + } + + /// Return true if variable is continuous + inline bool isContinuous(int colIndex) const { + return solver_->isContinuous(colIndex); + } + + /// Return true if variable is binary + inline bool isBinary(int colIndex) const { + return solver_->isBinary(colIndex); + } + + /** Return true if column is integer. + Note: This function returns true if the the column + is binary or a general integer. + */ + inline bool isInteger(int colIndex) const { + return solver_->isInteger(colIndex); + } + + /// Return true if variable is general integer + inline bool isIntegerNonBinary(int colIndex) const { + return solver_->isIntegerNonBinary(colIndex); + } + + /// Return true if variable is binary and not fixed at either bound + inline bool isFreeBinary(int colIndex) const { + return solver_->isFreeBinary(colIndex) ; + } + + /// Get pointer to row-wise copy of matrix + inline const CoinPackedMatrix * getMatrixByRow() const { + return solver_->getMatrixByRow(); + } + + /// Get pointer to column-wise copy of matrix + inline const CoinPackedMatrix * getMatrixByCol() const { + return solver_->getMatrixByCol(); + } + + /// Get solver's value for infinity + inline double getInfinity() const { + return solver_->getInfinity(); + } + /// Get pointer to array[getNumCols()] (for speed) of column lower bounds + inline const double * getCbcColLower() const { + return cbcColLower_; + } + /// Get pointer to array[getNumCols()] (for speed) of column upper bounds + inline const double * getCbcColUpper() const { + return cbcColUpper_; + } + /// Get pointer to array[getNumRows()] (for speed) of row lower bounds + inline const double * getCbcRowLower() const { + return cbcRowLower_; + } + /// Get pointer to array[getNumRows()] (for speed) of row upper bounds + inline const double * getCbcRowUpper() const { + return cbcRowUpper_; + } + /// Get pointer to array[getNumCols()] (for speed) of primal solution vector + inline const double * getCbcColSolution() const { + return cbcColSolution_; + } + /// Get pointer to array[getNumRows()] (for speed) of dual prices + inline const double * getCbcRowPrice() const { + return cbcRowPrice_; + } + /// Get a pointer to array[getNumCols()] (for speed) of reduced costs + inline const double * getCbcReducedCost() const { + return cbcReducedCost_; + } + /// Get pointer to array[getNumRows()] (for speed) of row activity levels. + inline const double * getCbcRowActivity() const { + return cbcRowActivity_; + } + //@} + + + /**@name Methods related to querying the solution */ + //@{ + /// Holds solution at continuous (after cuts if branchAndBound called) + inline double * continuousSolution() const { + return continuousSolution_; + } + /** Array marked whenever a solution is found if non-zero. + Code marks if heuristic returns better so heuristic + need only mark if it wants to on solutions which + are worse than current */ + inline int * usedInSolution() const { + return usedInSolution_; + } + /// Increases usedInSolution for nonzeros + void incrementUsed(const double * solution); + /// Record a new incumbent solution and update objectiveValue + void setBestSolution(CBC_Message how, + double & objectiveValue, const double *solution, + int fixVariables = 0); + /// Just update objectiveValue + void setBestObjectiveValue( double objectiveValue); + /// Deals with event handler and solution + CbcEventHandler::CbcAction dealWithEventHandler(CbcEventHandler::CbcEvent event, + double objValue, + const double * solution); + + /** Call this to really test if a valid solution can be feasible + Solution is number columns in size. + If fixVariables true then bounds of continuous solver updated. + Returns objective value (worse than cutoff if not feasible) + Previously computed objective value is now passed in (in case user does not do solve) + virtual so user can override + */ + virtual double checkSolution(double cutoff, double * solution, + int fixVariables, double originalObjValue); + /** Test the current solution for feasiblility. + + Scan all objects for indications of infeasibility. This is broken down + into simple integer infeasibility (\p numberIntegerInfeasibilities) + and all other reports of infeasibility (\p numberObjectInfeasibilities). + */ + bool feasibleSolution(int & numberIntegerInfeasibilities, + int & numberObjectInfeasibilities) const; + + /** Solution to the most recent lp relaxation. + + The solver's solution to the most recent lp relaxation. + */ + + inline double * currentSolution() const { + return currentSolution_; + } + /** For testing infeasibilities - will point to + currentSolution_ or solver-->getColSolution() + */ + inline const double * testSolution() const { + return testSolution_; + } + inline void setTestSolution(const double * solution) { + testSolution_ = solution; + } + /// Make sure region there and optionally copy solution + void reserveCurrentSolution(const double * solution = NULL); + + /// Get pointer to array[getNumCols()] of primal solution vector + inline const double * getColSolution() const { + return solver_->getColSolution(); + } + + /// Get pointer to array[getNumRows()] of dual prices + inline const double * getRowPrice() const { + return solver_->getRowPrice(); + } + + /// Get a pointer to array[getNumCols()] of reduced costs + inline const double * getReducedCost() const { + return solver_->getReducedCost(); + } + + /// Get pointer to array[getNumRows()] of row activity levels. + inline const double * getRowActivity() const { + return solver_->getRowActivity(); + } + + /// Get current objective function value + inline double getCurrentObjValue() const { + return dblParam_[CbcCurrentObjectiveValue]; + } + /// Get current minimization objective function value + inline double getCurrentMinimizationObjValue() const { + return dblParam_[CbcCurrentMinimizationObjectiveValue]; + } + + /// Get best objective function value as minimization + inline double getMinimizationObjValue() const { + return bestObjective_; + } + /// Set best objective function value as minimization + inline void setMinimizationObjValue(double value) { + bestObjective_ = value; + } + + /// Get best objective function value + inline double getObjValue() const { + return bestObjective_ * solver_->getObjSense() ; + } + /** Get best possible objective function value. + This is better of best possible left on tree + and best solution found. + If called from within branch and cut may be optimistic. + */ + double getBestPossibleObjValue() const; + /// Set best objective function value + inline void setObjValue(double value) { + bestObjective_ = value * solver_->getObjSense() ; + } + /// Get solver objective function value (as minimization) + inline double getSolverObjValue() const { + return solver_->getObjValue() * solver_->getObjSense() ; + } + + /** The best solution to the integer programming problem. + + The best solution to the integer programming problem found during + the search. If no solution is found, the method returns null. + */ + + inline double * bestSolution() const { + return bestSolution_; + } + /** User callable setBestSolution. + If check false does not check valid + If true then sees if feasible and warns if objective value + worse than given (so just set to COIN_DBL_MAX if you don't care). + If check true then does not save solution if not feasible + */ + void setBestSolution(const double * solution, int numberColumns, + double objectiveValue, bool check = false); + + /// Get number of solutions + inline int getSolutionCount() const { + return numberSolutions_; + } + + /// Set number of solutions (so heuristics will be different) + inline void setSolutionCount(int value) { + numberSolutions_ = value; + } + /// Number of saved solutions (including best) + int numberSavedSolutions() const; + /// Maximum number of extra saved solutions + inline int maximumSavedSolutions() const { + return maximumSavedSolutions_; + } + /// Set maximum number of extra saved solutions + void setMaximumSavedSolutions(int value); + /// Return a saved solution (0==best) - NULL if off end + const double * savedSolution(int which) const; + /// Return a saved solution objective (0==best) - COIN_DBL_MAX if off end + double savedSolutionObjective(int which) const; + /// Delete a saved solution and move others up + void deleteSavedSolution(int which); + + /** Current phase (so heuristics etc etc can find out). + 0 - initial solve + 1 - solve with cuts at root + 2 - solve with cuts + 3 - other e.g. strong branching + 4 - trying to validate a solution + 5 - at end of search + */ + inline int phase() const { + return phase_; + } + + /// Get number of heuristic solutions + inline int getNumberHeuristicSolutions() const { + return numberHeuristicSolutions_; + } + /// Set number of heuristic solutions + inline void setNumberHeuristicSolutions(int value) { + numberHeuristicSolutions_ = value; + } + + /// Set objective function sense (1 for min (default), -1 for max,) + inline void setObjSense(double s) { + dblParam_[CbcOptimizationDirection] = s; + solver_->setObjSense(s); + } + + /// Value of objective at continuous + inline double getContinuousObjective() const { + return originalContinuousObjective_; + } + inline void setContinuousObjective(double value) { + originalContinuousObjective_ = value; + } + /// Number of infeasibilities at continuous + inline int getContinuousInfeasibilities() const { + return continuousInfeasibilities_; + } + inline void setContinuousInfeasibilities(int value) { + continuousInfeasibilities_ = value; + } + /// Value of objective after root node cuts added + inline double rootObjectiveAfterCuts() const { + return continuousObjective_; + } + /// Sum of Changes to objective by first solve + inline double sumChangeObjective() const { + return sumChangeObjective1_; + } + /** Number of times global cuts violated. When global cut pool then this + should be kept for each cut and type of cut */ + inline int numberGlobalViolations() const { + return numberGlobalViolations_; + } + inline void clearNumberGlobalViolations() { + numberGlobalViolations_ = 0; + } + /// Whether to force a resolve after takeOffCuts + inline bool resolveAfterTakeOffCuts() const { + return resolveAfterTakeOffCuts_; + } + inline void setResolveAfterTakeOffCuts(bool yesNo) { + resolveAfterTakeOffCuts_ = yesNo; + } + /// Maximum number of rows + inline int maximumRows() const { + return maximumRows_; + } + /// Work basis for temporary use + inline CoinWarmStartBasis & workingBasis() { + return workingBasis_; + } + /// Get number of "iterations" to stop after + inline int getStopNumberIterations() const { + return stopNumberIterations_; + } + /// Set number of "iterations" to stop after + inline void setStopNumberIterations(int value) { + stopNumberIterations_ = value; + } + /// A pointer to model from CbcHeuristic + inline CbcModel * heuristicModel() const + { return heuristicModel_;} + /// Set a pointer to model from CbcHeuristic + inline void setHeuristicModel(CbcModel * model) + { heuristicModel_ = model;} + //@} + + /** \name Node selection */ + //@{ + // Comparison functions (which may be overridden by inheritance) + inline CbcCompareBase * nodeComparison() const { + return nodeCompare_; + } + void setNodeComparison(CbcCompareBase * compare); + void setNodeComparison(CbcCompareBase & compare); + //@} + + /** \name Problem feasibility checking */ + //@{ + // Feasibility functions (which may be overridden by inheritance) + inline CbcFeasibilityBase * problemFeasibility() const { + return problemFeasibility_; + } + void setProblemFeasibility(CbcFeasibilityBase * feasibility); + void setProblemFeasibility(CbcFeasibilityBase & feasibility); + //@} + + /** \name Tree methods and subtree methods */ + //@{ + /// Tree method e.g. heap (which may be overridden by inheritance) + inline CbcTree * tree() const { + return tree_; + } + /// For modifying tree handling (original is cloned) + void passInTreeHandler(CbcTree & tree); + /** For passing in an CbcModel to do a sub Tree (with derived tree handlers). + Passed in model must exist for duration of branch and bound + */ + void passInSubTreeModel(CbcModel & model); + /** For retrieving a copy of subtree model with given OsiSolver. + If no subtree model will use self (up to user to reset cutoff etc). + If solver NULL uses current + */ + CbcModel * subTreeModel(OsiSolverInterface * solver = NULL) const; + /// Returns number of times any subtree stopped on nodes, time etc + inline int numberStoppedSubTrees() const { + return numberStoppedSubTrees_; + } + /// Says a sub tree was stopped + inline void incrementSubTreeStopped() { + numberStoppedSubTrees_++; + } + /** Whether to automatically do presolve before branch and bound (subTrees). + 0 - no + 1 - ordinary presolve + 2 - integer presolve (dodgy) + */ + inline int typePresolve() const { + return presolve_; + } + inline void setTypePresolve(int value) { + presolve_ = value; + } + + //@} + + /** \name Branching Decisions + + See the CbcBranchDecision class for additional information. + */ + //@{ + + /// Get the current branching decision method. + inline CbcBranchDecision * branchingMethod() const { + return branchingMethod_; + } + /// Set the branching decision method. + inline void setBranchingMethod(CbcBranchDecision * method) { + delete branchingMethod_; + branchingMethod_ = method->clone(); + } + /** Set the branching method + + \overload + */ + inline void setBranchingMethod(CbcBranchDecision & method) { + delete branchingMethod_; + branchingMethod_ = method.clone(); + } + /// Get the current cut modifier method + inline CbcCutModifier * cutModifier() const { + return cutModifier_; + } + /// Set the cut modifier method + void setCutModifier(CbcCutModifier * modifier); + /** Set the cut modifier method + + \overload + */ + void setCutModifier(CbcCutModifier & modifier); + //@} + + /** \name Row (constraint) and Column (variable) cut generation */ + //@{ + + /** State of search + 0 - no solution + 1 - only heuristic solutions + 2 - branched to a solution + 3 - no solution but many nodes + */ + inline int stateOfSearch() const { + return stateOfSearch_; + } + inline void setStateOfSearch(int state) { + stateOfSearch_ = state; + } + /// Strategy worked out - mainly at root node for use by CbcNode + inline int searchStrategy() const { + return searchStrategy_; + } + /// Set strategy worked out - mainly at root node for use by CbcNode + inline void setSearchStrategy(int value) { + searchStrategy_ = value; + } + /// Stong branching strategy + inline int strongStrategy() const { + return strongStrategy_; + } + /// Set strong branching strategy + inline void setStrongStrategy(int value) { + strongStrategy_ = value; + } + + /// Get the number of cut generators + inline int numberCutGenerators() const { + return numberCutGenerators_; + } + /// Get the list of cut generators + inline CbcCutGenerator ** cutGenerators() const { + return generator_; + } + ///Get the specified cut generator + inline CbcCutGenerator * cutGenerator(int i) const { + return generator_[i]; + } + ///Get the specified cut generator before any changes + inline CbcCutGenerator * virginCutGenerator(int i) const { + return virginGenerator_[i]; + } + /** Add one generator - up to user to delete generators. + howoften affects how generator is used. 0 or 1 means always, + >1 means every that number of nodes. Negative values have same + meaning as positive but they may be switched off (-> -100) by code if + not many cuts generated at continuous. -99 is just done at root. + Name is just for printout. + If depth >0 overrides how often generator is called (if howOften==-1 or >0). + */ + void addCutGenerator(CglCutGenerator * generator, + int howOften = 1, const char * name = NULL, + bool normal = true, bool atSolution = false, + bool infeasible = false, int howOftenInSub = -100, + int whatDepth = -1, int whatDepthInSub = -1); +//@} + /** \name Strategy and sub models + + See the CbcStrategy class for additional information. + */ + //@{ + + /// Get the current strategy + inline CbcStrategy * strategy() const { + return strategy_; + } + /// Set the strategy. Clones + void setStrategy(CbcStrategy & strategy); + /// Set the strategy. assigns + inline void setStrategy(CbcStrategy * strategy) { + strategy_ = strategy; + } + /// Get the current parent model + inline CbcModel * parentModel() const { + return parentModel_; + } + /// Set the parent model + inline void setParentModel(CbcModel & parentModel) { + parentModel_ = &parentModel; + } + //@} + + + /** \name Heuristics and priorities */ + //@{ + /*! \brief Add one heuristic - up to user to delete + + The name is just used for print messages. + */ + void addHeuristic(CbcHeuristic * generator, const char *name = NULL, + int before = -1); + ///Get the specified heuristic + inline CbcHeuristic * heuristic(int i) const { + return heuristic_[i]; + } + /// Get the number of heuristics + inline int numberHeuristics() const { + return numberHeuristics_; + } + /// Set the number of heuristics + inline void setNumberHeuristics(int value) { + numberHeuristics_ = value; + } + /// Pointer to heuristic solver which found last solution (or NULL) + inline CbcHeuristic * lastHeuristic() const { + return lastHeuristic_; + } + /// set last heuristic which found a solution + inline void setLastHeuristic(CbcHeuristic * last) { + lastHeuristic_ = last; + } + + /** Pass in branching priorities. + + If ifClique then priorities are on cliques otherwise priorities are + on integer variables. + Other type (if exists set to default) + 1 is highest priority. (well actually -INT_MAX is but that's ugly) + If hotstart > 0 then branches are created to force + the variable to the value given by best solution. This enables a + sort of hot start. The node choice should be greatest depth + and hotstart should normally be switched off after a solution. + + If ifNotSimpleIntegers true then appended to normal integers + + This is now deprecated except for simple usage. If user + creates Cbcobjects then set priority in them + + \internal Added for Kurt Spielberg. + */ + void passInPriorities(const int * priorities, bool ifNotSimpleIntegers); + + /// Returns priority level for an object (or 1000 if no priorities exist) + inline int priority(int sequence) const { + return object_[sequence]->priority(); + } + + /*! \brief Set an event handler + + A clone of the handler passed as a parameter is stored in CbcModel. + */ + void passInEventHandler(const CbcEventHandler *eventHandler) ; + + /*! \brief Retrieve a pointer to the event handler */ + inline CbcEventHandler* getEventHandler() const { + return (eventHandler_) ; + } + + //@} + + /**@name Setting/Accessing application data */ + //@{ + /** Set application data. + + This is a pointer that the application can store into and + retrieve from the solver interface. + This field is available for the application to optionally + define and use. + */ + void setApplicationData (void * appData); + + /// Get application data + void * getApplicationData() const; + /** + For advanced applications you may wish to modify the behavior of Cbc + e.g. if the solver is a NLP solver then you may not have an exact + optimum solution at each step. Information could be built into + OsiSolverInterface but this is an alternative so that that interface + does not have to be changed. If something similar is useful to + enough solvers then it could be migrated + You can also pass in by using solver->setAuxiliaryInfo. + You should do that if solver is odd - if solver is normal simplex + then use this. + NOTE - characteristics are not cloned + */ + void passInSolverCharacteristics(OsiBabSolver * solverCharacteristics); + /// Get solver characteristics + inline const OsiBabSolver * solverCharacteristics() const { + return solverCharacteristics_; + } + //@} + + //--------------------------------------------------------------------------- + + /**@name Message handling etc */ + //@{ + /// Pass in Message handler (not deleted at end) + void passInMessageHandler(CoinMessageHandler * handler); + /// Set language + void newLanguage(CoinMessages::Language language); + inline void setLanguage(CoinMessages::Language language) { + newLanguage(language); + } + /// Return handler + inline CoinMessageHandler * messageHandler() const { + return handler_; + } + /// Return messages + inline CoinMessages & messages() { + return messages_; + } + /// Return pointer to messages + inline CoinMessages * messagesPointer() { + return &messages_; + } + /// Set log level + void setLogLevel(int value); + /// Get log level + inline int logLevel() const { + return handler_->logLevel(); + } + /** Set flag to say if handler_ is the default handler. + + The default handler is deleted when the model is deleted. Other + handlers (supplied by the client) will not be deleted. + */ + inline void setDefaultHandler(bool yesNo) { + defaultHandler_ = yesNo; + } + /// Check default handler + inline bool defaultHandler() const { + return defaultHandler_; + } + //@} + //--------------------------------------------------------------------------- + ///@name Specialized + //@{ + + /** + Set special options + 0 bit (1) - check if cuts valid (if on debugger list) + 1 bit (2) - use current basis to check integer solution (rather than all slack) + 2 bit (4) - don't check integer solution (by solving LP) + 3 bit (8) - fast analyze + 4 bit (16) - non-linear model - so no well defined CoinPackedMatrix + 5 bit (32) - keep names + 6 bit (64) - try for dominated columns + 7 bit (128) - SOS type 1 but all declared integer + 8 bit (256) - Set to say solution just found, unset by doing cuts + 9 bit (512) - Try reduced model after 100 nodes + 10 bit (1024) - Switch on some heuristics even if seems unlikely + 11 bit (2048) - Mark as in small branch and bound + 12 bit (4096) - Funny cuts so do slow way (in some places) + 13 bit (8192) - Funny cuts so do slow way (in other places) + 14 bit (16384) - Use Cplex! for fathoming + 15 bit (32768) - Try reduced model after 0 nodes + 16 bit (65536) - Original model had integer bounds + 17 bit (131072) - Perturbation switched off + 18 bit (262144) - donor CbcModel + 19 bit (524288) - recipient CbcModel + 20 bit (1048576) - waiting for sub model to return + 22 bit (4194304) - do not initialize random seed in solver (user has) + 23 bit (8388608) - leave solver_ with cuts + 24 bit (16777216) - just get feasible if no cutoff + */ + inline void setSpecialOptions(int value) { + specialOptions_ = value; + } + /// Get special options + inline int specialOptions() const { + return specialOptions_; + } + /// Set random seed + inline void setRandomSeed(int value) { + randomSeed_ = value; + } + /// Get random seed + inline int getRandomSeed() const { + return randomSeed_; + } + /// Set multiple root tries + inline void setMultipleRootTries(int value) { + multipleRootTries_ = value; + } + /// Get multiple root tries + inline int getMultipleRootTries() const { + return multipleRootTries_; + } + /// Tell model to stop on event + inline void sayEventHappened() + { eventHappened_=true;} + /// Says if normal solver i.e. has well defined CoinPackedMatrix + inline bool normalSolver() const { + return (specialOptions_&16) == 0; + } + /** Says if model is sitting there waiting for mini branch and bound to finish + This is because an event handler may only have access to parent model in + mini branch and bound + */ + inline bool waitingForMiniBranchAndBound() const { + return (specialOptions_&1048576) != 0; + } + /** Set more special options + at present bottom 6 bits used for shadow price mode + 1024 for experimental hotstart + 2048,4096 breaking out of cuts + 8192 slowly increase minimum drop + 16384 gomory + 32768 more heuristics in sub trees + 65536 no cuts in preprocessing + 131072 Time limits elapsed + 18 bit (262144) - Perturb fathom nodes + 19 bit (524288) - No limit on fathom nodes + 20 bit (1048576) - Reduce sum of infeasibilities before cuts + 21 bit (2097152) - Reduce sum of infeasibilities after cuts + 22 bit (4194304) - Conflict analysis + 23 bit (8388608) - Conflict analysis - temporary bit + 24 bit (16777216) - Add cutoff as LP constraint (out) + 25 bit (33554432) - diving/reordering + 26 bit (67108864) - load global cuts from file + 27 bit (134217728) - append binding global cuts to file + 28 bit (268435456) - idiot branching + 29 bit (536870912) - don't make fake objective + 30 bit (1073741824) - Funny SOS or similar - be careful + */ + inline void setMoreSpecialOptions(int value) { + moreSpecialOptions_ = value; + } + /// Get more special options + inline int moreSpecialOptions() const { + return moreSpecialOptions_; + } + /** Set more more special options + 0 bit (1) - find switching variables + 1 bit (2) - using fake objective until solution + 2 bit (4) - switching variables exist + 3 bit (8) - skip most of setBestSolution checks + 4 bit (16) - very lightweight preprocessing in smallB&B + 5 bit (32) - event handler needs to be cloned when parallel + 6 bit (64) - testing - use probing to make cliques + 7/8 bit (128) - try orbital branching (if nauty) + 9 bit (512) - branching on objective (later) + 10 bit (1024) - branching on constraints (later) + 11/12 bit 2048 - intermittent cuts + 13/14 bit 8192 - go to bitter end in strong branching (first time) + */ + inline void setMoreSpecialOptions2(int value) { + moreSpecialOptions2_ = value; + } + /// Get more special options2 + inline int moreSpecialOptions2() const { + return moreSpecialOptions2_; + } + /// Set cutoff as constraint + inline void setCutoffAsConstraint(bool yesNo) { + cutoffRowNumber_ = (yesNo) ? -2 : -1; + } + /// Set time method + inline void setUseElapsedTime(bool yesNo) { + if (yesNo) + moreSpecialOptions_ |= 131072; + else + moreSpecialOptions_ &= ~131072; + } + /// Get time method + inline bool useElapsedTime() const { + return (moreSpecialOptions_&131072)!=0; + } + /// Get useful temporary pointer + inline void * temporaryPointer() const + { return temporaryPointer_;} + /// Set useful temporary pointer + inline void setTemporaryPointer(void * pointer) + { temporaryPointer_=pointer;} + /// Go to dantzig pivot selection if easy problem (clp only) + void goToDantzig(int numberNodes, ClpDualRowPivot *& savePivotMethod); + /// Now we may not own objects - just point to solver's objects + inline bool ownObjects() const { + return ownObjects_; + } + /// Check original model before it gets messed up + void checkModel(); + //@} + //--------------------------------------------------------------------------- + + ///@name Constructors and destructors etc + //@{ + /// Default Constructor + CbcModel(); + + /// Constructor from solver + CbcModel(const OsiSolverInterface &); + + /** Assign a solver to the model (model assumes ownership) + + On return, \p solver will be NULL. + If deleteSolver then current solver deleted (if model owned) + + \note Parameter settings in the outgoing solver are not inherited by + the incoming solver. + */ + void assignSolver(OsiSolverInterface *&solver, bool deleteSolver = true); + + /** \brief Set ownership of solver + + A parameter of false tells CbcModel it does not own the solver and + should not delete it. Once you claim ownership of the solver, you're + responsible for eventually deleting it. Note that CbcModel clones + solvers with abandon. Unless you have a deep understanding of the + workings of CbcModel, the only time you want to claim ownership is when + you're about to delete the CbcModel object but want the solver to + continue to exist (as, for example, when branchAndBound has finished + and you want to hang on to the answer). + */ + inline void setModelOwnsSolver (bool ourSolver) { + ownership_ = ourSolver ? (ownership_ | 0x80000000) : (ownership_ & (~0x80000000)) ; + } + + /*! \brief Get ownership of solver + + A return value of true means that CbcModel owns the solver and will + take responsibility for deleting it when that becomes necessary. + */ + inline bool modelOwnsSolver () { + return ((ownership_&0x80000000) != 0) ; + } + + /** Copy constructor . + If cloneHandler is true then message handler is cloned + */ + CbcModel(const CbcModel & rhs, bool cloneHandler = false); + + /** Clone */ + virtual CbcModel *clone (bool cloneHandler); + + /// Assignment operator + CbcModel & operator=(const CbcModel& rhs); + + /// Destructor + virtual ~CbcModel (); + + /// Returns solver - has current state + inline OsiSolverInterface * solver() const { + return solver_; + } + + /// Returns current solver - sets new one + inline OsiSolverInterface * swapSolver(OsiSolverInterface * solver) { + OsiSolverInterface * returnSolver = solver_; + solver_ = solver; + return returnSolver; + } + + /// Returns solver with continuous state + inline OsiSolverInterface * continuousSolver() const { + return continuousSolver_; + } + + /// Create solver with continuous state + inline void createContinuousSolver() { + continuousSolver_ = solver_->clone(); + } + /// Clear solver with continuous state + inline void clearContinuousSolver() { + delete continuousSolver_; + continuousSolver_ = NULL; + } + + /// A copy of the solver, taken at constructor or by saveReferenceSolver + inline OsiSolverInterface * referenceSolver() const { + return referenceSolver_; + } + + /// Save a copy of the current solver so can be reset to + void saveReferenceSolver(); + + /** Uses a copy of reference solver to be current solver. + Because of possible mismatches all exotic integer information is loat + (apart from normal information in OsiSolverInterface) + so SOS etc and priorities will have to be redone + */ + void resetToReferenceSolver(); + + /// Clears out as much as possible (except solver) + void gutsOfDestructor(); + /** Clears out enough to reset CbcModel as if no branch and bound done + */ + void gutsOfDestructor2(); + /** Clears out enough to reset CbcModel cutoff etc + */ + void resetModel(); + /** Most of copy constructor + mode - 0 copy but don't delete before + 1 copy and delete before + 2 copy and delete before (but use virgin generators) + */ + void gutsOfCopy(const CbcModel & rhs, int mode = 0); + /// Move status, nodes etc etc across + void moveInfo(const CbcModel & rhs); + //@} + + ///@name Multithreading + //@{ + /// Indicates whether Cbc library has been compiled with multithreading support + static bool haveMultiThreadSupport(); + /// Get pointer to masterthread + CbcThread * masterThread() const { + return masterThread_; + } + /// Get pointer to walkback + CbcNodeInfo ** walkback() const { + return walkback_; + } + /// Get number of threads + inline int getNumberThreads() const { + return numberThreads_; + } + /// Set number of threads + inline void setNumberThreads(int value) { + numberThreads_ = value; + } + /// Get thread mode + inline int getThreadMode() const { + return threadMode_; + } + /** Set thread mode + always use numberThreads for branching + 1 set then deterministic + 2 set then use numberThreads for root cuts + 4 set then use numberThreads in root mini branch and bound + 8 set and numberThreads - do heuristics numberThreads at a time + 8 set and numberThreads==0 do all heuristics at once + default is 0 + */ + inline void setThreadMode(int value) { + threadMode_ = value; + } + /** Return + -2 if deterministic threaded and main thread + -1 if deterministic threaded and serial thread + 0 if serial + 1 if opportunistic threaded + */ + inline int parallelMode() const { + if (!numberThreads_) { + if ((threadMode_&1) == 0) + return 0; + else + return -1; + return 0; + } else { + if ((threadMode_&1) == 0) + return 1; + else + return -2; + } + } + /// Thread stuff for master + inline CbcBaseModel * master() const + { return master_;} + /// From here to end of section - code in CbcThread.cpp until class changed + /// Returns true if locked + bool isLocked() const; +#ifdef CBC_THREAD + /** + Locks a thread if parallel so that stuff like cut pool + can be updated and/or used. + */ + void lockThread(); + /** + Unlocks a thread if parallel to say cut pool stuff not needed + */ + void unlockThread(); +#else + inline void lockThread() {} + inline void unlockThread() {} +#endif + /** Set information in a child + -3 pass pointer to child thread info + -2 just stop + -1 delete simple child stuff + 0 delete opportunistic child stuff + 1 delete deterministic child stuff + */ + void setInfoInChild(int type, CbcThread * info); + /** Move/copy information from one model to another + -1 - initialization + 0 - from base model + 1 - to base model (and reset) + 2 - add in final statistics etc (and reset so can do clean destruction) + */ + void moveToModel(CbcModel * baseModel, int mode); + /// Split up nodes + int splitModel(int numberModels, CbcModel ** model, + int numberNodes); + /// Start threads + void startSplitModel(int numberIterations); + /// Merge models + void mergeModels(int numberModel, CbcModel ** model, + int numberNodes); + //@} + + ///@name semi-private i.e. users should not use + //@{ + /// Get how many Nodes it took to solve the problem. + int getNodeCount2() const { + return numberNodes2_; + } + /// Set pointers for speed + void setPointers(const OsiSolverInterface * solver); + /** Perform reduced cost fixing + + Fixes integer variables at their current value based on reduced cost + penalties. Returns number fixed + */ + int reducedCostFix() ; + /** Makes all handlers same. If makeDefault 1 then makes top level + default and rest point to that. If 2 then each is copy + */ + void synchronizeHandlers(int makeDefault); + /// Save a solution to saved list + void saveExtraSolution(const double * solution, double objectiveValue); + /// Save a solution to best and move current to saved + void saveBestSolution(const double * solution, double objectiveValue); + /// Delete best and saved solutions + void deleteSolutions(); + /// Encapsulates solver resolve + int resolve(OsiSolverInterface * solver); +#ifdef CLP_RESOLVE + /// Special purpose resolve + int resolveClp(OsiClpSolverInterface * solver, int type); +#endif + + /** Encapsulates choosing a variable - + anyAction -2, infeasible (-1 round again), 0 done + */ + int chooseBranch(CbcNode * & newNode, int numberPassesLeft, + CbcNode * oldNode, OsiCuts & cuts, + bool & resolved, CoinWarmStartBasis *lastws, + const double * lowerBefore, const double * upperBefore, + OsiSolverBranch * & branches); + int chooseBranch(CbcNode * newNode, int numberPassesLeft, bool & resolved); + + /** Return an empty basis object of the specified size + + A useful utility when constructing a basis for a subproblem from scratch. + The object returned will be of the requested capacity and appropriate for + the solver attached to the model. + */ + CoinWarmStartBasis *getEmptyBasis(int ns = 0, int na = 0) const ; + + /** Remove inactive cuts from the model + + An OsiSolverInterface is expected to maintain a valid basis, but not a + valid solution, when loose cuts are deleted. Restoring a valid solution + requires calling the solver to reoptimise. If it's certain the solution + will not be required, set allowResolve to false to suppress + reoptimisation. + If saveCuts then slack cuts will be saved + On input current cuts are cuts and newCuts + on exit current cuts will be correct. Returns number dropped + */ + int takeOffCuts(OsiCuts &cuts, + bool allowResolve, OsiCuts * saveCuts, + int numberNewCuts = 0, const OsiRowCut ** newCuts = NULL) ; + + /** Determine and install the active cuts that need to be added for + the current subproblem + + The whole truth is a bit more complicated. The first action is a call to + addCuts1(). addCuts() then sorts through the list, installs the tight + cuts in the model, and does bookkeeping (adjusts reference counts). + The basis returned from addCuts1() is adjusted accordingly. + + If it turns out that the node should really be fathomed by bound, + addCuts() simply treats all the cuts as loose as it does the bookkeeping. + + */ + int addCuts(CbcNode * node, CoinWarmStartBasis *&lastws); + + /** Traverse the tree from node to root and prep the model + + addCuts1() begins the job of prepping the model to match the current + subproblem. The model is stripped of all cuts, and the search tree is + traversed from node to root to determine the changes required. Appropriate + bounds changes are installed, a list of cuts is collected but not + installed, and an appropriate basis (minus the cuts, but big enough to + accommodate them) is constructed. + + Returns true if new problem similar to old + + \todo addCuts1() is called in contexts where it's known in advance that + all that's desired is to determine a list of cuts and do the + bookkeeping (adjust the reference counts). The work of installing + bounds and building a basis goes to waste. + */ + bool addCuts1(CbcNode * node, CoinWarmStartBasis *&lastws); + /** Returns bounds just before where - initially original bounds. + Also sets downstream nodes (lower if force 1, upper if 2) + */ + void previousBounds (CbcNode * node, CbcNodeInfo * where, int iColumn, + double & lower, double & upper, int force); + /** Set objective value in a node. This is separated out so that + odd solvers can use. It may look at extra information in + solverCharacteriscs_ and will also use bound from parent node + */ + void setObjectiveValue(CbcNode * thisNode, const CbcNode * parentNode) const; + + /** If numberBeforeTrust >0 then we are going to use CbcBranchDynamic. + Scan and convert CbcSimpleInteger objects + */ + void convertToDynamic(); + /// Set numberBeforeTrust in all objects + void synchronizeNumberBeforeTrust(int type = 0); + /// Zap integer information in problem (may leave object info) + void zapIntegerInformation(bool leaveObjects = true); + /// Use cliques for pseudocost information - return nonzero if infeasible + int cliquePseudoCosts(int doStatistics); + /// Fill in useful estimates + void pseudoShadow(int type); + /** Return pseudo costs + If not all integers or not pseudo costs - returns all zero + Length of arrays are numberIntegers() and entries + correspond to integerVariable()[i] + User must allocate arrays before call + */ + void fillPseudoCosts(double * downCosts, double * upCosts, + int * priority = NULL, + int * numberDown = NULL, int * numberUp = NULL, + int * numberDownInfeasible = NULL, + int * numberUpInfeasible = NULL) const; + /** Do heuristics at root. + 0 - don't delete + 1 - delete + 2 - just delete - don't even use + */ + void doHeuristicsAtRoot(int deleteHeuristicsAfterwards = 0); + /// Adjust heuristics based on model + void adjustHeuristics(); + /// Get the hotstart solution + inline const double * hotstartSolution() const { + return hotstartSolution_; + } + /// Get the hotstart priorities + inline const int * hotstartPriorities() const { + return hotstartPriorities_; + } + + /// Return the list of cuts initially collected for this subproblem + inline CbcCountRowCut ** addedCuts() const { + return addedCuts_; + } + /// Number of entries in the list returned by #addedCuts() + inline int currentNumberCuts() const { + return currentNumberCuts_; + } + /// Global cuts + inline CbcRowCuts * globalCuts() { + return &globalCuts_; + } + /// Get rid of global cuts + inline void zapGlobalCuts() { + globalCuts_ = CbcRowCuts(); + } + /// Copy and set a pointer to a row cut which will be added instead of normal branching. + void setNextRowCut(const OsiRowCut & cut); + /// Get a pointer to current node (be careful) + inline CbcNode * currentNode() const { + return currentNode_; + } + /// Get a pointer to probing info + inline CglTreeProbingInfo * probingInfo() const { + return probingInfo_; + } + /// Thread specific random number generator + inline CoinThreadRandom * randomNumberGenerator() { + return &randomNumberGenerator_; + } + /// Set the number of iterations done in strong branching. + inline void setNumberStrongIterations(int number) { + numberStrongIterations_ = number; + } + /// Get the number of iterations done in strong branching. + inline int numberStrongIterations() const { + return numberStrongIterations_; + } + /// Get maximum number of iterations (designed to be used in heuristics) + inline int maximumNumberIterations() const { + return maximumNumberIterations_; + } + /// Set maximum number of iterations (designed to be used in heuristics) + inline void setMaximumNumberIterations(int value) { + maximumNumberIterations_ = value; + } + /// Symmetry information + inline CbcSymmetry * symmetryInfo() const + { return symmetryInfo_;} + /// Set depth for fast nodes + inline void setFastNodeDepth(int value) { + fastNodeDepth_ = value; + } + /// Get depth for fast nodes + inline int fastNodeDepth() const { + return fastNodeDepth_; + } + /// Get anything with priority >= this can be treated as continuous + inline int continuousPriority() const { + return continuousPriority_; + } + /// Set anything with priority >= this can be treated as continuous + inline void setContinuousPriority(int value) { + continuousPriority_ = value; + } + inline void incrementExtra(int nodes, int iterations, int fathoms=1) { + numberExtraNodes_ += nodes; + numberExtraIterations_ += iterations; + numberFathoms_ += fathoms; + } + /// Zero extra + inline void zeroExtra() { + numberExtraNodes_ = 0; + numberExtraIterations_ = 0; + numberFathoms_ = 0; + } + /// Number of extra iterations + inline int numberExtraIterations() const { + return numberExtraIterations_; + } + /// Increment strong info + void incrementStrongInfo(int numberTimes, int numberIterations, + int numberFixed, bool ifInfeasible); + /// Return strong info + inline const int * strongInfo() const { + return strongInfo_; + } + + /// Return mutable strong info + inline int * mutableStrongInfo() { + return strongInfo_; + } + /// Get stored row cuts for donor/recipient CbcModel + CglStored * storedRowCuts() const { + return storedRowCuts_; + } + /// Set stored row cuts for donor/recipient CbcModel + void setStoredRowCuts(CglStored * cuts) { + storedRowCuts_ = cuts; + } + /// Says whether all dynamic integers + inline bool allDynamic () const { + return ((ownership_&0x40000000) != 0) ; + } + /// Create C++ lines to get to current state + void generateCpp( FILE * fp, int options); + /// Generate an OsiBranchingInformation object + OsiBranchingInformation usefulInformation() const; + /** Warm start object produced by heuristic or strong branching + + If get a valid integer solution outside branch and bound then it can take + a reasonable time to solve LP which produces clean solution. If this object has + any size then it will be used in solve. + */ + inline void setBestSolutionBasis(const CoinWarmStartBasis & bestSolutionBasis) { + bestSolutionBasis_ = bestSolutionBasis; + } + /// Redo walkback arrays + void redoWalkBack(); + //@} + + void setMIPStart( const std::vector< std::pair< std::string, double > > &mips ) { + this->mipStart_ = mips; + } + + const std::vector< std::pair< std::string, double > > &getMIPStart() { + return this->mipStart_; + } + + +//--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@{ + + /// The solver associated with this model. + OsiSolverInterface * solver_; + + /** Ownership of objects and other stuff + + 0x80000000 model owns solver + 0x40000000 all variables CbcDynamicPseudoCost + */ + unsigned int ownership_ ; + + /// A copy of the solver, taken at the continuous (root) node. + OsiSolverInterface * continuousSolver_; + + /// A copy of the solver, taken at constructor or by saveReferenceSolver + OsiSolverInterface * referenceSolver_; + + /// Message handler + CoinMessageHandler * handler_; + + /** Flag to say if handler_ is the default handler. + + The default handler is deleted when the model is deleted. Other + handlers (supplied by the client) will not be deleted. + */ + bool defaultHandler_; + + /// Cbc messages + CoinMessages messages_; + + /// Array for integer parameters + int intParam_[CbcLastIntParam]; + + /// Array for double parameters + double dblParam_[CbcLastDblParam]; + + /** Pointer to an empty warm start object + + It turns out to be useful to have this available as a base from + which to build custom warm start objects. This is typed as CoinWarmStart + rather than CoinWarmStartBasis to allow for the possibility that a + client might want to apply a solver that doesn't use a basis-based warm + start. See getEmptyBasis for an example of how this field can be used. + */ + mutable CoinWarmStart *emptyWarmStart_ ; + + /// Best objective + double bestObjective_; + /// Best possible objective + double bestPossibleObjective_; + /// Sum of Changes to objective by first solve + double sumChangeObjective1_; + /// Sum of Changes to objective by subsequent solves + double sumChangeObjective2_; + + /// Array holding the incumbent (best) solution. + double * bestSolution_; + /// Arrays holding other solutions. + double ** savedSolutions_; + + /** Array holding the current solution. + + This array is used more as a temporary. + */ + double * currentSolution_; + /** For testing infeasibilities - will point to + currentSolution_ or solver-->getColSolution() + */ + mutable const double * testSolution_; + /** MIPstart values + values for integer variables which will be converted to a complete integer initial feasible solution + */ + std::vector< std::pair< std::string, double > > mipStart_; + /** Warm start object produced by heuristic or strong branching + + If get a valid integer solution outside branch and bound then it can take + a reasonable time to solve LP which produces clean solution. If this object has + any size then it will be used in solve. + */ + CoinWarmStartBasis bestSolutionBasis_ ; + /// Global cuts + CbcRowCuts globalCuts_; + /// Global conflict cuts + CbcRowCuts * globalConflictCuts_; + + /// Minimum degradation in objective value to continue cut generation + double minimumDrop_; + /// Number of solutions + int numberSolutions_; + /// Number of saved solutions + int numberSavedSolutions_; + /// Maximum number of saved solutions + int maximumSavedSolutions_; + /** State of search + 0 - no solution + 1 - only heuristic solutions + 2 - branched to a solution + 3 - no solution but many nodes + */ + int stateOfSearch_; + /// At which depths to do cuts + int whenCuts_; + /// Hotstart solution + double * hotstartSolution_; + /// Hotstart priorities + int * hotstartPriorities_; + /// Number of heuristic solutions + int numberHeuristicSolutions_; + /// Cumulative number of nodes + int numberNodes_; + /** Cumulative number of nodes for statistics. + Must fix to match up + */ + int numberNodes2_; + /// Cumulative number of iterations + int numberIterations_; + /// Cumulative number of solves + int numberSolves_; + /// Status of problem - 0 finished, 1 stopped, 2 difficulties + int status_; + /** Secondary status of problem + -1 unset (status_ will also be -1) + 0 search completed with solution + 1 linear relaxation not feasible (or worse than cutoff) + 2 stopped on gap + 3 stopped on nodes + 4 stopped on time + 5 stopped on user event + 6 stopped on solutions + */ + int secondaryStatus_; + /// Number of integers in problem + int numberIntegers_; + /// Number of rows at continuous + int numberRowsAtContinuous_; + /** + -1 - cutoff as constraint not activated + -2 - waiting to activate + >=0 - activated + */ + int cutoffRowNumber_; + /// Maximum number of cuts + int maximumNumberCuts_; + /** Current phase (so heuristics etc etc can find out). + 0 - initial solve + 1 - solve with cuts at root + 2 - solve with cuts + 3 - other e.g. strong branching + 4 - trying to validate a solution + 5 - at end of search + */ + int phase_; + + /// Number of entries in #addedCuts_ + int currentNumberCuts_; + + /** Current limit on search tree depth + + The allocated size of #walkback_. Increased as needed. + */ + int maximumDepth_; + /** Array used to assemble the path between a node and the search tree root + + The array is resized when necessary. #maximumDepth_ is the current + allocated size. + */ + CbcNodeInfo ** walkback_; + CbcNodeInfo ** lastNodeInfo_; + const OsiRowCut ** lastCut_; + int lastDepth_; + int lastNumberCuts2_; + int maximumCuts_; + int * lastNumberCuts_; + + /** The list of cuts initially collected for this subproblem + + When the subproblem at this node is rebuilt, a set of cuts is collected + for inclusion in the constraint system. If any of these cuts are + subsequently removed because they have become loose, the corresponding + entry is set to NULL. + */ + CbcCountRowCut ** addedCuts_; + + /** A pointer to a row cut which will be added instead of normal branching. + After use it should be set to NULL. + */ + OsiRowCut * nextRowCut_; + + /// Current node so can be used elsewhere + CbcNode * currentNode_; + + /// Indices of integer variables + int * integerVariable_; + /// Whether of not integer + char * integerInfo_; + /// Holds solution at continuous (after cuts) + double * continuousSolution_; + /// Array marked whenever a solution is found if non-zero + int * usedInSolution_; + /** + Special options + 0 bit (1) - check if cuts valid (if on debugger list) + 1 bit (2) - use current basis to check integer solution (rather than all slack) + 2 bit (4) - don't check integer solution (by solving LP) + 3 bit (8) - fast analyze + 4 bit (16) - non-linear model - so no well defined CoinPackedMatrix + 5 bit (32) - keep names + 6 bit (64) - try for dominated columns + 7 bit (128) - SOS type 1 but all declared integer + 8 bit (256) - Set to say solution just found, unset by doing cuts + 9 bit (512) - Try reduced model after 100 nodes + 10 bit (1024) - Switch on some heuristics even if seems unlikely + 11 bit (2048) - Mark as in small branch and bound + 12 bit (4096) - Funny cuts so do slow way (in some places) + 13 bit (8192) - Funny cuts so do slow way (in other places) + 14 bit (16384) - Use Cplex! for fathoming + 15 bit (32768) - Try reduced model after 0 nodes + 16 bit (65536) - Original model had integer bounds + 17 bit (131072) - Perturbation switched off + 18 bit (262144) - donor CbcModel + 19 bit (524288) - recipient CbcModel + 20 bit (1048576) - waiting for sub model to return + 22 bit (4194304) - do not initialize random seed in solver (user has) + 23 bit (8388608) - leave solver_ with cuts + 24 bit (16777216) - just get feasible if no cutoff + */ + int specialOptions_; + /** More special options + at present bottom 6 bits used for shadow price mode + 1024 for experimental hotstart + 2048,4096 breaking out of cuts + 8192 slowly increase minimum drop + 16384 gomory + 32768 more heuristics in sub trees + 65536 no cuts in preprocessing + 131072 Time limits elapsed + 18 bit (262144) - Perturb fathom nodes + 19 bit (524288) - No limit on fathom nodes + 20 bit (1048576) - Reduce sum of infeasibilities before cuts + 21 bit (2097152) - Reduce sum of infeasibilities after cuts + */ + int moreSpecialOptions_; + /** More more special options + 0 bit (1) - find switching variables + 1 bit (2) - using fake objective until solution + 2 bit (4) - switching variables exist + 3 bit (8) - skip most of setBestSolution checks + 4 bit (16) - very lightweight preprocessing in smallB&B + 5 bit (32) - event handler needs to be cloned when parallel + 6 bit (64) - testing - use probing to make cliques + 7/8 bit (128) - try orbital branching (if nauty) + 9 bit (512) - branching on objective (later) + 10 bit (1024) - branching on constraints (later) + 11/12 bit 2048 - intermittent cuts + */ + int moreSpecialOptions2_; + /// User node comparison function + CbcCompareBase * nodeCompare_; + /// User feasibility function (see CbcFeasibleBase.hpp) + CbcFeasibilityBase * problemFeasibility_; + /// Tree + CbcTree * tree_; + /// Pointer to top of tree + CbcFullNodeInfo * topOfTree_; + /// A pointer to model to be used for subtrees + CbcModel * subTreeModel_; + /// A pointer to model from CbcHeuristic + CbcModel * heuristicModel_; + /// Number of times any subtree stopped on nodes, time etc + int numberStoppedSubTrees_; + /// Variable selection function + CbcBranchDecision * branchingMethod_; + /// Cut modifier function + CbcCutModifier * cutModifier_; + /// Strategy + CbcStrategy * strategy_; + /// Parent model + CbcModel * parentModel_; + /** Whether to automatically do presolve before branch and bound. + 0 - no + 1 - ordinary presolve + 2 - integer presolve (dodgy) + */ + /// Pointer to array[getNumCols()] (for speed) of column lower bounds + const double * cbcColLower_; + /// Pointer to array[getNumCols()] (for speed) of column upper bounds + const double * cbcColUpper_; + /// Pointer to array[getNumRows()] (for speed) of row lower bounds + const double * cbcRowLower_; + /// Pointer to array[getNumRows()] (for speed) of row upper bounds + const double * cbcRowUpper_; + /// Pointer to array[getNumCols()] (for speed) of primal solution vector + const double * cbcColSolution_; + /// Pointer to array[getNumRows()] (for speed) of dual prices + const double * cbcRowPrice_; + /// Get a pointer to array[getNumCols()] (for speed) of reduced costs + const double * cbcReducedCost_; + /// Pointer to array[getNumRows()] (for speed) of row activity levels. + const double * cbcRowActivity_; + /// Pointer to user-defined data structure + void * appData_; + /// Presolve for CbcTreeLocal + int presolve_; + /** Maximum number of candidates to consider for strong branching. + To disable strong branching, set this to 0. + */ + int numberStrong_; + /** \brief The number of branches before pseudo costs believed + in dynamic strong branching. + + A value of 0 is off. + */ + int numberBeforeTrust_; + /** \brief The number of variables for which to compute penalties + in dynamic strong branching. + */ + int numberPenalties_; + /// For threads - stop after this many "iterations" + int stopNumberIterations_; + /** Scale factor to make penalties match strong. + Should/will be computed */ + double penaltyScaleFactor_; + /// Number of analyze iterations to do + int numberAnalyzeIterations_; + /// Arrays with analysis results + double * analyzeResults_; + /// Useful temporary pointer + void * temporaryPointer_; + /// Number of nodes infeasible by normal branching (before cuts) + int numberInfeasibleNodes_; + /** Problem type as set by user or found by analysis. This will be extended + 0 - not known + 1 - Set partitioning <= + 2 - Set partitioning == + 3 - Set covering + */ + int problemType_; + /// Print frequency + int printFrequency_; + /// Number of cut generators + int numberCutGenerators_; + // Cut generators + CbcCutGenerator ** generator_; + // Cut generators before any changes + CbcCutGenerator ** virginGenerator_; + /// Number of heuristics + int numberHeuristics_; + /// Heuristic solvers + CbcHeuristic ** heuristic_; + /// Pointer to heuristic solver which found last solution (or NULL) + CbcHeuristic * lastHeuristic_; + /// Depth for fast nodes + int fastNodeDepth_; + /*! Pointer to the event handler */ +# ifdef CBC_ONLY_CLP + ClpEventHandler *eventHandler_ ; +# else + CbcEventHandler *eventHandler_ ; +# endif + /// Symmetry information + CbcSymmetry * symmetryInfo_; + /// Total number of objects + int numberObjects_; + + /** \brief Integer and Clique and ... information + + \note The code assumes that the first objects on the list will be + SimpleInteger objects for each integer variable, followed by + Clique objects. Portions of the code that understand Clique objects + will fail if they do not immediately follow the SimpleIntegers. + Large chunks of the code will fail if the first objects are not + SimpleInteger. As of 2003.08, SimpleIntegers and Cliques are the only + objects. + */ + OsiObject ** object_; + /// Now we may not own objects - just point to solver's objects + bool ownObjects_; + + /// Original columns as created by integerPresolve or preprocessing + int * originalColumns_; + /// How often to scan global cuts + int howOftenGlobalScan_; + /** Number of times global cuts violated. When global cut pool then this + should be kept for each cut and type of cut */ + int numberGlobalViolations_; + /// Number of extra iterations in fast lp + int numberExtraIterations_; + /// Number of extra nodes in fast lp + int numberExtraNodes_; + /// Number of times fast lp entered + int numberFathoms_; + /** Value of objective at continuous + (Well actually after initial round of cuts) + */ + double continuousObjective_; + /** Value of objective before root node cuts added + */ + double originalContinuousObjective_; + /// Number of infeasibilities at continuous + int continuousInfeasibilities_; + /// Maximum number of cut passes at root + int maximumCutPassesAtRoot_; + /// Maximum number of cut passes + int maximumCutPasses_; + /// Preferred way of branching + int preferredWay_; + /// Current cut pass number + int currentPassNumber_; + /// Maximum number of cuts (for whichGenerator_) + int maximumWhich_; + /// Maximum number of rows + int maximumRows_; + /// Random seed + int randomSeed_; + /// Multiple root tries + int multipleRootTries_; + /// Current depth + int currentDepth_; + /// Thread specific random number generator + mutable CoinThreadRandom randomNumberGenerator_; + /// Work basis for temporary use + CoinWarmStartBasis workingBasis_; + /// Which cut generator generated this cut + int * whichGenerator_; + /// Maximum number of statistics + int maximumStatistics_; + /// statistics + CbcStatistics ** statistics_; + /// Maximum depth reached + int maximumDepthActual_; + /// Number of reduced cost fixings + double numberDJFixed_; + /// Probing info + CglTreeProbingInfo * probingInfo_; + /// Number of fixed by analyze at root + int numberFixedAtRoot_; + /// Number fixed by analyze so far + int numberFixedNow_; + /// Whether stopping on gap + bool stoppedOnGap_; + /// Whether event happened + mutable bool eventHappened_; + /// Number of long strong goes + int numberLongStrong_; + /// Number of old active cuts + int numberOldActiveCuts_; + /// Number of new cuts + int numberNewCuts_; + /// Strategy worked out - mainly at root node + int searchStrategy_; + /** Strategy for strong branching + 0 - normal + when to do all fractional + 1 - root node + 2 - depth less than modifier + 4 - if objective == best possible + 6 - as 2+4 + when to do all including satisfied + 10 - root node etc. + If >=100 then do when depth <= strategy/100 (otherwise 5) + */ + int strongStrategy_; + /// Number of iterations in strong branching + int numberStrongIterations_; + /** 0 - number times strong branching done, 1 - number fixed, 2 - number infeasible + Second group of three is a snapshot at node [6] */ + int strongInfo_[7]; + /** + For advanced applications you may wish to modify the behavior of Cbc + e.g. if the solver is a NLP solver then you may not have an exact + optimum solution at each step. This gives characteristics - just for one BAB. + For actually saving/restoring a solution you need the actual solver one. + */ + OsiBabSolver * solverCharacteristics_; + /// Whether to force a resolve after takeOffCuts + bool resolveAfterTakeOffCuts_; + /// Maximum number of iterations (designed to be used in heuristics) + int maximumNumberIterations_; + /// Anything with priority >= this can be treated as continuous + int continuousPriority_; + /// Number of outstanding update information items + int numberUpdateItems_; + /// Maximum number of outstanding update information items + int maximumNumberUpdateItems_; + /// Update items + CbcObjectUpdateData * updateItems_; + /// Stored row cuts for donor/recipient CbcModel + CglStored * storedRowCuts_; + /** + Parallel + 0 - off + 1 - testing + 2-99 threads + other special meanings + */ + int numberThreads_; + /** thread mode + always use numberThreads for branching + 1 set then deterministic + 2 set then use numberThreads for root cuts + 4 set then use numberThreads in root mini branch and bound + default is 0 + */ + int threadMode_; + /// Number of global cuts on entry to a node + int numberGlobalCutsIn_; + /// Thread stuff for master + CbcBaseModel * master_; + /// Pointer to masterthread + CbcThread * masterThread_; +//@} +}; +/// So we can use osiObject or CbcObject during transition +void getIntegerInformation(const OsiObject * object, double & originalLower, + double & originalUpper) ; +// So we can call from other programs +// Real main program +class OsiClpSolverInterface; +int CbcMain (int argc, const char *argv[], OsiClpSolverInterface & solver, CbcModel ** babSolver); +int CbcMain (int argc, const char *argv[], CbcModel & babSolver); +// four ways of calling +int callCbc(const char * input2, OsiClpSolverInterface& solver1); +int callCbc(const char * input2); +int callCbc(const std::string input2, OsiClpSolverInterface& solver1); +int callCbc(const std::string input2) ; +// When we want to load up CbcModel with options first +void CbcMain0 (CbcModel & babSolver); +int CbcMain1 (int argc, const char *argv[], CbcModel & babSolver); +// two ways of calling +int callCbc(const char * input2, CbcModel & babSolver); +int callCbc(const std::string input2, CbcModel & babSolver); +// And when CbcMain0 already called to initialize +int callCbc1(const char * input2, CbcModel & babSolver); +int callCbc1(const std::string input2, CbcModel & babSolver); +// And when CbcMain0 already called to initialize (with call back) (see CbcMain1 for whereFrom) +int callCbc1(const char * input2, CbcModel & babSolver, int (CbcModel * currentSolver, int whereFrom)); +int callCbc1(const std::string input2, CbcModel & babSolver, int (CbcModel * currentSolver, int whereFrom)); +int CbcMain1 (int argc, const char *argv[], CbcModel & babSolver, int (CbcModel * currentSolver, int whereFrom)); +// For uniform setting of cut and heuristic options +void setCutAndHeuristicOptions(CbcModel & model); +#endif + |