diff options
author | Harpreet | 2016-08-04 15:25:44 +0530 |
---|---|---|
committer | Harpreet | 2016-08-04 15:25:44 +0530 |
commit | 9fd2976931c088dc523974afb901e96bad20f73c (patch) | |
tree | 22502de6e6988d5cd595290d11266f8432ad825b /build/Bonmin/include/coin/CbcCutGenerator.hpp | |
download | FOSSEE-Optim-toolbox-development-9fd2976931c088dc523974afb901e96bad20f73c.tar.gz FOSSEE-Optim-toolbox-development-9fd2976931c088dc523974afb901e96bad20f73c.tar.bz2 FOSSEE-Optim-toolbox-development-9fd2976931c088dc523974afb901e96bad20f73c.zip |
initial add
Diffstat (limited to 'build/Bonmin/include/coin/CbcCutGenerator.hpp')
-rw-r--r-- | build/Bonmin/include/coin/CbcCutGenerator.hpp | 482 |
1 files changed, 482 insertions, 0 deletions
diff --git a/build/Bonmin/include/coin/CbcCutGenerator.hpp b/build/Bonmin/include/coin/CbcCutGenerator.hpp new file mode 100644 index 0000000..f07142e --- /dev/null +++ b/build/Bonmin/include/coin/CbcCutGenerator.hpp @@ -0,0 +1,482 @@ +/* $Id: CbcCutGenerator.hpp 2081 2014-09-25 11:31:17Z forrest $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcCutGenerator_H +#define CbcCutGenerator_H + +#include "OsiSolverInterface.hpp" +#include "OsiCuts.hpp" +#include "CglCutGenerator.hpp" +#include "CbcCutModifier.hpp" + +class CbcModel; +class OsiRowCut; +class OsiRowCutDebugger; + +//############################################################################# + +/** Interface between Cbc and Cut Generation Library. + + \c CbcCutGenerator is intended to provide an intelligent interface between + Cbc and the cutting plane algorithms in the CGL. A \c CbcCutGenerator is + bound to a \c CglCutGenerator and to an \c CbcModel. It contains parameters + which control when and how the \c generateCuts method of the + \c CglCutGenerator will be called. + + The builtin decision criteria available to use when deciding whether to + generate cuts are limited: every <i>X</i> nodes, when a solution is found, + and when a subproblem is found to be infeasible. The idea is that the class + will grow more intelligent with time. + + \todo Add a pointer to function member which will allow a client to install + their own decision algorithm to decide whether or not to call the CGL + \p generateCuts method. Create a default decision method that looks + at the builtin criteria. + + \todo It strikes me as not good that generateCuts contains code specific to + individual CGL algorithms. Another set of pointer to function members, + so that the client can specify the cut generation method as well as + pre- and post-generation methods? Taken a bit further, should this + class contain a bunch of pointer to function members, one for each + of the places where the cut generator might be referenced? + Initialization, root node, search tree node, discovery of solution, + and termination all come to mind. Initialization and termination would + also be useful for instrumenting cbc. +*/ + +class CbcCutGenerator { + +public: + + /** \name Generate Cuts */ + //@{ + /** Generate cuts for the client model. + + Evaluate the state of the client model and decide whether to generate cuts. + The generated cuts are inserted into and returned in the collection of cuts + \p cs. + + If \p fullScan is !=0, the generator is obliged to call the CGL + \c generateCuts routine. Otherwise, it is free to make a local decision. + Negative fullScan says things like at integer solution + The current implementation uses \c whenCutGenerator_ to decide. + + The routine returns true if reoptimisation is needed (because the state of + the solver interface has been modified). + + If node then can find out depth + */ + bool generateCuts( OsiCuts &cs, int fullScan, OsiSolverInterface * solver, + CbcNode * node); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CbcCutGenerator (); + + /// Normal constructor + CbcCutGenerator(CbcModel * model, 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, int switchOffIfLessThan = 0); + + /// Copy constructor + CbcCutGenerator (const CbcCutGenerator &); + + /// Assignment operator + CbcCutGenerator & operator=(const CbcCutGenerator& rhs); + + /// Destructor + ~CbcCutGenerator (); + //@} + + /**@name Gets and sets */ + //@{ + /** Set the client model. + + In addition to setting the client model, refreshModel also calls + the \c refreshSolver method of the CglCutGenerator object. + */ + void refreshModel(CbcModel * model); + + /// return name of generator + inline const char * cutGeneratorName() const { + return generatorName_; + } + + /// Create C++ lines to show how to tune + void generateTuning( FILE * fp); + /** Set the cut generation interval + + Set the number of nodes evaluated between calls to the Cgl object's + \p generateCuts routine. + + If \p value is positive, cuts will always be generated at the specified + interval. + If \p value is negative, cuts will initially be generated at the specified + interval, but Cbc may adjust the value depending on the success of cuts + produced by this generator. + + A value of -100 disables the generator, while a value of -99 means + just at root. + */ + void setHowOften(int value) ; + + /// Get the cut generation interval. + inline int howOften() const { + return whenCutGenerator_; + } + /// Get the cut generation interval.in sub tree + inline int howOftenInSub() const { + return whenCutGeneratorInSub_; + } + /// Get level of cut inaccuracy (0 means exact e.g. cliques) + inline int inaccuracy() const { + return inaccuracy_; + } + /// Set level of cut inaccuracy (0 means exact e.g. cliques) + inline void setInaccuracy(int level) { + inaccuracy_ = level; + } + + /** Set the cut generation depth + + Set the depth criterion for calls to the Cgl object's + \p generateCuts routine. Only active if > 0. + + If whenCutGenerator is positive and this is positive then this overrides. + If whenCutGenerator is -1 then this is used as criterion if any cuts + were generated at root node. + If whenCutGenerator is anything else this is ignored. + */ + void setWhatDepth(int value) ; + /// Set the cut generation depth in sub tree + void setWhatDepthInSub(int value) ; + /// Get the cut generation depth criterion. + inline int whatDepth() const { + return depthCutGenerator_; + } + /// Get the cut generation depth criterion.in sub tree + inline int whatDepthInSub() const { + return depthCutGeneratorInSub_; + } + /// Set maximum number of times to enter + inline void setMaximumTries(int value) + { maximumTries_ = value;} + /// Get maximum number of times to enter + inline int maximumTries() const + { return maximumTries_;} + + /// Get switches + inline int switches() const { + return switches_; + } + /// Set switches (for copying from virgin state) + inline void setSwitches(int value) { + switches_ = value; + } + /// Get whether the cut generator should be called in the normal place + inline bool normal() const { + return (switches_&1) != 0; + } + /// Set whether the cut generator should be called in the normal place + inline void setNormal(bool value) { + switches_ &= ~1; + switches_ |= value ? 1 : 0; + } + /// Get whether the cut generator should be called when a solution is found + inline bool atSolution() const { + return (switches_&2) != 0; + } + /// Set whether the cut generator should be called when a solution is found + inline void setAtSolution(bool value) { + switches_ &= ~2; + switches_ |= value ? 2 : 0; + } + /** Get whether the cut generator should be called when the subproblem is + found to be infeasible. + */ + inline bool whenInfeasible() const { + return (switches_&4) != 0; + } + /** Set whether the cut generator should be called when the subproblem is + found to be infeasible. + */ + inline void setWhenInfeasible(bool value) { + switches_ &= ~4; + switches_ |= value ? 4 : 0; + } + /// Get whether the cut generator is being timed + inline bool timing() const { + return (switches_&64) != 0; + } + /// Set whether the cut generator is being timed + inline void setTiming(bool value) { + switches_ &= ~64; + switches_ |= value ? 64 : 0; + timeInCutGenerator_ = 0.0; + } + /// Return time taken in cut generator + inline double timeInCutGenerator() const { + return timeInCutGenerator_; + } + inline void incrementTimeInCutGenerator(double value) { + timeInCutGenerator_ += value; + } + /// Get the \c CglCutGenerator corresponding to this \c CbcCutGenerator. + inline CglCutGenerator * generator() const { + return generator_; + } + /// Number times cut generator entered + inline int numberTimesEntered() const { + return numberTimes_; + } + inline void setNumberTimesEntered(int value) { + numberTimes_ = value; + } + inline void incrementNumberTimesEntered(int value = 1) { + numberTimes_ += value; + } + /// Total number of cuts added + inline int numberCutsInTotal() const { + return numberCuts_; + } + inline void setNumberCutsInTotal(int value) { + numberCuts_ = value; + } + inline void incrementNumberCutsInTotal(int value = 1) { + numberCuts_ += value; + } + /// Total number of elements added + inline int numberElementsInTotal() const { + return numberElements_; + } + inline void setNumberElementsInTotal(int value) { + numberElements_ = value; + } + inline void incrementNumberElementsInTotal(int value = 1) { + numberElements_ += value; + } + /// Total number of column cuts + inline int numberColumnCuts() const { + return numberColumnCuts_; + } + inline void setNumberColumnCuts(int value) { + numberColumnCuts_ = value; + } + inline void incrementNumberColumnCuts(int value = 1) { + numberColumnCuts_ += value; + } + /// Total number of cuts active after (at end of n cut passes at each node) + inline int numberCutsActive() const { + return numberCutsActive_; + } + inline void setNumberCutsActive(int value) { + numberCutsActive_ = value; + } + inline void incrementNumberCutsActive(int value = 1) { + numberCutsActive_ += value; + } + inline void setSwitchOffIfLessThan(int value) { + switchOffIfLessThan_ = value; + } + inline int switchOffIfLessThan() const { + return switchOffIfLessThan_; + } + /// Say if optimal basis needed + inline bool needsOptimalBasis() const { + return (switches_&128) != 0; + } + /// Set if optimal basis needed + inline void setNeedsOptimalBasis(bool yesNo) { + switches_ &= ~128; + switches_ |= yesNo ? 128 : 0; + } + /// Whether generator MUST be called again if any cuts (i.e. ignore break from loop) + inline bool mustCallAgain() const { + return (switches_&8) != 0; + } + /// Set whether generator MUST be called again if any cuts (i.e. ignore break from loop) + inline void setMustCallAgain(bool yesNo) { + switches_ &= ~8; + switches_ |= yesNo ? 8 : 0; + } + /// Whether generator switched off for moment + inline bool switchedOff() const { + return (switches_&16) != 0; + } + /// Set whether generator switched off for moment + inline void setSwitchedOff(bool yesNo) { + switches_ &= ~16; + switches_ |= yesNo ? 16 : 0; + } + /// Whether last round of cuts did little + inline bool ineffectualCuts() const { + return (switches_&512) != 0; + } + /// Set whether last round of cuts did little + inline void setIneffectualCuts(bool yesNo) { + switches_ &= ~512; + switches_ |= yesNo ? 512 : 0; + } + /// Whether to use if any cuts generated + inline bool whetherToUse() const { + return (switches_&1024) != 0; + } + /// Set whether to use if any cuts generated + inline void setWhetherToUse(bool yesNo) { + switches_ &= ~1024; + switches_ |= yesNo ? 1024 : 0; + } + /// Whether in must call again mode (or after others) + inline bool whetherInMustCallAgainMode() const { + return (switches_&2048) != 0; + } + /// Set whether in must call again mode (or after others) + inline void setWhetherInMustCallAgainMode(bool yesNo) { + switches_ &= ~2048; + switches_ |= yesNo ? 2048 : 0; + } + /// Whether to call at end + inline bool whetherCallAtEnd() const { + return (switches_&4096) != 0; + } + /// Set whether to call at end + inline void setWhetherCallAtEnd(bool yesNo) { + switches_ &= ~4096; + switches_ |= yesNo ? 4096 : 0; + } + /// Whether needs refresh on copy + inline bool needsRefresh() const { + return (switches_&8192) != 0; + } + /// Set whether needs refresh on copy + inline void setNeedsRefresh(bool yesNo) { + switches_ &= ~8192; + switches_ |= yesNo ? 8192 : 0; + } + /// Number of cuts generated at root + inline int numberCutsAtRoot() const { + return numberCutsAtRoot_; + } + inline void setNumberCutsAtRoot(int value) { + numberCutsAtRoot_ = value; + } + /// Number of cuts active at root + inline int numberActiveCutsAtRoot() const { + return numberActiveCutsAtRoot_; + } + inline void setNumberActiveCutsAtRoot(int value) { + numberActiveCutsAtRoot_ = value; + } + /// Number of short cuts at root + inline int numberShortCutsAtRoot() const { + return numberShortCutsAtRoot_; + } + inline void setNumberShortCutsAtRoot(int value) { + numberShortCutsAtRoot_ = value; + } + /// Set model + inline void setModel(CbcModel * model) { + model_ = model; + } + /// Whether global cuts at root + inline bool globalCutsAtRoot() const { + return (switches_&32) != 0; + } + /// Set whether global cuts at root + inline void setGlobalCutsAtRoot(bool yesNo) { + switches_ &= ~32; + switches_ |= yesNo ? 32 : 0; + } + /// Whether global cuts + inline bool globalCuts() const { + return (switches_&256) != 0; + } + /// Set whether global cuts + inline void setGlobalCuts(bool yesNo) { + switches_ &= ~256; + switches_ |= yesNo ? 256 : 0; + } + /// Add in statistics from other + void addStatistics(const CbcCutGenerator * other); + /// Scale back statistics by factor + void scaleBackStatistics(int factor); + //@} + +private: + /**@name Private gets and sets */ + //@{ + //@} + /// Saved cuts + OsiCuts savedCuts_; + /// Time in cut generator + double timeInCutGenerator_; + /// The client model + CbcModel *model_; + + // The CglCutGenerator object + CglCutGenerator * generator_; + + /// Name of generator + char * generatorName_; + + /** Number of nodes between calls to the CglCutGenerator::generateCuts + routine. + */ + int whenCutGenerator_; + /** Number of nodes between calls to the CglCutGenerator::generateCuts + routine in sub tree. + */ + int whenCutGeneratorInSub_; + /** If first pass at root produces fewer than this cuts then switch off + */ + int switchOffIfLessThan_; + + /** Depth at which to call the CglCutGenerator::generateCuts + routine (If >0 then overrides when and is called if depth%depthCutGenerator==0). + */ + int depthCutGenerator_; + + /** Depth at which to call the CglCutGenerator::generateCuts + routine (If >0 then overrides when and is called if depth%depthCutGenerator==0). + In sub tree. + */ + int depthCutGeneratorInSub_; + + /// Level of cut inaccuracy (0 means exact e.g. cliques) + int inaccuracy_; + /// Number times cut generator entered + int numberTimes_; + /// Total number of cuts added + int numberCuts_; + /// Total number of elements added + int numberElements_; + /// Total number of column cuts added + int numberColumnCuts_; + /// Total number of cuts active after (at end of n cut passes at each node) + int numberCutsActive_; + /// Number of cuts generated at root + int numberCutsAtRoot_; + /// Number of cuts active at root + int numberActiveCutsAtRoot_; + /// Number of short cuts at root + int numberShortCutsAtRoot_; + /// Switches - see gets and sets + int switches_; + /// Maximum number of times to enter + int maximumTries_; +}; + +// How often to do if mostly switched off (A) +# define SCANCUTS 1000 +// How often to do if mostly switched off (probing B) +# define SCANCUTS_PROBING 1000 + +#endif + |