COIN-OR::LEMON - Graph Library

Ticket #397: 70bee017b584.patch

File 70bee017b584.patch, 32.2 KB (added by thoneyvazul, 13 years ago)
  • lemon/Makefile.am

    # HG changeset patch
    # User Antal Nemes <thoneyvazul@gmail.com>
    # Date 1289856215 -3600
    # Node ID 70bee017b584c6c4e3dd4013e37a4d875dbbe0f0
    # Parent  1937b6455b7d0cff4f1e21bdd7c5a66b4c1af1cf
    Port max. card. search alg. from svn -r3512 (#397) and (#56)
    
    diff --git a/lemon/Makefile.am b/lemon/Makefile.am
    a b  
    107107        lemon/matching.h \
    108108        lemon/math.h \
    109109        lemon/min_cost_arborescence.h \
     110        lemon/max_cardinality_search.h \
    110111        lemon/nauty_reader.h \
    111112        lemon/network_simplex.h \
    112113        lemon/pairing_heap.h \
  • new file lemon/max_cardinality_search.h

    diff --git a/lemon/max_cardinality_search.h b/lemon/max_cardinality_search.h
    new file mode 100644
    - +  
     1/* -*- C++ -*-
     2 *
     3 * This file is a part of LEMON, a generic C++ optimization library
     4 *
     5 * Copyright (C) 2003-2010
     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_MAX_CARDINALITY_SEARCH_H
     20#define LEMON_MAX_CARDINALITY_SEARCH_H
     21
     22
     23/// \ingroup search
     24/// \file
     25/// \brief Maximum cardinality search in undirected digraphs.
     26
     27#include <lemon/bin_heap.h>
     28#include <lemon/bucket_heap.h>
     29
     30#include <lemon/error.h>
     31#include <lemon/maps.h>
     32
     33#include <functional>
     34
     35namespace lemon {
     36
     37  /// \brief Default traits class of MaxCardinalitySearch class.
     38  ///
     39  /// Default traits class of MaxCardinalitySearch class.
     40  /// \param Digraph Digraph type.
     41  /// \param CapacityMap Type of capacity map.
     42  template <typename GR, typename CAP>
     43  struct MaxCardinalitySearchDefaultTraits {
     44    /// The digraph type the algorithm runs on.
     45    typedef GR Digraph;
     46
     47    template <typename CM>
     48    struct CapMapSelector {
     49
     50      typedef CM CapacityMap;
     51
     52      static CapacityMap *createCapacityMap(const Digraph& g) {
     53        return new CapacityMap(g);
     54      }
     55    };
     56
     57    template <typename CM>
     58    struct CapMapSelector<ConstMap<CM, Const<int, 1> > > {
     59
     60      typedef ConstMap<CM, Const<int, 1> > CapacityMap;
     61
     62      static CapacityMap *createCapacityMap(const Digraph&) {
     63        return new CapacityMap;
     64      }
     65    };
     66
     67    /// \brief The type of the map that stores the arc capacities.
     68    ///
     69    /// The type of the map that stores the arc capacities.
     70    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
     71    typedef typename CapMapSelector<CAP>::CapacityMap CapacityMap;
     72
     73    /// \brief The type of the capacity of the arcs.
     74    typedef typename CapacityMap::Value Value;
     75
     76    /// \brief Instantiates a CapacityMap.
     77    ///
     78    /// This function instantiates a \ref CapacityMap.
     79    /// \param digraph is the digraph, to which we would like to define
     80    /// the CapacityMap.
     81    static CapacityMap *createCapacityMap(const Digraph& digraph) {
     82      return CapMapSelector<CapacityMap>::createCapacityMap(digraph);
     83    }
     84
     85    /// \brief The cross reference type used by heap.
     86    ///
     87    /// The cross reference type used by heap.
     88    /// Usually it is \c Digraph::NodeMap<int>.
     89    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
     90
     91    /// \brief Instantiates a HeapCrossRef.
     92    ///
     93    /// This function instantiates a \ref HeapCrossRef.
     94    /// \param digraph is the digraph, to which we would like to define the
     95    /// HeapCrossRef.
     96    static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) {
     97      return new HeapCrossRef(digraph);
     98    }
     99   
     100    template <typename CapacityMap>
     101    struct HeapSelector {
     102      template <typename Value, typename Ref>
     103      struct Selector {
     104        typedef BinHeap<Value, Ref, std::greater<Value> > Heap;
     105      };
     106    };
     107
     108    template <typename CapacityKey>
     109    struct HeapSelector<ConstMap<CapacityKey, Const<int, 1> > > {
     110      template <typename Value, typename Ref>
     111      struct Selector {
     112        typedef BucketHeap<Ref, false > Heap;
     113      };
     114    };
     115
     116    /// \brief The heap type used by MaxCardinalitySearch algorithm.
     117    ///
     118    /// The heap type used by MaxCardinalitySearch algorithm. It should
     119    /// maximalize the priorities. The default heap type is
     120    /// the \ref BinHeap, but it is specialized when the
     121    /// CapacityMap is ConstMap<Digraph::Node, Const<int, 1> >
     122    /// to BucketHeap.
     123    ///
     124    /// \sa MaxCardinalitySearch
     125    typedef typename HeapSelector<CapacityMap>
     126    ::template Selector<Value, HeapCrossRef>
     127    ::Heap Heap;
     128
     129    /// \brief Instantiates a Heap.
     130    ///
     131    /// This function instantiates a \ref Heap.
     132    /// \param crossref The cross reference of the heap.
     133    static Heap *createHeap(HeapCrossRef& crossref) {
     134      return new Heap(crossref);
     135    }
     136
     137    /// \brief The type of the map that stores whether a node is processed.
     138    ///
     139    /// The type of the map that stores whether a node is processed.
     140    /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
     141    /// By default it is a NullMap.
     142    typedef NullMap<typename Digraph::Node, bool> ProcessedMap;
     143
     144    /// \brief Instantiates a ProcessedMap.
     145    ///
     146    /// This function instantiates a \ref ProcessedMap.
     147    /// \param digraph is the digraph, to which
     148    /// we would like to define the \ref ProcessedMap
     149#ifdef DOXYGEN
     150    static ProcessedMap *createProcessedMap(const Digraph &digraph)
     151#else
     152    static ProcessedMap *createProcessedMap(const Digraph &)
     153#endif
     154    {
     155      return new ProcessedMap();
     156    }
     157
     158    /// \brief The type of the map that stores the cardinalities of the nodes.
     159    ///
     160    /// The type of the map that stores the cardinalities of the nodes.
     161    /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
     162    typedef typename Digraph::template NodeMap<Value> CardinalityMap;
     163
     164    /// \brief Instantiates a CardinalityMap.
     165    ///
     166    /// This function instantiates a \ref CardinalityMap.
     167    /// \param digraph is the digraph, to which we would like to define the \ref
     168    /// CardinalityMap
     169    static CardinalityMap *createCardinalityMap(const Digraph &digraph) {
     170      return new CardinalityMap(digraph);
     171    }
     172
     173
     174  };
     175 
     176  /// \ingroup search
     177  ///
     178  /// \brief Maximum Cardinality Search algorithm class.
     179  ///
     180  /// This class provides an efficient implementation of Maximum Cardinality
     181  /// Search algorithm. The maximum cardinality search first chooses any
     182  /// node of the digraph. Then every time it chooses one unprocessed node
     183  /// with maximum cardinality, i.e the sum of capacities on out arcs to the nodes
     184  /// which were previusly processed.
     185  /// If there is a cut in the digraph the algorithm should choose
     186  /// again any unprocessed node of the digraph.
     187
     188  /// The arc capacities are passed to the algorithm using a
     189  /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
     190  /// kind of capacity.
     191  ///
     192  /// The type of the capacity is determined by the \ref
     193  /// concepts::ReadMap::Value "Value" of the capacity map.
     194  ///
     195  /// It is also possible to change the underlying priority heap.
     196  ///
     197  ///
     198  /// \param GR The digraph type the algorithm runs on. The value of
     199  /// Digraph is not used directly by the search algorithm, it
     200  /// is only passed to \ref MaxCardinalitySearchDefaultTraits.
     201  /// \param CAP This read-only ArcMap determines the capacities of
     202  /// the arcs. It is read once for each arc, so the map may involve in
     203  /// relatively time consuming process to compute the arc capacity if
     204  /// it is necessary. The default map type is \ref
     205  /// ConstMap "ConstMap<concepts::Digraph::Arc, Const<int,1> >". The value
     206  /// of CapacityMap is not used directly by search algorithm, it is only
     207  /// passed to \ref MaxCardinalitySearchDefaultTraits. 
     208  /// \param TR Traits class to set various data types used by the
     209  /// algorithm.  The default traits class is
     210  /// \ref MaxCardinalitySearchDefaultTraits
     211  /// "MaxCardinalitySearchDefaultTraits<GR, CAP>". 
     212  /// See \ref MaxCardinalitySearchDefaultTraits
     213  /// for the documentation of a MaxCardinalitySearch traits class.
     214
     215#ifdef DOXYGEN
     216  template <typename GR, typename CAP, typename TR>
     217#else
     218  template <typename GR, typename CAP =
     219            ConstMap<typename GR::Arc, Const<int,1> >,
     220            typename TR =
     221            MaxCardinalitySearchDefaultTraits<GR, CAP> >
     222#endif
     223  class MaxCardinalitySearch {
     224  public:
     225
     226    typedef TR Traits;
     227    ///The type of the underlying digraph.
     228    typedef typename Traits::Digraph Digraph;
     229   
     230    ///The type of the capacity of the arcs.
     231    typedef typename Traits::CapacityMap::Value Value;
     232    ///The type of the map that stores the arc capacities.
     233    typedef typename Traits::CapacityMap CapacityMap;
     234    ///The type of the map indicating if a node is processed.
     235    typedef typename Traits::ProcessedMap ProcessedMap;
     236    ///The type of the map that stores the cardinalities of the nodes.
     237    typedef typename Traits::CardinalityMap CardinalityMap;
     238    ///The cross reference type used for the current heap.
     239    typedef typename Traits::HeapCrossRef HeapCrossRef;
     240    ///The heap type used by the algorithm. It maximizes the priorities.
     241    typedef typename Traits::Heap Heap;
     242  private:
     243    // Pointer to the underlying digraph.
     244    const Digraph *_graph;
     245    // Pointer to the capacity map
     246    const CapacityMap *_capacity;
     247    // Indicates if \ref _capacity is locally allocated (\c true) or not.
     248    bool local_capacity;
     249    // Pointer to the map of cardinality.
     250    CardinalityMap *_cardinality;
     251    // Indicates if \ref _cardinality is locally allocated (\c true) or not.
     252    bool local_cardinality;
     253    // Pointer to the map of processed status of the nodes.
     254    ProcessedMap *_processed;
     255    // Indicates if \ref _processed is locally allocated (\c true) or not.
     256    bool local_processed;
     257    // Pointer to the heap cross references.
     258    HeapCrossRef *_heap_cross_ref;
     259    // Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not.
     260    bool local_heap_cross_ref;
     261    // Pointer to the heap.
     262    Heap *_heap;
     263    // Indicates if \ref _heap is locally allocated (\c true) or not.
     264    bool local_heap;
     265
     266  public :
     267
     268    typedef MaxCardinalitySearch Create;
     269 
     270    ///\name Named template parameters
     271
     272    ///@{
     273
     274    template <class T>
     275    struct DefCapacityMapTraits : public Traits {
     276      typedef T CapacityMap;
     277      static CapacityMap *createCapacityMap(const Digraph &) {
     278        LEMON_ASSERT(false,"Uninitialized parameter.");
     279        return 0;
     280      }
     281    };
     282    /// \brief \ref named-templ-param "Named parameter" for setting
     283    /// CapacityMap type
     284    ///
     285    /// \ref named-templ-param "Named parameter" for setting CapacityMap type
     286    /// for the algorithm.
     287    template <class T>
     288    struct SetCapacityMap
     289      : public MaxCardinalitySearch<Digraph, CapacityMap,
     290                                    DefCapacityMapTraits<T> > {
     291      typedef MaxCardinalitySearch<Digraph, CapacityMap,
     292                                   DefCapacityMapTraits<T> > Create;
     293    };
     294
     295    template <class T>
     296    struct DefCardinalityMapTraits : public Traits {
     297      typedef T CardinalityMap;
     298      static CardinalityMap *createCardinalityMap(const Digraph &)
     299      {
     300        LEMON_ASSERT(false,"Uninitialized parameter.");
     301        return 0;
     302      }
     303    };
     304    /// \brief \ref named-templ-param "Named parameter" for setting
     305    /// CardinalityMap type
     306    ///
     307    /// \ref named-templ-param "Named parameter" for setting CardinalityMap
     308    /// type for the algorithm.
     309    template <class T>
     310    struct SetCardinalityMap
     311      : public MaxCardinalitySearch<Digraph, CapacityMap,
     312                                    DefCardinalityMapTraits<T> > {
     313      typedef MaxCardinalitySearch<Digraph, CapacityMap,
     314                                   DefCardinalityMapTraits<T> > Create;
     315    };
     316   
     317    template <class T>
     318    struct DefProcessedMapTraits : public Traits {
     319      typedef T ProcessedMap;
     320      static ProcessedMap *createProcessedMap(const Digraph &) {
     321        LEMON_ASSERT(false,"Uninitialized parameter.");
     322        return 0;
     323      }
     324    };
     325    /// \brief \ref named-templ-param "Named parameter" for setting
     326    /// ProcessedMap type
     327    ///
     328    /// \ref named-templ-param "Named parameter" for setting ProcessedMap type
     329    /// for the algorithm.
     330    template <class T>
     331    struct SetProcessedMap
     332      : public MaxCardinalitySearch<Digraph, CapacityMap,
     333                                    DefProcessedMapTraits<T> > {
     334      typedef MaxCardinalitySearch<Digraph, CapacityMap,
     335                                   DefProcessedMapTraits<T> > Create;
     336    };
     337   
     338    template <class H, class CR>
     339    struct DefHeapTraits : public Traits {
     340      typedef CR HeapCrossRef;
     341      typedef H Heap;
     342      static HeapCrossRef *createHeapCrossRef(const Digraph &) {
     343        LEMON_ASSERT(false,"Uninitialized parameter.");
     344        return 0;
     345      }
     346      static Heap *createHeap(HeapCrossRef &) {
     347        LEMON_ASSERT(false,"Uninitialized parameter.");
     348        return 0;
     349      }
     350    };
     351    /// \brief \ref named-templ-param "Named parameter" for setting heap
     352    /// and cross reference type
     353    ///
     354    /// \ref named-templ-param "Named parameter" for setting heap and cross
     355    /// reference type for the algorithm.
     356    template <class H, class CR = typename Digraph::template NodeMap<int> >
     357    struct SetHeap
     358      : public MaxCardinalitySearch<Digraph, CapacityMap,
     359                                    DefHeapTraits<H, CR> > {
     360      typedef MaxCardinalitySearch< Digraph, CapacityMap,
     361                                    DefHeapTraits<H, CR> > Create;
     362    };
     363
     364    template <class H, class CR>
     365    struct DefStandardHeapTraits : public Traits {
     366      typedef CR HeapCrossRef;
     367      typedef H Heap;
     368      static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) {
     369        return new HeapCrossRef(digraph);
     370      }
     371      static Heap *createHeap(HeapCrossRef &crossref) {
     372        return new Heap(crossref);
     373      }
     374    };
     375
     376    /// \brief \ref named-templ-param "Named parameter" for setting heap and
     377    /// cross reference type with automatic allocation
     378    ///
     379    /// \ref named-templ-param "Named parameter" for setting heap and cross
     380    /// reference type. It can allocate the heap and the cross reference
     381    /// object if the cross reference's constructor waits for the digraph as
     382    /// parameter and the heap's constructor waits for the cross reference.
     383    template <class H, class CR = typename Digraph::template NodeMap<int> >
     384    struct SetStandardHeap
     385      : public MaxCardinalitySearch<Digraph, CapacityMap,
     386                                    DefStandardHeapTraits<H, CR> > {
     387      typedef MaxCardinalitySearch<Digraph, CapacityMap,
     388                                   DefStandardHeapTraits<H, CR> >
     389      Create;
     390    };
     391   
     392    ///@}
     393
     394
     395  protected:
     396
     397    MaxCardinalitySearch() {}
     398
     399  public:     
     400   
     401    /// \brief Constructor.
     402    ///
     403    ///\param digraph the digraph the algorithm will run on.
     404    ///\param capacity the capacity map used by the algorithm.
     405    ///When no capacity map given, a constant 1 capacity map will
     406    ///be allocated.
     407#ifdef DOXYGEN
     408    MaxCardinalitySearch(const Digraph& digraph,
     409                         const CapacityMap& capacity=0 ) :
     410#else
     411    MaxCardinalitySearch(const Digraph& digraph,
     412                         const CapacityMap& capacity=*static_cast<const CapacityMap*>(0) ) :
     413#endif
     414      _graph(&digraph),
     415      _capacity(&capacity), local_capacity(false),
     416      _cardinality(0), local_cardinality(false),
     417      _processed(0), local_processed(false),
     418      _heap_cross_ref(0), local_heap_cross_ref(false),
     419      _heap(0), local_heap(false)
     420    { }
     421
     422    /// \brief Destructor.
     423    ~MaxCardinalitySearch() {
     424      if(local_capacity) delete _capacity;
     425      if(local_cardinality) delete _cardinality;
     426      if(local_processed) delete _processed;
     427      if(local_heap_cross_ref) delete _heap_cross_ref;
     428      if(local_heap) delete _heap;
     429    }
     430
     431    /// \brief Sets the capacity map.
     432    ///
     433    /// Sets the capacity map.
     434    /// \return <tt> (*this) </tt>
     435    MaxCardinalitySearch &capacityMap(const CapacityMap &m) {
     436      if (local_capacity) {
     437        delete _capacity;
     438        local_capacity=false;
     439      }
     440      _capacity=&m;
     441      return *this;
     442    }
     443
     444    /// \brief Returns a const reference to the capacity map.
     445    ///
     446    /// Returns a const reference to the capacity map used by
     447    /// the algorithm.
     448    const CapacityMap &capacityMap() const {
     449      return *_capacity;
     450    }
     451
     452    /// \brief Sets the map storing the cardinalities calculated by the
     453    /// algorithm.
     454    ///
     455    /// Sets the map storing the cardinalities calculated by the algorithm.
     456    /// If you don't use this function before calling \ref run(),
     457    /// it will allocate one. The destuctor deallocates this
     458    /// automatically allocated map, of course.
     459    /// \return <tt> (*this) </tt>
     460    MaxCardinalitySearch &cardinalityMap(CardinalityMap &m) {
     461      if(local_cardinality) {
     462        delete _cardinality;
     463        local_cardinality=false;
     464      }
     465      _cardinality = &m;
     466      return *this;
     467    }
     468
     469    /// \brief Sets the map storing the processed nodes.
     470    ///
     471    /// Sets the map storing the processed nodes.
     472    /// If you don't use this function before calling \ref run(),
     473    /// it will allocate one. The destuctor deallocates this
     474    /// automatically allocated map, of course.
     475    /// \return <tt> (*this) </tt>
     476    MaxCardinalitySearch &processedMap(ProcessedMap &m)
     477    {
     478      if(local_processed) {
     479        delete _processed;
     480        local_processed=false;
     481      }
     482      _processed = &m;
     483      return *this;
     484    }
     485
     486    /// \brief Returns a const reference to the cardinality map.
     487    ///
     488    /// Returns a const reference to the cardinality map used by
     489    /// the algorithm.
     490    const ProcessedMap &processedMap() const {
     491      return *_processed;
     492    }
     493
     494    /// \brief Sets the heap and the cross reference used by algorithm.
     495    ///
     496    /// Sets the heap and the cross reference used by algorithm.
     497    /// If you don't use this function before calling \ref run(),
     498    /// it will allocate one. The destuctor deallocates this
     499    /// automatically allocated map, of course.
     500    /// \return <tt> (*this) </tt>
     501    MaxCardinalitySearch &heap(Heap& hp, HeapCrossRef &cr) {
     502      if(local_heap_cross_ref) {
     503        delete _heap_cross_ref;
     504        local_heap_cross_ref = false;
     505      }
     506      _heap_cross_ref = &cr;
     507      if(local_heap) {
     508        delete _heap;
     509        local_heap = false;
     510      }
     511      _heap = &hp;
     512      return *this;
     513    }
     514
     515    /// \brief Returns a const reference to the heap.
     516    ///
     517    /// Returns a const reference to the heap used by
     518    /// the algorithm.
     519    const Heap &heap() const {
     520      return *_heap;
     521    }
     522
     523    /// \brief Returns a const reference to the cross reference.
     524    ///
     525    /// Returns a const reference to the cross reference
     526    /// of the heap.
     527    const HeapCrossRef &heapCrossRef() const {
     528      return *_heap_cross_ref;
     529    }
     530
     531  private:
     532
     533    typedef typename Digraph::Node Node;
     534    typedef typename Digraph::NodeIt NodeIt;
     535    typedef typename Digraph::Arc Arc;
     536    typedef typename Digraph::InArcIt InArcIt;
     537
     538    void create_maps() {
     539      if(!_capacity) {
     540        local_capacity = true;
     541        _capacity = Traits::createCapacityMap(*_graph);
     542      }
     543      if(!_cardinality) {
     544        local_cardinality = true;
     545        _cardinality = Traits::createCardinalityMap(*_graph);
     546      }
     547      if(!_processed) {
     548        local_processed = true;
     549        _processed = Traits::createProcessedMap(*_graph);
     550      }
     551      if (!_heap_cross_ref) {
     552        local_heap_cross_ref = true;
     553        _heap_cross_ref = Traits::createHeapCrossRef(*_graph);
     554      }
     555      if (!_heap) {
     556        local_heap = true;
     557        _heap = Traits::createHeap(*_heap_cross_ref);
     558      }
     559    }
     560   
     561    void finalizeNodeData(Node node, Value capacity) {
     562      _processed->set(node, true);
     563      _cardinality->set(node, capacity);
     564    }
     565
     566  public:
     567    /// \name Execution control
     568    /// The simplest way to execute the algorithm is to use
     569    /// one of the member functions called \ref run().
     570    /// \n
     571    /// If you need more control on the execution,
     572    /// first you must call \ref init(), then you can add several source nodes
     573    /// with \ref addSource().
     574    /// Finally \ref start() will perform the computation.
     575
     576    ///@{
     577
     578    /// \brief Initializes the internal data structures.
     579    ///
     580    /// Initializes the internal data structures, and clears the heap.
     581    void init() {
     582      create_maps();
     583      _heap->clear();
     584      for (NodeIt it(*_graph) ; it != INVALID ; ++it) {
     585        _processed->set(it, false);
     586        _heap_cross_ref->set(it, Heap::PRE_HEAP);
     587      }
     588    }
     589   
     590    /// \brief Adds a new source node.
     591    ///
     592    /// Adds a new source node to the priority heap.
     593    ///
     594    /// It checks if the node has not yet been added to the heap.
     595    void addSource(Node source, Value capacity = 0) {
     596      if(_heap->state(source) == Heap::PRE_HEAP) {
     597        _heap->push(source, capacity);
     598      }
     599    }
     600   
     601    /// \brief Processes the next node in the priority heap
     602    ///
     603    /// Processes the next node in the priority heap.
     604    ///
     605    /// \return The processed node.
     606    ///
     607    /// \warning The priority heap must not be empty!
     608    Node processNextNode() {
     609      Node node = _heap->top();
     610      finalizeNodeData(node, _heap->prio());
     611      _heap->pop();
     612     
     613      for (InArcIt it(*_graph, node); it != INVALID; ++it) {
     614        Node source = _graph->source(it);
     615        switch (_heap->state(source)) {
     616        case Heap::PRE_HEAP:
     617          _heap->push(source, (*_capacity)[it]);
     618          break;
     619        case Heap::IN_HEAP:
     620          _heap->decrease(source, (*_heap)[source] + (*_capacity)[it]);
     621          break;
     622        case Heap::POST_HEAP:
     623          break;
     624        }
     625      }
     626      return node;
     627    }
     628
     629    /// \brief Next node to be processed.
     630    ///
     631    /// Next node to be processed.
     632    ///
     633    /// \return The next node to be processed or INVALID if the
     634    /// priority heap is empty.
     635    Node nextNode() {
     636      return !_heap->empty() ? _heap->top() : INVALID;
     637    }
     638 
     639    /// \brief Returns \c false if there are nodes
     640    /// to be processed in the priority heap
     641    ///
     642    /// Returns \c false if there are nodes
     643    /// to be processed in the priority heap
     644    bool emptyQueue() { return _heap->empty(); }
     645    /// \brief Returns the number of the nodes to be processed
     646    /// in the priority heap
     647    ///
     648    /// Returns the number of the nodes to be processed in the priority heap
     649    int emptySize() { return _heap->size(); }
     650   
     651    /// \brief Executes the algorithm.
     652    ///
     653    /// Executes the algorithm.
     654    ///
     655    ///\pre init() must be called and at least one node should be added
     656    /// with addSource() before using this function.
     657    ///
     658    /// This method runs the Maximum Cardinality Search algorithm from the
     659    /// source node(s).
     660    void start() {
     661      while ( !_heap->empty() ) processNextNode();
     662    }
     663   
     664    /// \brief Executes the algorithm until \c dest is reached.
     665    ///
     666    /// Executes the algorithm until \c dest is reached.
     667    ///
     668    /// \pre init() must be called and at least one node should be added
     669    /// with addSource() before using this function.
     670    ///
     671    /// This method runs the %MaxCardinalitySearch algorithm from the source
     672    /// nodes.
     673    void start(Node dest) {
     674      while ( !_heap->empty() && _heap->top()!=dest ) processNextNode();
     675      if ( !_heap->empty() ) finalizeNodeData(_heap->top(), _heap->prio());
     676    }
     677   
     678    /// \brief Executes the algorithm until a condition is met.
     679    ///
     680    /// Executes the algorithm until a condition is met.
     681    ///
     682    /// \pre init() must be called and at least one node should be added
     683    /// with addSource() before using this function.
     684    ///
     685    /// \param nm must be a bool (or convertible) node map. The algorithm
     686    /// will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
     687    template <typename NodeBoolMap>
     688    void start(const NodeBoolMap &nm) {
     689      while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
     690      if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio());
     691    }
     692   
     693    /// \brief Runs the maximum cardinality search algorithm from node \c s.
     694    ///
     695    /// This method runs the %MaxCardinalitySearch algorithm from a root
     696    /// node \c s.
     697    ///
     698    ///\note d.run(s) is just a shortcut of the following code.
     699    ///\code
     700    ///  d.init();
     701    ///  d.addSource(s);
     702    ///  d.start();
     703    ///\endcode
     704    void run(Node s) {
     705      init();
     706      addSource(s);
     707      start();
     708    }
     709
     710    /// \brief Runs the maximum cardinality search algorithm for the
     711    /// whole digraph.
     712    ///
     713    /// This method runs the %MaxCardinalitySearch algorithm from all
     714    /// unprocessed node of the digraph.
     715    ///
     716    ///\note d.run(s) is just a shortcut of the following code.
     717    ///\code
     718    ///  d.init();
     719    ///  for (NodeIt it(digraph); it != INVALID; ++it) {
     720    ///    if (!d.reached(it)) {
     721    ///      d.addSource(s);
     722    ///      d.start();
     723    ///    }
     724    ///  }
     725    ///\endcode
     726    void run() {
     727      init();
     728      for (NodeIt it(*_graph); it != INVALID; ++it) {
     729        if (!reached(it)) {
     730          addSource(it);
     731          start();
     732        }
     733      }
     734    }
     735   
     736    ///@}
     737
     738    /// \name Query Functions
     739    /// The results of the maximum cardinality search algorithm can be
     740    /// obtained using these functions.
     741    /// \n
     742    /// Before the use of these functions, either run() or start() must be
     743    /// called.
     744   
     745    ///@{
     746
     747    /// \brief The cardinality of a node.
     748    ///
     749    /// Returns the cardinality of a node.
     750    /// \pre \ref run() must be called before using this function.
     751    /// \warning If node \c v in unreachable from the root the return value
     752    /// of this funcion is undefined.
     753    Value cardinality(Node node) const { return (*_cardinality)[node]; }
     754
     755    /// \brief The current cardinality of a node.
     756    ///
     757    /// Returns the current cardinality of a node.
     758    /// \pre the given node should be reached but not processed
     759    Value currentCardinality(Node node) const { return (*_heap)[node]; }
     760
     761    /// \brief Returns a reference to the NodeMap of cardinalities.
     762    ///
     763    /// Returns a reference to the NodeMap of cardinalities. \pre \ref run()
     764    /// must be called before using this function.
     765    const CardinalityMap &cardinalityMap() const { return *_cardinality;}
     766 
     767    /// \brief Checks if a node is reachable from the root.
     768    ///
     769    /// Returns \c true if \c v is reachable from the root.
     770    /// \warning The source nodes are initated as unreached.
     771    /// \pre \ref run() must be called before using this function.
     772    bool reached(Node v) { return (*_heap_cross_ref)[v] != Heap::PRE_HEAP; }
     773
     774    /// \brief Checks if a node is processed.
     775    ///
     776    /// Returns \c true if \c v is processed, i.e. the shortest
     777    /// path to \c v has already found.
     778    /// \pre \ref run() must be called before using this function.
     779    bool processed(Node v) { return (*_heap_cross_ref)[v] == Heap::POST_HEAP; }
     780   
     781    ///@}
     782  };
     783
     784}
     785
     786#endif
  • test/CMakeLists.txt

    diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
    a b  
    3131  kruskal_test
    3232  maps_test
    3333  matching_test
     34  max_cardinality_search_test
    3435  max_clique_test
    3536  min_cost_arborescence_test
    3637  min_cost_flow_test
  • test/Makefile.am

    diff --git a/test/Makefile.am b/test/Makefile.am
    a b  
    3333        test/kruskal_test \
    3434        test/maps_test \
    3535        test/matching_test \
     36        test/max_cardinality_search_test \
    3637        test/max_clique_test \
    3738        test/min_cost_arborescence_test \
    3839        test/min_cost_flow_test \
     
    8586test_maps_test_SOURCES = test/maps_test.cc
    8687test_mip_test_SOURCES = test/mip_test.cc
    8788test_matching_test_SOURCES = test/matching_test.cc
     89test_max_cardinality_search_test_SOURCES = test/max_cardinality_search_test.cc
    8890test_max_clique_test_SOURCES = test/max_clique_test.cc
    8991test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
    9092test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
  • new file test/max_cardinality_search_test.cc

    diff --git a/test/max_cardinality_search_test.cc b/test/max_cardinality_search_test.cc
    new file mode 100644
    - +  
     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-2010
     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#include <iostream>
     20
     21#include "test_tools.h"
     22#include <lemon/smart_graph.h>
     23#include <lemon/max_cardinality_search.h>
     24#include <lemon/concepts/digraph.h>
     25#include <lemon/concepts/maps.h>
     26#include <lemon/concepts/heap.h>
     27#include <lemon/lgf_reader.h>
     28
     29using namespace lemon;
     30using namespace std;
     31
     32char test_lgf[] =
     33  "@nodes\n"
     34  "label\n"
     35  "0\n"
     36  "1\n"
     37  "2\n"
     38  "3\n"
     39  "@arcs\n"
     40  "    label capacity\n"
     41  "0 1 0     2\n"
     42  "1 0 1     2\n"
     43  "2 1 2     1\n"
     44  "2 3 3     3\n"
     45  "3 2 4     3\n"
     46  "3 1 5     5\n"
     47  "@attributes\n"
     48  "s 0\n"
     49  "x 1\n"
     50  "y 2\n"
     51  "z 3\n";
     52
     53void checkMaxCardSearchCompile() {
     54
     55  typedef concepts::Digraph Digraph;
     56  typedef int Value;
     57  typedef Digraph::Node Node;
     58  typedef Digraph::Arc Arc;
     59  typedef concepts::ReadMap<Arc,Value> CapMap;
     60  typedef concepts::ReadWriteMap<Node,Value> CardMap;
     61  typedef concepts::ReadWriteMap<Node,bool> ProcMap;
     62  typedef Digraph::NodeMap<int> HeapCrossRef;
     63
     64  Digraph g;
     65  Node n,s;
     66  CapMap cap;
     67  CardMap card;
     68  ProcMap proc;
     69  HeapCrossRef crossref(g);
     70 
     71  typedef MaxCardinalitySearch<Digraph,CapMap>
     72    ::SetCapacityMap<CapMap>
     73    ::SetCardinalityMap<CardMap>
     74    ::SetProcessedMap<ProcMap>
     75    ::SetStandardHeap<BinHeap<Value,HeapCrossRef> >
     76    ::Create MaxCardType;
     77
     78  MaxCardType maxcard(g,cap);
     79  const MaxCardType& const_maxcard = maxcard;
     80
     81  const MaxCardType::Heap& heap_const = const_maxcard.heap();
     82  MaxCardType::Heap& heap = const_cast<MaxCardType::Heap&>(heap_const);
     83  maxcard.heap(heap,crossref);
     84 
     85  maxcard.capacityMap(cap).cardinalityMap(card).processedMap(proc);
     86
     87  maxcard.init();
     88  maxcard.addSource(s);
     89  n = maxcard.nextNode();
     90   maxcard.processNextNode();
     91   maxcard.start();
     92   maxcard.run(s);
     93   maxcard.run();
     94 }
     95
     96 void checkWithIntMap( std::istringstream& input)
     97 {
     98   typedef SmartDigraph Digraph;
     99   typedef Digraph::Node Node;
     100   typedef Digraph::ArcMap<int> CapMap;
     101
     102   Digraph g;
     103   Node s,x,y,z,a;
     104   CapMap cap(g);
     105
     106   DigraphReader<Digraph>(g,input).
     107     arcMap("capacity", cap).
     108     node("s",s).
     109     node("x",x).
     110     node("y",y).
     111     node("z",z).
     112     run();
     113
     114   MaxCardinalitySearch<Digraph,CapMap> maxcard(g,cap);
     115
     116   maxcard.init();
     117   maxcard.addSource(s);
     118   maxcard.start(x);
     119
     120   check(maxcard.processed(s) and !maxcard.processed(x) and
     121         !maxcard.processed(y), "Wrong processed()!");
     122
     123   a=maxcard.nextNode();
     124   check(maxcard.processNextNode()==a,
     125         "Wrong nextNode() or processNextNode() return value!");
     126
     127   check(maxcard.processed(a), "Wrong processNextNode()!");
     128
     129   maxcard.start();
     130   check(maxcard.cardinality(x)==2 and maxcard.cardinality(y)>=4,
     131         "Wrong cardinalities!");
     132 }
     133
     134 void checkWithConst1Map(std::istringstream &input) {
     135   typedef SmartDigraph Digraph;
     136   typedef Digraph::Node Node;
     137
     138   Digraph g;
     139   Node s,x,y,z;
     140
     141  DigraphReader<Digraph>(g,input).
     142    node("s",s).
     143    node("x",x).
     144    node("y",y).
     145    node("z",z).
     146    run();
     147
     148  MaxCardinalitySearch<Digraph> maxcard(g);
     149  maxcard.run(s);
     150  check(maxcard.cardinality(x)==1 &&
     151        maxcard.cardinality(y)+maxcard.cardinality(z)==3,
     152        "Wrong cardinalities!");
     153}
     154
     155int main() {
     156
     157  std::istringstream input1(test_lgf);
     158  checkWithIntMap(input1);
     159
     160  std::istringstream input2(test_lgf);
     161  checkWithConst1Map(input2);
     162}