lemon/counter.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 982 bb70ad62c95f
parent 209 765619b7cbb2
child 833 e20173729589
permissions -rw-r--r--
Fix critical bug in preflow (#372)

The wrong transition between the bound decrease and highest active
heuristics caused the bug. The last node chosen in bound decrease mode
is used in the first iteration in highest active mode.
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     5  * Copyright (C) 2003-2009
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #ifndef LEMON_COUNTER_H
    20 #define LEMON_COUNTER_H
    21 
    22 #include <string>
    23 #include <iostream>
    24 
    25 ///\ingroup timecount
    26 ///\file
    27 ///\brief Tools for counting steps and events
    28 
    29 namespace lemon
    30 {
    31 
    32   template<class P> class _NoSubCounter;
    33 
    34   template<class P>
    35   class _SubCounter
    36   {
    37     P &_parent;
    38     std::string _title;
    39     std::ostream &_os;
    40     int count;
    41   public:
    42 
    43     typedef _SubCounter<_SubCounter<P> > SubCounter;
    44     typedef _NoSubCounter<_SubCounter<P> > NoSubCounter;
    45 
    46     _SubCounter(P &parent)
    47       : _parent(parent), _title(), _os(std::cerr), count(0) {}
    48     _SubCounter(P &parent,std::string title,std::ostream &os=std::cerr)
    49       : _parent(parent), _title(title), _os(os), count(0) {}
    50     _SubCounter(P &parent,const char *title,std::ostream &os=std::cerr)
    51       : _parent(parent), _title(title), _os(os), count(0) {}
    52     ~_SubCounter() {
    53       _os << _title << count <<std::endl;
    54       _parent+=count;
    55     }
    56     _SubCounter &operator++() { count++; return *this;}
    57     int operator++(int) { return count++; }
    58     _SubCounter &operator--() { count--; return *this;}
    59     int operator--(int) { return count--; }
    60     _SubCounter &operator+=(int c) { count+=c; return *this;}
    61     _SubCounter &operator-=(int c) { count-=c; return *this;}
    62     operator int() {return count;}
    63   };
    64 
    65   template<class P>
    66   class _NoSubCounter
    67   {
    68     P &_parent;
    69   public:
    70     typedef _NoSubCounter<_NoSubCounter<P> > SubCounter;
    71     typedef _NoSubCounter<_NoSubCounter<P> > NoSubCounter;
    72 
    73     _NoSubCounter(P &parent) :_parent(parent) {}
    74     _NoSubCounter(P &parent,std::string,std::ostream &)
    75       :_parent(parent) {}
    76     _NoSubCounter(P &parent,std::string)
    77       :_parent(parent) {}
    78     _NoSubCounter(P &parent,const char *,std::ostream &)
    79       :_parent(parent) {}
    80     _NoSubCounter(P &parent,const char *)
    81       :_parent(parent) {}
    82     ~_NoSubCounter() {}
    83     _NoSubCounter &operator++() { ++_parent; return *this;}
    84     int operator++(int) { _parent++; return 0;}
    85     _NoSubCounter &operator--() { --_parent; return *this;}
    86     int operator--(int) { _parent--; return 0;}
    87     _NoSubCounter &operator+=(int c) { _parent+=c; return *this;}
    88     _NoSubCounter &operator-=(int c) { _parent-=c; return *this;}
    89     operator int() {return 0;}
    90   };
    91 
    92 
    93   /// \addtogroup timecount
    94   /// @{
    95 
    96   /// A counter class
    97 
    98   /// This class makes it easier to count certain events (e.g. for debug
    99   /// reasons).
   100   /// You can increment or decrement the counter using \c operator++,
   101   /// \c operator--, \c operator+= and \c operator-=. You can also
   102   /// define subcounters for the different phases of the algorithm or
   103   /// for different types of operations.
   104   /// A report containing the given title and the value of the counter
   105   /// is automatically printed on destruction.
   106   ///
   107   /// The following example shows the usage of counters and subcounters.
   108   /// \code
   109   /// // Bubble sort
   110   /// std::vector<T> v;
   111   /// ...
   112   /// Counter op("Operations: ");
   113   /// Counter::SubCounter as(op, "Assignments: ");
   114   /// Counter::SubCounter co(op, "Comparisons: ");
   115   /// for (int i = v.size()-1; i > 0; --i) {
   116   ///   for (int j = 0; j < i; ++j) {
   117   ///     if (v[j] > v[j+1]) {
   118   ///       T tmp = v[j];
   119   ///       v[j] = v[j+1];
   120   ///       v[j+1] = tmp;
   121   ///       as += 3;          // three assignments
   122   ///     }
   123   ///     ++co;               // one comparison
   124   ///   }
   125   /// }
   126   /// \endcode
   127   ///
   128   /// This code prints out something like that:
   129   /// \code
   130   /// Comparisons: 45
   131   /// Assignments: 57
   132   /// Operations: 102
   133   /// \endcode
   134   ///
   135   /// \sa NoCounter
   136   class Counter
   137   {
   138     std::string _title;
   139     std::ostream &_os;
   140     int count;
   141   public:
   142 
   143     /// SubCounter class
   144 
   145     /// This class can be used to setup subcounters for a \ref Counter
   146     /// to have finer reports. A subcounter provides exactly the same
   147     /// operations as the main \ref Counter, but it also increments and
   148     /// decrements the value of its parent.
   149     /// Subcounters can also have subcounters.
   150     ///
   151     /// The parent counter must be given as the first parameter of the
   152     /// constructor. Apart from that a title and an \c ostream object
   153     /// can also be given just like for the main \ref Counter.
   154     ///
   155     /// A report containing the given title and the value of the
   156     /// subcounter is automatically printed on destruction. If you
   157     /// would like to turn off this report, use \ref NoSubCounter
   158     /// instead.
   159     ///
   160     /// \sa NoSubCounter
   161     typedef _SubCounter<Counter> SubCounter;
   162 
   163     /// SubCounter class without printing report on destruction
   164 
   165     /// This class can be used to setup subcounters for a \ref Counter.
   166     /// It is the same as \ref SubCounter but it does not print report
   167     /// on destruction. (It modifies the value of its parent, so 'No'
   168     /// only means 'do not print'.)
   169     ///
   170     /// Replacing \ref SubCounter "SubCounter"s with \ref NoSubCounter
   171     /// "NoSubCounter"s makes it possible to turn off reporting
   172     /// subcounter values without actually removing the definitions
   173     /// and the increment or decrement operators.
   174     ///
   175     /// \sa SubCounter
   176     typedef _NoSubCounter<Counter> NoSubCounter;
   177 
   178     /// Constructor.
   179     Counter() : _title(), _os(std::cerr), count(0) {}
   180     /// Constructor.
   181     Counter(std::string title,std::ostream &os=std::cerr)
   182       : _title(title), _os(os), count(0) {}
   183     /// Constructor.
   184     Counter(const char *title,std::ostream &os=std::cerr)
   185       : _title(title), _os(os), count(0) {}
   186     /// Destructor. Prints the given title and the value of the counter.
   187     ~Counter() {
   188       _os << _title << count <<std::endl;
   189     }
   190     ///\e
   191     Counter &operator++() { count++; return *this;}
   192     ///\e
   193     int operator++(int) { return count++;}
   194     ///\e
   195     Counter &operator--() { count--; return *this;}
   196     ///\e
   197     int operator--(int) { return count--;}
   198     ///\e
   199     Counter &operator+=(int c) { count+=c; return *this;}
   200     ///\e
   201     Counter &operator-=(int c) { count-=c; return *this;}
   202     /// Resets the counter to the given value.
   203 
   204     /// Resets the counter to the given value.
   205     /// \note This function does not reset the values of
   206     /// \ref SubCounter "SubCounter"s but it resets \ref NoSubCounter
   207     /// "NoSubCounter"s along with the main counter.
   208     void reset(int c=0) {count=c;}
   209     /// Returns the value of the counter.
   210     operator int() {return count;}
   211   };
   212 
   213   /// 'Do nothing' version of Counter.
   214 
   215   /// This class can be used in the same way as \ref Counter however it
   216   /// does not count at all and does not print report on destruction.
   217   ///
   218   /// Replacing a \ref Counter with a \ref NoCounter makes it possible
   219   /// to turn off all counting and reporting (SubCounters should also
   220   /// be replaced with NoSubCounters), so it does not affect the
   221   /// efficiency of the program at all.
   222   ///
   223   /// \sa Counter
   224   class NoCounter
   225   {
   226   public:
   227     typedef _NoSubCounter<NoCounter> SubCounter;
   228     typedef _NoSubCounter<NoCounter> NoSubCounter;
   229 
   230     NoCounter() {}
   231     NoCounter(std::string,std::ostream &) {}
   232     NoCounter(const char *,std::ostream &) {}
   233     NoCounter(std::string) {}
   234     NoCounter(const char *) {}
   235     NoCounter &operator++() { return *this; }
   236     int operator++(int) { return 0; }
   237     NoCounter &operator--() { return *this; }
   238     int operator--(int) { return 0; }
   239     NoCounter &operator+=(int) { return *this;}
   240     NoCounter &operator-=(int) { return *this;}
   241     void reset(int) {}
   242     void reset() {}
   243     operator int() {return 0;}
   244   };
   245 
   246   ///@}
   247 }
   248 
   249 #endif