source: trunk/Cbc/src/CbcCutGenerator.hpp @ 1569

Last change on this file since 1569 was 1432, checked in by bjarni, 10 years ago

Added extra return at end of each source file where needed, to remove possible linefeed conflicts (NightlyBuild? errors)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.9 KB
Line 
1/* $Id: CbcCutGenerator.hpp 1432 2010-02-07 19:33:53Z forrest $ */
2// Copyright (C) 2003, International Business Machines
3// Corporation and others.  All Rights Reserved.
4#ifndef CbcCutGenerator_H
5#define CbcCutGenerator_H
6
7#include "OsiSolverInterface.hpp"
8#include "OsiCuts.hpp"
9#include "CglCutGenerator.hpp"
10#include "CbcCutModifier.hpp"
11
12class CbcModel;
13class OsiRowCut;
14class OsiRowCutDebugger;
15
16//#############################################################################
17
18/** Interface between Cbc and Cut Generation Library.
19
20  \c CbcCutGenerator is intended to provide an intelligent interface between
21  Cbc and the cutting plane algorithms in the CGL. A \c CbcCutGenerator is
22  bound to a \c CglCutGenerator and to an \c CbcModel. It contains parameters
23  which control when and how the \c generateCuts method of the
24  \c CglCutGenerator will be called.
25
26  The builtin decision criteria available to use when deciding whether to
27  generate cuts are limited: every <i>X</i> nodes, when a solution is found,
28  and when a subproblem is found to be infeasible. The idea is that the class
29  will grow more intelligent with time.
30
31  \todo Add a pointer to function member which will allow a client to install
32        their own decision algorithm to decide whether or not to call the CGL
33        \p generateCuts method. Create a default decision method that looks
34        at the builtin criteria.
35
36  \todo It strikes me as not good that generateCuts contains code specific to
37        individual CGL algorithms. Another set of pointer to function members,
38        so that the client can specify the cut generation method as well as
39        pre- and post-generation methods? Taken a bit further, should this
40        class contain a bunch of pointer to function members, one for each
41        of the places where the cut generator might be referenced?
42        Initialization, root node, search tree node, discovery of solution,
43        and termination all come to mind. Initialization and termination would
44        also be useful for instrumenting cbc.
45*/
46
47class CbcCutGenerator  {
48
49public:
50
51    /** \name Generate Cuts */
52    //@{
53    /** Generate cuts for the client model.
54
55      Evaluate the state of the client model and decide whether to generate cuts.
56      The generated cuts are inserted into and returned in the collection of cuts
57      \p cs.
58
59      If \p fullScan is !=0, the generator is obliged to call the CGL
60      \c generateCuts routine.  Otherwise, it is free to make a local decision.
61      Negative fullScan says things like at integer solution
62      The current implementation uses \c whenCutGenerator_ to decide.
63
64      The routine returns true if reoptimisation is needed (because the state of
65      the solver interface has been modified).
66
67      If node then can find out depth
68    */
69    bool generateCuts( OsiCuts &cs, int fullScan, OsiSolverInterface * solver,
70                       CbcNode * node);
71    //@}
72
73
74    /**@name Constructors and destructors */
75    //@{
76    /// Default constructor
77    CbcCutGenerator ();
78
79    /// Normal constructor
80    CbcCutGenerator(CbcModel * model, CglCutGenerator * generator,
81                    int howOften = 1, const char * name = NULL,
82                    bool normal = true, bool atSolution = false,
83                    bool infeasible = false, int howOftenInsub = -100,
84                    int whatDepth = -1, int whatDepthInSub = -1, int switchOffIfLessThan = 0);
85
86    /// Copy constructor
87    CbcCutGenerator (const CbcCutGenerator &);
88
89    /// Assignment operator
90    CbcCutGenerator & operator=(const CbcCutGenerator& rhs);
91
92    /// Destructor
93    ~CbcCutGenerator ();
94    //@}
95
96    /**@name Gets and sets */
97    //@{
98    /** Set the client model.
99
100      In addition to setting the client model, refreshModel also calls
101      the \c refreshSolver method of the CglCutGenerator object.
102    */
103    void refreshModel(CbcModel * model);
104
105    /// return name of generator
106    inline const char * cutGeneratorName() const {
107        return generatorName_;
108    }
109
110    /// Create C++ lines to show how to tune
111    void generateTuning( FILE * fp);
112    /** Set the cut generation interval
113
114      Set the number of nodes evaluated between calls to the Cgl object's
115      \p generateCuts routine.
116
117      If \p value is positive, cuts will always be generated at the specified
118      interval.
119      If \p value is negative, cuts will initially be generated at the specified
120      interval, but Cbc may adjust the value depending on the success of cuts
121      produced by this generator.
122
123      A value of -100 disables the generator, while a value of -99 means
124      just at root.
125    */
126    void setHowOften(int value) ;
127
128    /// Get the cut generation interval.
129    inline int howOften() const {
130        return whenCutGenerator_;
131    }
132    /// Get the cut generation interval.in sub tree
133    inline int howOftenInSub() const {
134        return whenCutGeneratorInSub_;
135    }
136    /// Get level of cut inaccuracy (0 means exact e.g. cliques)
137    inline int inaccuracy() const {
138        return inaccuracy_;
139    }
140    /// Set level of cut inaccuracy (0 means exact e.g. cliques)
141    inline void setInaccuracy(int level) {
142        inaccuracy_ = level;
143    }
144
145    /** Set the cut generation depth
146
147      Set the depth criterion for calls to the Cgl object's
148      \p generateCuts routine.  Only active if > 0.
149
150      If whenCutGenerator is positive and this is positive then this overrides.
151      If whenCutGenerator is -1 then this is used as criterion if any cuts
152      were generated at root node.
153      If whenCutGenerator is anything else this is ignored.
154    */
155    void setWhatDepth(int value) ;
156    /// Set the cut generation depth in sub tree
157    void setWhatDepthInSub(int value) ;
158    /// Get the cut generation depth criterion.
159    inline int whatDepth() const {
160        return depthCutGenerator_;
161    }
162    /// Get the cut generation depth criterion.in sub tree
163    inline int whatDepthInSub() const {
164        return depthCutGeneratorInSub_;
165    }
166
167    /// Get whether the cut generator should be called in the normal place
168    inline bool normal() const {
169        return (switches_&1) != 0;
170    }
171    /// Set whether the cut generator should be called in the normal place
172    inline void setNormal(bool value) {
173        switches_ &= ~1;
174        switches_ |= value ? 1 : 0;
175    }
176    /// Get whether the cut generator should be called when a solution is found
177    inline bool atSolution() const {
178        return (switches_&2) != 0;
179    }
180    /// Set whether the cut generator should be called when a solution is found
181    inline void setAtSolution(bool value) {
182        switches_ &= ~2;
183        switches_ |= value ? 2 : 0;
184    }
185    /** Get whether the cut generator should be called when the subproblem is
186        found to be infeasible.
187    */
188    inline bool whenInfeasible() const {
189        return (switches_&4) != 0;
190    }
191    /** Set whether the cut generator should be called when the subproblem is
192        found to be infeasible.
193    */
194    inline void setWhenInfeasible(bool value) {
195        switches_ &= ~4;
196        switches_ |= value ? 4 : 0;
197    }
198    /// Get whether the cut generator is being timed
199    inline bool timing() const {
200        return (switches_&64) != 0;
201    }
202    /// Set whether the cut generator is being timed
203    inline void setTiming(bool value) {
204        switches_ &= ~64;
205        switches_ |= value ? 64 : 0;
206        timeInCutGenerator_ = 0.0;
207    }
208    /// Return time taken in cut generator
209    inline double timeInCutGenerator() const {
210        return timeInCutGenerator_;
211    }
212    inline void incrementTimeInCutGenerator(double value) {
213        timeInCutGenerator_ += value;
214    }
215    /// Get the \c CglCutGenerator corresponding to this \c CbcCutGenerator.
216    inline CglCutGenerator * generator() const {
217        return generator_;
218    }
219    /// Number times cut generator entered
220    inline int numberTimesEntered() const {
221        return numberTimes_;
222    }
223    inline void setNumberTimesEntered(int value) {
224        numberTimes_ = value;
225    }
226    inline void incrementNumberTimesEntered(int value = 1) {
227        numberTimes_ += value;
228    }
229    /// Total number of cuts added
230    inline int numberCutsInTotal() const {
231        return numberCuts_;
232    }
233    inline void setNumberCutsInTotal(int value) {
234        numberCuts_ = value;
235    }
236    inline void incrementNumberCutsInTotal(int value = 1) {
237        numberCuts_ += value;
238    }
239    /// Total number of elements added
240    inline int numberElementsInTotal() const {
241        return numberElements_;
242    }
243    inline void setNumberElementsInTotal(int value) {
244        numberElements_ = value;
245    }
246    inline void incrementNumberElementsInTotal(int value = 1) {
247        numberElements_ += value;
248    }
249    /// Total number of column cuts
250    inline int numberColumnCuts() const {
251        return numberColumnCuts_;
252    }
253    inline void setNumberColumnCuts(int value) {
254        numberColumnCuts_ = value;
255    }
256    inline void incrementNumberColumnCuts(int value = 1) {
257        numberColumnCuts_ += value;
258    }
259    /// Total number of cuts active after (at end of n cut passes at each node)
260    inline int numberCutsActive() const {
261        return numberCutsActive_;
262    }
263    inline void setNumberCutsActive(int value) {
264        numberCutsActive_ = value;
265    }
266    inline void incrementNumberCutsActive(int value = 1) {
267        numberCutsActive_ += value;
268    }
269    inline void setSwitchOffIfLessThan(int value) {
270        switchOffIfLessThan_ = value;
271    }
272    inline int switchOffIfLessThan() const {
273        return switchOffIfLessThan_;
274    }
275    /// Say if optimal basis needed
276    inline bool needsOptimalBasis() const {
277        return (switches_&128) != 0;
278    }
279    /// Set if optimal basis needed
280    inline void setNeedsOptimalBasis(bool yesNo) {
281        switches_ &= ~128;
282        switches_ |= yesNo ? 128 : 0;
283    }
284    /// Whether generator MUST be called again if any cuts (i.e. ignore break from loop)
285    inline bool mustCallAgain() const {
286        return (switches_&8) != 0;
287    }
288    /// Set whether generator MUST be called again if any cuts (i.e. ignore break from loop)
289    inline void setMustCallAgain(bool yesNo) {
290        switches_ &= ~8;
291        switches_ |= yesNo ? 8 : 0;
292    }
293    /// Whether generator switched off for moment
294    inline bool switchedOff() const {
295        return (switches_&16) != 0;
296    }
297    /// Set whether generator switched off for moment
298    inline void setSwitchedOff(bool yesNo) {
299        switches_ &= ~16;
300        switches_ |= yesNo ? 16 : 0;
301    }
302    /// Whether last round of cuts did little
303    inline bool ineffectualCuts() const {
304        return (switches_&512) != 0;
305    }
306    /// Set whether last round of cuts did little
307    inline void setIneffectualCuts(bool yesNo) {
308        switches_ &= ~512;
309        switches_ |= yesNo ? 512 : 0;
310    }
311    /// Whether to use if any cuts generated
312    inline bool whetherToUse() const {
313        return (switches_&1024) != 0;
314    }
315    /// Set whether to use if any cuts generated
316    inline void setWhetherToUse(bool yesNo) {
317        switches_ &= ~1024;
318        switches_ |= yesNo ? 1024 : 0;
319    }
320    /// Number of cuts generated at root
321    inline int numberCutsAtRoot() const {
322        return numberCutsAtRoot_;
323    }
324    inline void setNumberCutsAtRoot(int value) {
325        numberCutsAtRoot_ = value;
326    }
327    /// Number of cuts active at root
328    inline int numberActiveCutsAtRoot() const {
329        return numberActiveCutsAtRoot_;
330    }
331    inline void setNumberActiveCutsAtRoot(int value) {
332        numberActiveCutsAtRoot_ = value;
333    }
334    /// Number of short cuts at root
335    inline int numberShortCutsAtRoot() const {
336        return numberShortCutsAtRoot_;
337    }
338    /// Set model
339    inline void setModel(CbcModel * model) {
340        model_ = model;
341    }
342    /// Whether global cuts at root
343    inline bool globalCutsAtRoot() const {
344        return (switches_&32) != 0;
345    }
346    /// Set whether global cuts at root
347    inline void setGlobalCutsAtRoot(bool yesNo) {
348        switches_ &= ~32;
349        switches_ |= yesNo ? 32 : 0;
350    }
351    /// Whether global cuts
352    inline bool globalCuts() const {
353        return (switches_&256) != 0;
354    }
355    /// Set whether global cuts
356    inline void setGlobalCuts(bool yesNo) {
357        switches_ &= ~256;
358        switches_ |= yesNo ? 256 : 0;
359    }
360    //@}
361
362private:
363    /**@name Private gets and sets */
364    //@{
365    //@}
366    /// Saved cuts
367    OsiCuts savedCuts_;
368    /// Time in cut generator
369    double timeInCutGenerator_;
370    /// The client model
371    CbcModel *model_;
372
373    // The CglCutGenerator object
374    CglCutGenerator * generator_;
375
376    /// Name of generator
377    char * generatorName_;
378
379    /** Number of nodes between calls to the CglCutGenerator::generateCuts
380       routine.
381    */
382    int whenCutGenerator_;
383    /** Number of nodes between calls to the CglCutGenerator::generateCuts
384       routine in sub tree.
385    */
386    int whenCutGeneratorInSub_;
387    /** If first pass at root produces fewer than this cuts then switch off
388     */
389    int switchOffIfLessThan_;
390
391    /** Depth at which to call the CglCutGenerator::generateCuts
392       routine (If >0 then overrides when and is called if depth%depthCutGenerator==0).
393    */
394    int depthCutGenerator_;
395
396    /** Depth at which to call the CglCutGenerator::generateCuts
397       routine (If >0 then overrides when and is called if depth%depthCutGenerator==0).
398       In sub tree.
399    */
400    int depthCutGeneratorInSub_;
401
402    /// Level of cut inaccuracy (0 means exact e.g. cliques)
403    int inaccuracy_;
404    /// Number times cut generator entered
405    int numberTimes_;
406    /// Total number of cuts added
407    int numberCuts_;
408    /// Total number of elements added
409    int numberElements_;
410    /// Total number of column cuts added
411    int numberColumnCuts_;
412    /// Total number of cuts active after (at end of n cut passes at each node)
413    int numberCutsActive_;
414    /// Number of cuts generated at root
415    int numberCutsAtRoot_;
416    /// Number of cuts active at root
417    int numberActiveCutsAtRoot_;
418    /// Number of short cuts at root
419    int numberShortCutsAtRoot_;
420    /// Switches - see gets and sets
421    int switches_;
422};
423
424// How often to do if mostly switched off (A)
425# define SCANCUTS 1000
426// How often to do if mostly switched off (probing B)
427# define SCANCUTS_PROBING 1000
428
429#endif
430
Note: See TracBrowser for help on using the repository browser.