deba@2284: /* -*- C++ -*- deba@2284: * lemon/min_cut.h - Part of LEMON, a generic C++ optimization library deba@2284: * deba@2284: * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@2284: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@2284: * deba@2284: * Permission to use, modify and distribute this software is granted deba@2284: * provided that this copyright notice appears in all copies. For deba@2284: * precise terms see the accompanying LICENSE file. deba@2284: * deba@2284: * This software is provided "AS IS" with no warranty of any kind, deba@2284: * express or implied, and with no claim as to its suitability for any deba@2284: * purpose. deba@2284: * deba@2284: */ deba@2284: deba@2337: #ifndef LEMON_NAGAMOCHI_IBARAKI_H deba@2337: #define LEMON_NAGAMOCHI_IBARAKI_H deba@2284: deba@2284: deba@2376: /// \ingroup min_cut deba@2337: /// \file deba@2337: /// \brief Maximum cardinality search and minimum cut in undirected deba@2337: /// graphs. deba@2284: deba@2284: #include deba@2284: #include deba@2284: #include deba@2284: deba@2337: #include deba@2337: #include deba@2337: deba@2284: #include deba@2284: #include deba@2284: #include deba@2284: deba@2284: #include deba@2284: deba@2337: #include deba@2337: #include deba@2337: deba@2284: namespace lemon { deba@2284: deba@2284: namespace _min_cut_bits { deba@2284: deba@2284: template deba@2284: struct HeapSelector { deba@2284: template deba@2284: struct Selector { deba@2284: typedef BinHeap > Heap; deba@2284: }; deba@2284: }; deba@2284: deba@2284: template deba@2284: struct HeapSelector > > { deba@2284: template deba@2284: struct Selector { deba@2284: typedef BucketHeap Heap; deba@2284: }; deba@2284: }; deba@2284: deba@2284: } deba@2284: deba@2284: /// \brief Default traits class of MaxCardinalitySearch class. deba@2284: /// deba@2284: /// Default traits class of MaxCardinalitySearch class. deba@2284: /// \param Graph Graph type. deba@2284: /// \param CapacityMap Type of length map. deba@2284: template deba@2284: struct MaxCardinalitySearchDefaultTraits { deba@2284: /// The graph type the algorithm runs on. deba@2284: typedef _Graph Graph; deba@2284: deba@2284: /// \brief The type of the map that stores the edge capacities. deba@2284: /// deba@2284: /// The type of the map that stores the edge capacities. deba@2284: /// It must meet the \ref concepts::ReadMap "ReadMap" concept. deba@2284: typedef _CapacityMap CapacityMap; deba@2284: deba@2284: /// \brief The type of the capacity of the edges. deba@2284: typedef typename CapacityMap::Value Value; deba@2284: deba@2284: /// \brief The cross reference type used by heap. deba@2284: /// deba@2284: /// The cross reference type used by heap. deba@2284: /// Usually it is \c Graph::NodeMap. deba@2284: typedef typename Graph::template NodeMap HeapCrossRef; deba@2284: deba@2284: /// \brief Instantiates a HeapCrossRef. deba@2284: /// deba@2284: /// This function instantiates a \ref HeapCrossRef. deba@2284: /// \param graph is the graph, to which we would like to define the deba@2284: /// HeapCrossRef. deba@2284: static HeapCrossRef *createHeapCrossRef(const Graph &graph) { deba@2284: return new HeapCrossRef(graph); deba@2284: } deba@2284: deba@2284: /// \brief The heap type used by MaxCardinalitySearch algorithm. deba@2284: /// deba@2284: /// The heap type used by MaxCardinalitySearch algorithm. It should deba@2284: /// maximalize the priorities. The default heap type is deba@2284: /// the \ref BinHeap, but it is specialized when the deba@2284: /// CapacityMap is ConstMap > deba@2284: /// to BucketHeap. deba@2284: /// deba@2284: /// \sa MaxCardinalitySearch deba@2284: typedef typename _min_cut_bits deba@2284: ::HeapSelector deba@2284: ::template Selector deba@2284: ::Heap Heap; deba@2284: deba@2284: /// \brief Instantiates a Heap. deba@2284: /// deba@2284: /// This function instantiates a \ref Heap. deba@2284: /// \param crossref The cross reference of the heap. deba@2284: static Heap *createHeap(HeapCrossRef& crossref) { deba@2284: return new Heap(crossref); deba@2284: } deba@2284: deba@2284: /// \brief The type of the map that stores whether a nodes is processed. deba@2284: /// deba@2284: /// The type of the map that stores whether a nodes is processed. deba@2284: /// It must meet the \ref concepts::WriteMap "WriteMap" concept. deba@2284: /// By default it is a NullMap. deba@2284: typedef NullMap ProcessedMap; deba@2284: deba@2284: /// \brief Instantiates a ProcessedMap. deba@2284: /// deba@2284: /// This function instantiates a \ref ProcessedMap. deba@2284: /// \param graph is the graph, to which deba@2284: /// we would like to define the \ref ProcessedMap deba@2284: #ifdef DOXYGEN deba@2284: static ProcessedMap *createProcessedMap(const Graph &graph) deba@2284: #else deba@2284: static ProcessedMap *createProcessedMap(const Graph &) deba@2284: #endif deba@2284: { deba@2284: return new ProcessedMap(); deba@2284: } deba@2284: deba@2284: /// \brief The type of the map that stores the cardinalties of the nodes. deba@2284: /// deba@2284: /// The type of the map that stores the cardinalities of the nodes. deba@2284: /// It must meet the \ref concepts::WriteMap "WriteMap" concept. deba@2284: typedef typename Graph::template NodeMap CardinalityMap; deba@2284: deba@2284: /// \brief Instantiates a CardinalityMap. deba@2284: /// deba@2284: /// This function instantiates a \ref CardinalityMap. deba@2284: /// \param graph is the graph, to which we would like to define the \ref deba@2284: /// CardinalityMap deba@2284: static CardinalityMap *createCardinalityMap(const Graph &graph) { deba@2284: return new CardinalityMap(graph); deba@2284: } deba@2284: deba@2337: deba@2284: }; deba@2284: deba@2376: /// \ingroup search deba@2284: /// deba@2284: /// \brief Maximum Cardinality Search algorithm class. deba@2284: /// deba@2284: /// This class provides an efficient implementation of Maximum Cardinality deba@2284: /// Search algorithm. The maximum cardinality search chooses first time any deba@2284: /// node of the graph. Then every time it chooses the node which is connected deba@2284: /// to the processed nodes at most in the sum of capacities on the out deba@2284: /// edges. If there is a cut in the graph the algorithm should choose deba@2284: /// again any unprocessed node of the graph. Each node cardinality is deba@2284: /// the sum of capacities on the out edges to the nodes which are processed deba@2284: /// before the given node. deba@2284: /// deba@2284: /// The edge capacities are passed to the algorithm using a deba@2284: /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any deba@2284: /// kind of capacity. deba@2284: /// deba@2284: /// The type of the capacity is determined by the \ref deba@2284: /// concepts::ReadMap::Value "Value" of the capacity map. deba@2284: /// deba@2284: /// It is also possible to change the underlying priority heap. deba@2284: /// deba@2284: /// deba@2284: /// \param _Graph The graph type the algorithm runs on. The default value deba@2284: /// is \ref ListGraph. The value of Graph is not used directly by deba@2284: /// the search algorithm, it is only passed to deba@2284: /// \ref MaxCardinalitySearchDefaultTraits. deba@2284: /// \param _CapacityMap This read-only EdgeMap determines the capacities of deba@2284: /// the edges. It is read once for each edge, so the map may involve in deba@2284: /// relatively time consuming process to compute the edge capacity if deba@2284: /// it is necessary. The default map type is \ref deba@2284: /// concepts::Graph::EdgeMap "Graph::EdgeMap". The value deba@2284: /// of CapacityMap is not used directly by search algorithm, it is only deba@2284: /// passed to \ref MaxCardinalitySearchDefaultTraits. deba@2284: /// \param _Traits Traits class to set various data types used by the deba@2284: /// algorithm. The default traits class is deba@2284: /// \ref MaxCardinalitySearchDefaultTraits deba@2284: /// "MaxCardinalitySearchDefaultTraits<_Graph, _CapacityMap>". deba@2284: /// See \ref MaxCardinalitySearchDefaultTraits deba@2284: /// for the documentation of a MaxCardinalitySearch traits class. deba@2284: /// deba@2284: /// \author Balazs Dezso deba@2284: deba@2284: #ifdef DOXYGEN deba@2284: template deba@2284: #else deba@2284: template , deba@2284: typename _Traits = deba@2284: MaxCardinalitySearchDefaultTraits<_Graph, _CapacityMap> > deba@2284: #endif deba@2284: class MaxCardinalitySearch { deba@2284: public: deba@2284: /// \brief \ref Exception for uninitialized parameters. deba@2284: /// deba@2284: /// This error represents problems in the initialization deba@2284: /// of the parameters of the algorithms. deba@2284: class UninitializedParameter : public lemon::UninitializedParameter { deba@2284: public: deba@2284: virtual const char* what() const throw() { deba@2284: return "lemon::MaxCardinalitySearch::UninitializedParameter"; deba@2284: } deba@2284: }; deba@2284: deba@2284: typedef _Traits Traits; deba@2284: ///The type of the underlying graph. deba@2284: typedef typename Traits::Graph Graph; deba@2284: deba@2284: ///The type of the capacity of the edges. deba@2284: typedef typename Traits::CapacityMap::Value Value; deba@2284: ///The type of the map that stores the edge capacities. deba@2284: typedef typename Traits::CapacityMap CapacityMap; deba@2284: ///The type of the map indicating if a node is processed. deba@2284: typedef typename Traits::ProcessedMap ProcessedMap; deba@2284: ///The type of the map that stores the cardinalities of the nodes. deba@2284: typedef typename Traits::CardinalityMap CardinalityMap; deba@2284: ///The cross reference type used for the current heap. deba@2284: typedef typename Traits::HeapCrossRef HeapCrossRef; deba@2284: ///The heap type used by the algorithm. It maximize the priorities. deba@2284: typedef typename Traits::Heap Heap; deba@2284: private: deba@2284: /// Pointer to the underlying graph. deba@2284: const Graph *_graph; deba@2284: /// Pointer to the capacity map deba@2284: const CapacityMap *_capacity; deba@2284: ///Pointer to the map of cardinality. deba@2284: CardinalityMap *_cardinality; deba@2284: ///Indicates if \ref _cardinality is locally allocated (\c true) or not. deba@2284: bool local_cardinality; deba@2284: ///Pointer to the map of processed status of the nodes. deba@2284: ProcessedMap *_processed; deba@2284: ///Indicates if \ref _processed is locally allocated (\c true) or not. deba@2284: bool local_processed; deba@2284: ///Pointer to the heap cross references. deba@2284: HeapCrossRef *_heap_cross_ref; deba@2284: ///Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not. deba@2284: bool local_heap_cross_ref; deba@2284: ///Pointer to the heap. deba@2284: Heap *_heap; deba@2284: ///Indicates if \ref _heap is locally allocated (\c true) or not. deba@2284: bool local_heap; deba@2284: deba@2284: public : deba@2284: deba@2284: typedef MaxCardinalitySearch Create; deba@2284: deba@2284: ///\name Named template parameters deba@2284: deba@2284: ///@{ deba@2284: deba@2284: template deba@2284: struct DefCardinalityMapTraits : public Traits { deba@2284: typedef T CardinalityMap; deba@2284: static CardinalityMap *createCardinalityMap(const Graph &) deba@2284: { deba@2284: throw UninitializedParameter(); deba@2284: } deba@2284: }; deba@2284: /// \brief \ref named-templ-param "Named parameter" for setting deba@2284: /// CardinalityMap type deba@2284: /// deba@2284: /// \ref named-templ-param "Named parameter" for setting CardinalityMap deba@2284: /// type deba@2284: template deba@2284: struct DefCardinalityMap deba@2284: : public MaxCardinalitySearch > { deba@2284: typedef MaxCardinalitySearch > Create; deba@2284: }; deba@2284: deba@2284: template deba@2284: struct DefProcessedMapTraits : public Traits { deba@2284: typedef T ProcessedMap; deba@2284: static ProcessedMap *createProcessedMap(const Graph &) { deba@2284: throw UninitializedParameter(); deba@2284: } deba@2284: }; deba@2284: /// \brief \ref named-templ-param "Named parameter" for setting deba@2284: /// ProcessedMap type deba@2284: /// deba@2284: /// \ref named-templ-param "Named parameter" for setting ProcessedMap type deba@2284: /// deba@2284: template deba@2284: struct DefProcessedMap deba@2284: : public MaxCardinalitySearch > { deba@2284: typedef MaxCardinalitySearch > Create; deba@2284: }; deba@2284: deba@2284: template deba@2284: struct DefHeapTraits : public Traits { deba@2284: typedef CR HeapCrossRef; deba@2284: typedef H Heap; deba@2284: static HeapCrossRef *createHeapCrossRef(const Graph &) { deba@2284: throw UninitializedParameter(); deba@2284: } deba@2284: static Heap *createHeap(HeapCrossRef &) { deba@2284: throw UninitializedParameter(); deba@2284: } deba@2284: }; deba@2284: /// \brief \ref named-templ-param "Named parameter" for setting heap deba@2284: /// and cross reference type deba@2284: /// deba@2284: /// \ref named-templ-param "Named parameter" for setting heap and cross deba@2284: /// reference type deba@2284: template > deba@2284: struct DefHeap deba@2284: : public MaxCardinalitySearch > { deba@2284: typedef MaxCardinalitySearch< Graph, CapacityMap, deba@2284: DefHeapTraits > Create; deba@2284: }; deba@2284: deba@2284: template deba@2284: struct DefStandardHeapTraits : public Traits { deba@2284: typedef CR HeapCrossRef; deba@2284: typedef H Heap; deba@2284: static HeapCrossRef *createHeapCrossRef(const Graph &graph) { deba@2284: return new HeapCrossRef(graph); deba@2284: } deba@2284: static Heap *createHeap(HeapCrossRef &crossref) { deba@2284: return new Heap(crossref); deba@2284: } deba@2284: }; deba@2284: deba@2284: /// \brief \ref named-templ-param "Named parameter" for setting heap and deba@2284: /// cross reference type with automatic allocation deba@2284: /// deba@2284: /// \ref named-templ-param "Named parameter" for setting heap and cross deba@2284: /// reference type. It can allocate the heap and the cross reference deba@2284: /// object if the cross reference's constructor waits for the graph as deba@2284: /// parameter and the heap's constructor waits for the cross reference. deba@2284: template > deba@2284: struct DefStandardHeap deba@2284: : public MaxCardinalitySearch > { deba@2284: typedef MaxCardinalitySearch > deba@2284: Create; deba@2284: }; deba@2284: deba@2284: ///@} deba@2284: deba@2284: deba@2284: protected: deba@2284: deba@2284: MaxCardinalitySearch() {} deba@2284: deba@2284: public: deba@2284: deba@2284: /// \brief Constructor. deba@2284: /// deba@2284: ///\param graph the graph the algorithm will run on. deba@2284: ///\param capacity the capacity map used by the algorithm. deba@2284: MaxCardinalitySearch(const Graph& graph, const CapacityMap& capacity) : deba@2284: _graph(&graph), _capacity(&capacity), deba@2284: _cardinality(0), local_cardinality(false), deba@2284: _processed(0), local_processed(false), deba@2284: _heap_cross_ref(0), local_heap_cross_ref(false), deba@2284: _heap(0), local_heap(false) deba@2284: { } deba@2284: deba@2284: /// \brief Destructor. deba@2284: ~MaxCardinalitySearch() { deba@2284: if(local_cardinality) delete _cardinality; deba@2284: if(local_processed) delete _processed; deba@2284: if(local_heap_cross_ref) delete _heap_cross_ref; deba@2284: if(local_heap) delete _heap; deba@2284: } deba@2284: deba@2284: /// \brief Sets the capacity map. deba@2284: /// deba@2284: /// Sets the capacity map. deba@2284: /// \return (*this) deba@2284: MaxCardinalitySearch &capacityMap(const CapacityMap &m) { deba@2284: _capacity = &m; deba@2284: return *this; deba@2284: } deba@2284: deba@2284: /// \brief Sets the map storing the cardinalities calculated by the deba@2284: /// algorithm. deba@2284: /// deba@2284: /// Sets the map storing the cardinalities calculated by the algorithm. deba@2284: /// If you don't use this function before calling \ref run(), deba@2284: /// it will allocate one. The destuctor deallocates this deba@2284: /// automatically allocated map, of course. deba@2284: /// \return (*this) deba@2284: MaxCardinalitySearch &cardinalityMap(CardinalityMap &m) { deba@2284: if(local_cardinality) { deba@2284: delete _cardinality; deba@2284: local_cardinality=false; deba@2284: } deba@2284: _cardinality = &m; deba@2284: return *this; deba@2284: } deba@2284: deba@2284: /// \brief Sets the map storing the processed nodes. deba@2284: /// deba@2284: /// Sets the map storing the processed nodes. deba@2284: /// If you don't use this function before calling \ref run(), deba@2284: /// it will allocate one. The destuctor deallocates this deba@2284: /// automatically allocated map, of course. deba@2284: /// \return (*this) deba@2284: MaxCardinalitySearch &processedMap(ProcessedMap &m) deba@2284: { deba@2284: if(local_processed) { deba@2284: delete _processed; deba@2284: local_processed=false; deba@2284: } deba@2284: _processed = &m; deba@2284: return *this; deba@2284: } deba@2284: deba@2284: /// \brief Sets the heap and the cross reference used by algorithm. deba@2284: /// deba@2284: /// Sets the heap and the cross reference used by algorithm. deba@2284: /// If you don't use this function before calling \ref run(), deba@2284: /// it will allocate one. The destuctor deallocates this deba@2284: /// automatically allocated map, of course. deba@2284: /// \return (*this) deba@2386: MaxCardinalitySearch &heap(Heap& hp, HeapCrossRef &cr) { deba@2284: if(local_heap_cross_ref) { deba@2284: delete _heap_cross_ref; deba@2284: local_heap_cross_ref = false; deba@2284: } deba@2386: _heap_cross_ref = &cr; deba@2284: if(local_heap) { deba@2284: delete _heap; deba@2284: local_heap = false; deba@2284: } deba@2386: _heap = &hp; deba@2284: return *this; deba@2284: } deba@2284: deba@2284: private: deba@2284: deba@2284: typedef typename Graph::Node Node; deba@2284: typedef typename Graph::NodeIt NodeIt; deba@2284: typedef typename Graph::Edge Edge; deba@2284: typedef typename Graph::InEdgeIt InEdgeIt; deba@2284: deba@2284: void create_maps() { deba@2284: if(!_cardinality) { deba@2284: local_cardinality = true; deba@2284: _cardinality = Traits::createCardinalityMap(*_graph); deba@2284: } deba@2284: if(!_processed) { deba@2284: local_processed = true; deba@2284: _processed = Traits::createProcessedMap(*_graph); deba@2284: } deba@2284: if (!_heap_cross_ref) { deba@2284: local_heap_cross_ref = true; deba@2284: _heap_cross_ref = Traits::createHeapCrossRef(*_graph); deba@2284: } deba@2284: if (!_heap) { deba@2284: local_heap = true; deba@2284: _heap = Traits::createHeap(*_heap_cross_ref); deba@2284: } deba@2284: } deba@2284: deba@2284: void finalizeNodeData(Node node, Value capacity) { deba@2284: _processed->set(node, true); deba@2284: _cardinality->set(node, capacity); deba@2284: } deba@2284: deba@2284: public: deba@2284: /// \name Execution control deba@2284: /// The simplest way to execute the algorithm is to use deba@2284: /// one of the member functions called \c run(...). deba@2284: /// \n deba@2284: /// If you need more control on the execution, deba@2284: /// first you must call \ref init(), then you can add several source nodes deba@2284: /// with \ref addSource(). deba@2284: /// Finally \ref start() will perform the actual path deba@2284: /// computation. deba@2284: deba@2284: ///@{ deba@2284: deba@2284: /// \brief Initializes the internal data structures. deba@2284: /// deba@2284: /// Initializes the internal data structures. deba@2284: void init() { deba@2284: create_maps(); deba@2284: _heap->clear(); deba@2284: for (NodeIt it(*_graph) ; it != INVALID ; ++it) { deba@2284: _processed->set(it, false); deba@2284: _heap_cross_ref->set(it, Heap::PRE_HEAP); deba@2284: } deba@2284: } deba@2284: deba@2284: /// \brief Adds a new source node. deba@2284: /// deba@2284: /// Adds a new source node to the priority heap. deba@2284: /// deba@2284: /// It checks if the node has not yet been added to the heap. deba@2284: void addSource(Node source, Value capacity = 0) { deba@2284: if(_heap->state(source) == Heap::PRE_HEAP) { deba@2284: _heap->push(source, capacity); deba@2284: } deba@2284: } deba@2284: deba@2284: /// \brief Processes the next node in the priority heap deba@2284: /// deba@2284: /// Processes the next node in the priority heap. deba@2284: /// deba@2284: /// \return The processed node. deba@2284: /// deba@2284: /// \warning The priority heap must not be empty! deba@2284: Node processNextNode() { deba@2284: Node node = _heap->top(); deba@2284: finalizeNodeData(node, _heap->prio()); deba@2284: _heap->pop(); deba@2284: deba@2284: for (InEdgeIt it(*_graph, node); it != INVALID; ++it) { deba@2284: Node source = _graph->source(it); deba@2284: switch (_heap->state(source)) { deba@2284: case Heap::PRE_HEAP: deba@2284: _heap->push(source, (*_capacity)[it]); deba@2284: break; deba@2284: case Heap::IN_HEAP: deba@2284: _heap->decrease(source, (*_heap)[source] + (*_capacity)[it]); deba@2284: break; deba@2284: case Heap::POST_HEAP: deba@2284: break; deba@2284: } deba@2284: } deba@2284: return node; deba@2284: } deba@2284: deba@2284: /// \brief Next node to be processed. deba@2284: /// deba@2284: /// Next node to be processed. deba@2284: /// deba@2284: /// \return The next node to be processed or INVALID if the deba@2284: /// priority heap is empty. deba@2284: Node nextNode() { deba@2284: return _heap->empty() ? _heap->top() : INVALID; deba@2284: } deba@2284: deba@2284: /// \brief Returns \c false if there are nodes deba@2284: /// to be processed in the priority heap deba@2284: /// deba@2284: /// Returns \c false if there are nodes deba@2284: /// to be processed in the priority heap deba@2284: bool emptyQueue() { return _heap->empty(); } deba@2284: /// \brief Returns the number of the nodes to be processed deba@2284: /// in the priority heap deba@2284: /// deba@2284: /// Returns the number of the nodes to be processed in the priority heap deba@2284: int queueSize() { return _heap->size(); } deba@2284: deba@2284: /// \brief Executes the algorithm. deba@2284: /// deba@2284: /// Executes the algorithm. deba@2284: /// deba@2284: ///\pre init() must be called and at least one node should be added deba@2284: /// with addSource() before using this function. deba@2284: /// deba@2284: /// This method runs the Maximum Cardinality Search algorithm from the deba@2284: /// source node(s). deba@2284: void start() { deba@2284: while ( !_heap->empty() ) processNextNode(); deba@2284: } deba@2284: deba@2284: /// \brief Executes the algorithm until \c dest is reached. deba@2284: /// deba@2284: /// Executes the algorithm until \c dest is reached. deba@2284: /// deba@2284: /// \pre init() must be called and at least one node should be added deba@2284: /// with addSource() before using this function. deba@2284: /// deba@2284: /// This method runs the %MaxCardinalitySearch algorithm from the source deba@2284: /// nodes. deba@2284: void start(Node dest) { deba@2284: while ( !_heap->empty() && _heap->top()!=dest ) processNextNode(); deba@2284: if ( !_heap->empty() ) finalizeNodeData(_heap->top(), _heap->prio()); deba@2284: } deba@2284: deba@2284: /// \brief Executes the algorithm until a condition is met. deba@2284: /// deba@2284: /// Executes the algorithm until a condition is met. deba@2284: /// deba@2284: /// \pre init() must be called and at least one node should be added deba@2284: /// with addSource() before using this function. deba@2284: /// deba@2284: /// \param nm must be a bool (or convertible) node map. The algorithm deba@2284: /// will stop when it reaches a node \c v with nm[v]==true. deba@2284: template deba@2284: void start(const NodeBoolMap &nm) { deba@2284: while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode(); deba@2284: if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio()); deba@2284: } deba@2284: deba@2284: /// \brief Runs the maximal cardinality search algorithm from node \c s. deba@2284: /// deba@2284: /// This method runs the %MaxCardinalitySearch algorithm from a root deba@2284: /// node \c s. deba@2284: /// deba@2284: ///\note d.run(s) is just a shortcut of the following code. deba@2284: ///\code deba@2284: /// d.init(); deba@2284: /// d.addSource(s); deba@2284: /// d.start(); deba@2284: ///\endcode deba@2284: void run(Node s) { deba@2284: init(); deba@2284: addSource(s); deba@2284: start(); deba@2284: } deba@2284: deba@2284: /// \brief Runs the maximal cardinality search algorithm for the deba@2284: /// whole graph. deba@2284: /// deba@2284: /// This method runs the %MaxCardinalitySearch algorithm from all deba@2284: /// unprocessed node of the graph. deba@2284: /// deba@2284: ///\note d.run(s) is just a shortcut of the following code. deba@2284: ///\code deba@2284: /// d.init(); deba@2284: /// for (NodeIt it(graph); it != INVALID; ++it) { deba@2284: /// if (!d.reached(it)) { deba@2284: /// d.addSource(s); deba@2284: /// d.start(); deba@2284: /// } deba@2284: /// } deba@2284: ///\endcode deba@2284: void run() { deba@2284: init(); deba@2284: for (NodeIt it(*_graph); it != INVALID; ++it) { deba@2284: if (!reached(it)) { deba@2284: addSource(it); deba@2284: start(); deba@2284: } deba@2284: } deba@2284: } deba@2284: deba@2284: ///@} deba@2284: deba@2284: /// \name Query Functions deba@2284: /// The result of the maximum cardinality search algorithm can be deba@2284: /// obtained using these functions. deba@2284: /// \n deba@2284: /// Before the use of these functions, either run() or start() must be deba@2284: /// called. deba@2284: deba@2284: ///@{ deba@2284: deba@2284: /// \brief The cardinality of a node. deba@2284: /// deba@2284: /// Returns the cardinality of a node. deba@2284: /// \pre \ref run() must be called before using this function. deba@2284: /// \warning If node \c v in unreachable from the root the return value deba@2284: /// of this funcion is undefined. deba@2284: Value cardinality(Node node) const { return (*_cardinality)[node]; } deba@2284: deba@2337: /// \brief The current cardinality of a node. deba@2337: /// deba@2337: /// Returns the current cardinality of a node. deba@2337: /// \pre the given node should be reached but not processed deba@2337: Value currentCardinality(Node node) const { return (*_heap)[node]; } deba@2337: deba@2284: /// \brief Returns a reference to the NodeMap of cardinalities. deba@2284: /// deba@2284: /// Returns a reference to the NodeMap of cardinalities. \pre \ref run() deba@2284: /// must be called before using this function. deba@2284: const CardinalityMap &cardinalityMap() const { return *_cardinality;} deba@2284: deba@2284: /// \brief Checks if a node is reachable from the root. deba@2284: /// deba@2284: /// Returns \c true if \c v is reachable from the root. deba@2284: /// \warning The source nodes are inditated as unreached. deba@2284: /// \pre \ref run() must be called before using this function. deba@2284: bool reached(Node v) { return (*_heap_cross_ref)[v] != Heap::PRE_HEAP; } deba@2284: deba@2284: /// \brief Checks if a node is processed. deba@2284: /// deba@2284: /// Returns \c true if \c v is processed, i.e. the shortest deba@2284: /// path to \c v has already found. deba@2284: /// \pre \ref run() must be called before using this function. deba@2284: bool processed(Node v) { return (*_heap_cross_ref)[v] == Heap::POST_HEAP; } deba@2284: deba@2284: ///@} deba@2284: }; deba@2284: deba@2284: /// \brief Default traits class of NagamochiIbaraki class. deba@2284: /// deba@2284: /// Default traits class of NagamochiIbaraki class. deba@2284: /// \param Graph Graph type. deba@2284: /// \param CapacityMap Type of length map. deba@2284: template deba@2284: struct NagamochiIbarakiDefaultTraits { deba@2284: /// \brief The type of the capacity of the edges. deba@2284: typedef typename _CapacityMap::Value Value; deba@2284: deba@2284: /// The graph type the algorithm runs on. deba@2284: typedef _Graph Graph; deba@2284: deba@2284: /// The AuxGraph type which is an Graph deba@2284: typedef ListUGraph AuxGraph; deba@2284: deba@2284: /// \brief Instantiates a AuxGraph. deba@2284: /// deba@2284: /// This function instantiates a \ref AuxGraph. deba@2284: static AuxGraph *createAuxGraph() { deba@2284: return new AuxGraph(); deba@2284: } deba@2284: deba@2284: /// \brief The type of the map that stores the edge capacities. deba@2284: /// deba@2284: /// The type of the map that stores the edge capacities. deba@2284: /// It must meet the \ref concepts::ReadMap "ReadMap" concept. deba@2284: typedef _CapacityMap CapacityMap; deba@2284: deba@2284: /// \brief Instantiates a CapacityMap. deba@2284: /// deba@2284: /// This function instantiates a \ref CapacityMap. deba@2284: #ifdef DOXYGEN deba@2284: static CapacityMap *createCapacityMap(const Graph& graph) deba@2284: #else deba@2284: static CapacityMap *createCapacityMap(const Graph&) deba@2284: #endif deba@2284: { deba@2284: throw UninitializedParameter(); deba@2284: } deba@2284: deba@2337: /// \brief The CutValueMap type deba@2337: /// deba@2337: /// The type of the map that stores the cut value of a node. deba@2337: typedef AuxGraph::NodeMap AuxCutValueMap; deba@2337: deba@2337: /// \brief Instantiates a AuxCutValueMap. deba@2337: /// deba@2337: /// This function instantiates a \ref AuxCutValueMap. deba@2337: static AuxCutValueMap *createAuxCutValueMap(const AuxGraph& graph) { deba@2337: return new AuxCutValueMap(graph); deba@2337: } deba@2337: deba@2284: /// \brief The AuxCapacityMap type deba@2284: /// deba@2337: /// The type of the map that stores the auxiliary edge capacities. deba@2284: typedef AuxGraph::UEdgeMap AuxCapacityMap; deba@2284: deba@2284: /// \brief Instantiates a AuxCapacityMap. deba@2284: /// deba@2284: /// This function instantiates a \ref AuxCapacityMap. deba@2284: static AuxCapacityMap *createAuxCapacityMap(const AuxGraph& graph) { deba@2284: return new AuxCapacityMap(graph); deba@2284: } deba@2284: deba@2284: /// \brief The cross reference type used by heap. deba@2284: /// deba@2284: /// The cross reference type used by heap. deba@2284: /// Usually it is \c Graph::NodeMap. deba@2284: typedef AuxGraph::NodeMap HeapCrossRef; deba@2284: deba@2284: /// \brief Instantiates a HeapCrossRef. deba@2284: /// deba@2284: /// This function instantiates a \ref HeapCrossRef. deba@2284: /// \param graph is the graph, to which we would like to define the deba@2284: /// HeapCrossRef. deba@2284: static HeapCrossRef *createHeapCrossRef(const AuxGraph &graph) { deba@2284: return new HeapCrossRef(graph); deba@2284: } deba@2284: deba@2284: /// \brief The heap type used by NagamochiIbaraki algorithm. deba@2284: /// deba@2284: /// The heap type used by NagamochiIbaraki algorithm. It should deba@2284: /// maximalize the priorities and the heap's key type is deba@2284: /// the aux graph's node. deba@2284: /// deba@2284: /// \sa BinHeap deba@2284: /// \sa NagamochiIbaraki deba@2284: typedef typename _min_cut_bits deba@2284: ::HeapSelector deba@2284: ::template Selector deba@2284: ::Heap Heap; deba@2284: deba@2284: /// \brief Instantiates a Heap. deba@2284: /// deba@2284: /// This function instantiates a \ref Heap. deba@2284: /// \param crossref The cross reference of the heap. deba@2284: static Heap *createHeap(HeapCrossRef& crossref) { deba@2284: return new Heap(crossref); deba@2284: } deba@2284: deba@2284: /// \brief Map from the AuxGraph's node type to the Graph's node type. deba@2284: /// deba@2284: /// Map from the AuxGraph's node type to the Graph's node type. deba@2284: typedef typename AuxGraph deba@2284: ::template NodeMap NodeRefMap; deba@2284: deba@2284: /// \brief Instantiates a NodeRefMap. deba@2284: /// deba@2284: /// This function instantiates a \ref NodeRefMap. deba@2284: static NodeRefMap *createNodeRefMap(const AuxGraph& graph) { deba@2284: return new NodeRefMap(graph); deba@2284: } deba@2284: deba@2284: /// \brief Map from the Graph's node type to the Graph's node type. deba@2284: /// deba@2284: /// Map from the Graph's node type to the Graph's node type. deba@2284: typedef typename Graph deba@2284: ::template NodeMap ListRefMap; deba@2284: deba@2284: /// \brief Instantiates a ListRefMap. deba@2284: /// deba@2284: /// This function instantiates a \ref ListRefMap. deba@2284: static ListRefMap *createListRefMap(const Graph& graph) { deba@2284: return new ListRefMap(graph); deba@2284: } deba@2284: deba@2284: deba@2284: }; deba@2284: deba@2376: /// \ingroup min_cut deba@2284: /// deba@2284: /// \brief Calculates the minimum cut in an undirected graph. deba@2284: /// deba@2284: /// Calculates the minimum cut in an undirected graph with the deba@2284: /// Nagamochi-Ibaraki algorithm. The algorithm separates the graph's deba@2284: /// nodes into two partitions with the minimum sum of edge capacities deba@2284: /// between the two partitions. The algorithm can be used to test deba@2284: /// the network reliability specifically to test how many links have deba@2284: /// to be destroyed in the network to split it at least two deba@2284: /// distinict subnetwork. deba@2284: /// deba@2284: /// The complexity of the algorithm is \f$ O(ne\log(n)) \f$ but with deba@2337: /// Fibonacci heap it can be decreased to \f$ O(ne+n^2\log(n)) \f$. deba@2337: /// When capacity map is neutral then it uses BucketHeap which deba@2284: /// results \f$ O(ne) \f$ time complexity. deba@2337: /// deba@2337: /// \warning The value type of the capacity map should be able to hold deba@2337: /// any cut value of the graph, otherwise the result can overflow. deba@2284: #ifdef DOXYGEN deba@2284: template deba@2284: #else deba@2284: template , deba@2284: typename _Traits deba@2284: = NagamochiIbarakiDefaultTraits<_Graph, _CapacityMap> > deba@2284: #endif deba@2284: class NagamochiIbaraki { deba@2284: public: deba@2284: /// \brief \ref Exception for uninitialized parameters. deba@2284: /// deba@2284: /// This error represents problems in the initialization deba@2284: /// of the parameters of the algorithms. deba@2284: class UninitializedParameter : public lemon::UninitializedParameter { deba@2284: public: deba@2284: virtual const char* what() const throw() { deba@2284: return "lemon::NagamochiIbaraki::UninitializedParameter"; deba@2284: } deba@2284: }; deba@2284: deba@2284: deba@2284: private: deba@2284: deba@2284: typedef _Traits Traits; deba@2284: /// The type of the underlying graph. deba@2284: typedef typename Traits::Graph Graph; deba@2284: deba@2284: /// The type of the capacity of the edges. deba@2284: typedef typename Traits::CapacityMap::Value Value; deba@2284: /// The type of the map that stores the edge capacities. deba@2284: typedef typename Traits::CapacityMap CapacityMap; deba@2284: /// The type of the aux graph deba@2284: typedef typename Traits::AuxGraph AuxGraph; deba@2284: /// The type of the aux capacity map deba@2284: typedef typename Traits::AuxCapacityMap AuxCapacityMap; deba@2337: /// The type of the aux cut value map deba@2337: typedef typename Traits::AuxCutValueMap AuxCutValueMap; deba@2284: /// The cross reference type used for the current heap. deba@2284: typedef typename Traits::HeapCrossRef HeapCrossRef; deba@2284: /// The heap type used by the max cardinality algorithm. deba@2284: typedef typename Traits::Heap Heap; deba@2284: /// The node refrefernces between the original and aux graph type. deba@2284: typedef typename Traits::NodeRefMap NodeRefMap; deba@2284: /// The list node refrefernces in the original graph type. deba@2284: typedef typename Traits::ListRefMap ListRefMap; deba@2284: deba@2284: public: deba@2284: deba@2284: ///\name Named template parameters deba@2284: deba@2284: ///@{ deba@2284: deba@2284: struct DefNeutralCapacityTraits : public Traits { deba@2284: typedef ConstMap > CapacityMap; deba@2284: static CapacityMap *createCapacityMap(const Graph&) { deba@2284: return new CapacityMap(); deba@2284: } deba@2284: }; deba@2284: /// \brief \ref named-templ-param "Named parameter" for setting deba@2284: /// the capacity type to constMap() deba@2284: /// deba@2284: /// \ref named-templ-param "Named parameter" for setting deba@2284: /// the capacity type to constMap() deba@2284: struct DefNeutralCapacity deba@2284: : public NagamochiIbaraki { deba@2284: typedef NagamochiIbaraki Create; deba@2284: }; deba@2284: deba@2284: deba@2284: template deba@2284: struct DefHeapTraits : public Traits { deba@2284: typedef CR HeapCrossRef; deba@2284: typedef H Heap; deba@2284: static HeapCrossRef *createHeapCrossRef(const AuxGraph &) { deba@2284: throw UninitializedParameter(); deba@2284: } deba@2284: static Heap *createHeap(HeapCrossRef &) { deba@2284: throw UninitializedParameter(); deba@2284: } deba@2284: }; deba@2284: /// \brief \ref named-templ-param "Named parameter" for setting heap deba@2284: /// and cross reference type deba@2284: /// deba@2284: /// \ref named-templ-param "Named parameter" for setting heap and cross deba@2284: /// reference type deba@2284: template > deba@2284: struct DefHeap deba@2284: : public NagamochiIbaraki > { deba@2284: typedef NagamochiIbaraki< Graph, CapacityMap, deba@2284: DefHeapTraits > Create; deba@2284: }; deba@2284: deba@2284: template deba@2284: struct DefStandardHeapTraits : public Traits { deba@2284: typedef CR HeapCrossRef; deba@2284: typedef H Heap; deba@2284: static HeapCrossRef *createHeapCrossRef(const AuxGraph &graph) { deba@2284: return new HeapCrossRef(graph); deba@2284: } deba@2284: static Heap *createHeap(HeapCrossRef &crossref) { deba@2284: return new Heap(crossref); deba@2284: } deba@2284: }; deba@2284: deba@2284: /// \brief \ref named-templ-param "Named parameter" for setting heap and deba@2284: /// cross reference type with automatic allocation deba@2284: /// deba@2284: /// \ref named-templ-param "Named parameter" for setting heap and cross deba@2284: /// reference type. It can allocate the heap and the cross reference deba@2284: /// object if the cross reference's constructor waits for the graph as deba@2284: /// parameter and the heap's constructor waits for the cross reference. deba@2284: template > deba@2284: struct DefStandardHeap deba@2284: : public NagamochiIbaraki > { deba@2284: typedef NagamochiIbaraki > deba@2284: Create; deba@2284: }; deba@2284: deba@2284: ///@} deba@2284: deba@2284: deba@2284: private: deba@2284: /// Pointer to the underlying graph. deba@2284: const Graph *_graph; deba@2284: /// Pointer to the capacity map deba@2284: const CapacityMap *_capacity; deba@2284: /// \brief Indicates if \ref _capacity is locally allocated deba@2284: /// (\c true) or not. deba@2284: bool local_capacity; deba@2284: deba@2284: /// Pointer to the aux graph. deba@2284: AuxGraph *_aux_graph; deba@2284: /// \brief Indicates if \ref _aux_graph is locally allocated deba@2284: /// (\c true) or not. deba@2284: bool local_aux_graph; deba@2284: /// Pointer to the aux capacity map deba@2284: AuxCapacityMap *_aux_capacity; deba@2284: /// \brief Indicates if \ref _aux_capacity is locally allocated deba@2284: /// (\c true) or not. deba@2284: bool local_aux_capacity; deba@2337: /// Pointer to the aux cut value map deba@2337: AuxCutValueMap *_aux_cut_value; deba@2337: /// \brief Indicates if \ref _aux_cut_value is locally allocated deba@2337: /// (\c true) or not. deba@2337: bool local_aux_cut_value; deba@2284: /// Pointer to the heap cross references. deba@2284: HeapCrossRef *_heap_cross_ref; deba@2284: /// \brief Indicates if \ref _heap_cross_ref is locally allocated deba@2284: /// (\c true) or not. deba@2284: bool local_heap_cross_ref; deba@2284: /// Pointer to the heap. deba@2284: Heap *_heap; deba@2284: /// Indicates if \ref _heap is locally allocated (\c true) or not. deba@2284: bool local_heap; deba@2284: deba@2284: /// The min cut value. deba@2284: Value _min_cut; deba@2284: /// The number of the nodes of the aux graph. deba@2284: int _node_num; deba@2337: /// The first and last node of the min cut in the next list. deba@2337: std::vector _cut; deba@2284: deba@2284: /// \brief The first and last element in the list associated deba@2284: /// to the aux graph node. deba@2284: NodeRefMap *_first, *_last; deba@2284: /// \brief The next node in the node lists. deba@2284: ListRefMap *_next; deba@2284: deba@2337: void createStructures() { deba@2284: if (!_capacity) { deba@2284: local_capacity = true; deba@2284: _capacity = Traits::createCapacityMap(*_graph); deba@2284: } deba@2284: if(!_aux_graph) { deba@2284: local_aux_graph = true; deba@2284: _aux_graph = Traits::createAuxGraph(); deba@2284: } deba@2284: if(!_aux_capacity) { deba@2284: local_aux_capacity = true; deba@2284: _aux_capacity = Traits::createAuxCapacityMap(*_aux_graph); deba@2284: } deba@2337: if(!_aux_cut_value) { deba@2337: local_aux_cut_value = true; deba@2337: _aux_cut_value = Traits::createAuxCutValueMap(*_aux_graph); deba@2337: } deba@2284: deba@2284: _first = Traits::createNodeRefMap(*_aux_graph); deba@2284: _last = Traits::createNodeRefMap(*_aux_graph); deba@2284: deba@2284: _next = Traits::createListRefMap(*_graph); deba@2284: deba@2284: if (!_heap_cross_ref) { deba@2284: local_heap_cross_ref = true; deba@2284: _heap_cross_ref = Traits::createHeapCrossRef(*_aux_graph); deba@2284: } deba@2284: if (!_heap) { deba@2284: local_heap = true; deba@2284: _heap = Traits::createHeap(*_heap_cross_ref); deba@2284: } deba@2284: } deba@2284: deba@2337: void createAuxGraph() { deba@2337: typename Graph::template NodeMap ref(*_graph); deba@2337: deba@2337: for (typename Graph::NodeIt n(*_graph); n != INVALID; ++n) { deba@2337: _next->set(n, INVALID); deba@2337: typename AuxGraph::Node node = _aux_graph->addNode(); deba@2337: _first->set(node, n); deba@2337: _last->set(node, n); deba@2337: ref.set(n, node); deba@2337: } deba@2337: deba@2337: typename AuxGraph::template NodeMap deba@2337: edges(*_aux_graph, INVALID); deba@2337: deba@2337: for (typename Graph::NodeIt n(*_graph); n != INVALID; ++n) { deba@2337: for (typename Graph::IncEdgeIt e(*_graph, n); e != INVALID; ++e) { deba@2337: typename Graph::Node tn = _graph->runningNode(e); deba@2337: if (n < tn || n == tn) continue; deba@2337: if (edges[ref[tn]] != INVALID) { deba@2337: Value value = deba@2337: (*_aux_capacity)[edges[ref[tn]]] + (*_capacity)[e]; deba@2337: _aux_capacity->set(edges[ref[tn]], value); deba@2337: } else { deba@2337: edges.set(ref[tn], _aux_graph->addEdge(ref[n], ref[tn])); deba@2337: Value value = (*_capacity)[e]; deba@2337: _aux_capacity->set(edges[ref[tn]], value); deba@2337: } deba@2337: } deba@2337: for (typename Graph::IncEdgeIt e(*_graph, n); e != INVALID; ++e) { deba@2337: typename Graph::Node tn = _graph->runningNode(e); deba@2337: edges.set(ref[tn], INVALID); deba@2337: } deba@2337: } deba@2337: deba@2337: _cut.resize(1, INVALID); deba@2337: _min_cut = std::numeric_limits::max(); deba@2337: for (typename AuxGraph::NodeIt n(*_aux_graph); n != INVALID; ++n) { deba@2337: Value value = 0; deba@2337: for (typename AuxGraph::IncEdgeIt e(*_aux_graph, n); deba@2337: e != INVALID; ++e) { deba@2337: value += (*_aux_capacity)[e]; deba@2337: } deba@2337: if (_min_cut > value) { deba@2337: _min_cut = value; deba@2337: _cut[0] = (*_first)[n]; deba@2337: } deba@2337: (*_aux_cut_value)[n] = value; deba@2337: } deba@2337: } deba@2337: deba@2337: deba@2284: public : deba@2284: deba@2284: typedef NagamochiIbaraki Create; deba@2284: deba@2284: deba@2284: /// \brief Constructor. deba@2284: /// deba@2284: ///\param graph the graph the algorithm will run on. deba@2284: ///\param capacity the capacity map used by the algorithm. deba@2284: NagamochiIbaraki(const Graph& graph, const CapacityMap& capacity) deba@2284: : _graph(&graph), deba@2284: _capacity(&capacity), local_capacity(false), deba@2284: _aux_graph(0), local_aux_graph(false), deba@2284: _aux_capacity(0), local_aux_capacity(false), deba@2337: _aux_cut_value(0), local_aux_cut_value(false), deba@2284: _heap_cross_ref(0), local_heap_cross_ref(false), deba@2284: _heap(0), local_heap(false), deba@2284: _first(0), _last(0), _next(0) {} deba@2284: deba@2284: /// \brief Constructor. deba@2284: /// deba@2284: /// This constructor can be used only when the Traits class deba@2284: /// defines how can we instantiate a local capacity map. deba@2284: /// If the DefNeutralCapacity used the algorithm automatically deba@2284: /// construct the capacity map. deba@2284: /// deba@2284: ///\param graph the graph the algorithm will run on. deba@2284: NagamochiIbaraki(const Graph& graph) deba@2284: : _graph(&graph), deba@2284: _capacity(0), local_capacity(false), deba@2284: _aux_graph(0), local_aux_graph(false), deba@2284: _aux_capacity(0), local_aux_capacity(false), deba@2337: _aux_cut_value(0), local_aux_cut_value(false), deba@2284: _heap_cross_ref(0), local_heap_cross_ref(false), deba@2284: _heap(0), local_heap(false), deba@2284: _first(0), _last(0), _next(0) {} deba@2284: deba@2284: /// \brief Destructor. deba@2284: /// deba@2284: /// Destructor. deba@2284: ~NagamochiIbaraki() { deba@2284: if (local_heap) delete _heap; deba@2284: if (local_heap_cross_ref) delete _heap_cross_ref; deba@2284: if (_first) delete _first; deba@2284: if (_last) delete _last; deba@2284: if (_next) delete _next; deba@2284: if (local_aux_capacity) delete _aux_capacity; deba@2337: if (local_aux_cut_value) delete _aux_cut_value; deba@2284: if (local_aux_graph) delete _aux_graph; deba@2284: if (local_capacity) delete _capacity; deba@2284: } deba@2284: deba@2284: /// \brief Sets the heap and the cross reference used by algorithm. deba@2284: /// deba@2284: /// Sets the heap and the cross reference used by algorithm. deba@2284: /// If you don't use this function before calling \ref run(), deba@2284: /// it will allocate one. The destuctor deallocates this deba@2284: /// automatically allocated heap and cross reference, of course. deba@2284: /// \return (*this) deba@2386: NagamochiIbaraki &heap(Heap& hp, HeapCrossRef &cr) deba@2284: { deba@2284: if (local_heap_cross_ref) { deba@2284: delete _heap_cross_ref; deba@2284: local_heap_cross_ref=false; deba@2284: } deba@2386: _heap_cross_ref = &cr; deba@2284: if (local_heap) { deba@2284: delete _heap; deba@2284: local_heap=false; deba@2284: } deba@2386: _heap = &hp; deba@2284: return *this; deba@2284: } deba@2284: deba@2284: /// \brief Sets the aux graph. deba@2284: /// deba@2284: /// Sets the aux graph used by algorithm. deba@2284: /// If you don't use this function before calling \ref run(), deba@2284: /// it will allocate one. The destuctor deallocates this deba@2284: /// automatically allocated graph, of course. deba@2284: /// \return (*this) deba@2284: NagamochiIbaraki &auxGraph(AuxGraph& aux_graph) deba@2284: { deba@2284: if(local_aux_graph) { deba@2284: delete _aux_graph; deba@2284: local_aux_graph=false; deba@2284: } deba@2284: _aux_graph = &aux_graph; deba@2284: return *this; deba@2284: } deba@2284: deba@2284: /// \brief Sets the aux capacity map. deba@2284: /// deba@2284: /// Sets the aux capacity map used by algorithm. deba@2284: /// If you don't use this function before calling \ref run(), deba@2284: /// it will allocate one. The destuctor deallocates this deba@2284: /// automatically allocated graph, of course. deba@2284: /// \return (*this) deba@2284: NagamochiIbaraki &auxCapacityMap(AuxCapacityMap& aux_capacity_map) deba@2284: { deba@2284: if(local_aux_capacity) { deba@2284: delete _aux_capacity; deba@2284: local_aux_capacity=false; deba@2284: } deba@2284: _aux_capacity = &aux_capacity_map; deba@2284: return *this; deba@2284: } deba@2284: deba@2284: /// \name Execution control deba@2284: /// The simplest way to execute the algorithm is to use deba@2284: /// one of the member functions called \c run(). deba@2284: /// \n deba@2284: /// If you need more control on the execution, deba@2284: /// first you must call \ref init() and then call the start() deba@2284: /// or proper times the processNextPhase() member functions. deba@2284: deba@2284: ///@{ deba@2284: deba@2284: /// \brief Initializes the internal data structures. deba@2284: /// deba@2284: /// Initializes the internal data structures. deba@2284: void init() { deba@2284: _node_num = countNodes(*_graph); deba@2337: createStructures(); deba@2337: createAuxGraph(); deba@2284: } deba@2284: deba@2337: private: deba@2337: deba@2337: struct EdgeInfo { deba@2337: typename AuxGraph::Node source, target; deba@2337: Value capacity; deba@2337: }; deba@2337: deba@2337: struct EdgeInfoLess { deba@2337: bool operator()(const EdgeInfo& left, const EdgeInfo& right) const { deba@2337: return (left.source < right.source) || deba@2337: (left.source == right.source && left.target < right.target); deba@2337: } deba@2337: }; deba@2337: deba@2337: public: deba@2337: deba@2337: deba@2284: /// \brief Processes the next phase deba@2284: /// deba@2337: /// Processes the next phase in the algorithm. The function should deba@2337: /// be called at most countNodes(graph) - 1 times to get surely deba@2337: /// the min cut in the graph. deba@2284: /// deba@2284: ///\return %True when the algorithm finished. deba@2284: bool processNextPhase() { deba@2284: if (_node_num <= 1) return true; deba@2284: deba@2284: typedef typename AuxGraph::Node Node; deba@2284: typedef typename AuxGraph::NodeIt NodeIt; deba@2284: typedef typename AuxGraph::UEdge UEdge; deba@2337: typedef typename AuxGraph::UEdgeIt UEdgeIt; deba@2284: typedef typename AuxGraph::IncEdgeIt IncEdgeIt; deba@2284: deba@2337: typename AuxGraph::template UEdgeMap _edge_cut(*_aux_graph); deba@2337: deba@2337: deba@2337: for (NodeIt n(*_aux_graph); n != INVALID; ++n) { deba@2337: _heap_cross_ref->set(n, Heap::PRE_HEAP); deba@2284: } deba@2284: deba@2337: std::vector nodes; deba@2337: nodes.reserve(_node_num); deba@2337: int sep = 0; deba@2284: deba@2337: Value alpha = 0; deba@2337: Value emc = std::numeric_limits::max(); deba@2284: deba@2337: _heap->push(typename AuxGraph::NodeIt(*_aux_graph), 0); deba@2337: while (!_heap->empty()) { deba@2337: Node node = _heap->top(); deba@2337: Value value = _heap->prio(); deba@2337: deba@2337: _heap->pop(); deba@2337: for (typename AuxGraph::IncEdgeIt e(*_aux_graph, node); deba@2337: e != INVALID; ++e) { deba@2337: Node tn = _aux_graph->runningNode(e); deba@2337: switch (_heap->state(tn)) { deba@2337: case Heap::PRE_HEAP: deba@2337: _heap->push(tn, (*_aux_capacity)[e]); deba@2337: _edge_cut[e] = (*_heap)[tn]; deba@2337: break; deba@2337: case Heap::IN_HEAP: deba@2337: _heap->decrease(tn, (*_aux_capacity)[e] + (*_heap)[tn]); deba@2337: _edge_cut[e] = (*_heap)[tn]; deba@2337: break; deba@2337: case Heap::POST_HEAP: deba@2337: break; deba@2337: } deba@2337: } deba@2284: deba@2337: alpha += (*_aux_cut_value)[node]; deba@2337: alpha -= 2 * value; deba@2284: deba@2337: nodes.push_back(node); deba@2337: if (!_heap->empty()) { deba@2337: if (alpha < emc) { deba@2337: emc = alpha; deba@2337: sep = nodes.size(); deba@2337: } deba@2284: } deba@2284: } deba@2284: deba@2386: if (int(nodes.size()) < _node_num) { deba@2337: _aux_graph->clear(); deba@2337: _node_num = 1; deba@2337: _cut.clear(); deba@2386: for (int i = 0; i < int(nodes.size()); ++i) { deba@2337: typename Graph::Node n = (*_first)[nodes[i]]; deba@2337: while (n != INVALID) { deba@2337: _cut.push_back(n); deba@2337: n = (*_next)[n]; deba@2337: } deba@2337: } deba@2337: _min_cut = 0; deba@2337: return true; deba@2284: } deba@2284: deba@2337: if (emc < _min_cut) { deba@2337: _cut.clear(); deba@2337: for (int i = 0; i < sep; ++i) { deba@2337: typename Graph::Node n = (*_first)[nodes[i]]; deba@2337: while (n != INVALID) { deba@2337: _cut.push_back(n); deba@2337: n = (*_next)[n]; deba@2337: } deba@2337: } deba@2337: _min_cut = emc; deba@2337: } deba@2284: deba@2337: typedef typename AuxGraph::template NodeMap UfeCr; deba@2337: UfeCr ufecr(*_aux_graph); deba@2337: typedef UnionFindEnum Ufe; deba@2337: Ufe ufe(ufecr); deba@2337: deba@2337: for (typename AuxGraph::NodeIt n(*_aux_graph); n != INVALID; ++n) { deba@2337: ufe.insert(n); deba@2337: } deba@2337: deba@2337: for (typename AuxGraph::UEdgeIt e(*_aux_graph); e != INVALID; ++e) { deba@2337: if (_edge_cut[e] >= emc) { deba@2337: ufe.join(_aux_graph->source(e), _aux_graph->target(e)); deba@2284: } deba@2284: } deba@2284: deba@2386: typedef typename Ufe::ClassIt UfeCIt; deba@2386: if (ufe.size(UfeCIt(ufe)) == _node_num) { deba@2337: _aux_graph->clear(); deba@2337: _node_num = 1; deba@2337: return true; deba@2337: } deba@2337: deba@2337: std::vector remnodes; deba@2337: deba@2337: typename AuxGraph::template NodeMap edges(*_aux_graph, INVALID); deba@2337: for (typename Ufe::ClassIt c(ufe); c != INVALID; ++c) { deba@2337: if (ufe.size(c) == 1) continue; deba@2337: for (typename Ufe::ItemIt r(ufe, c); r != INVALID; ++r) { deba@2386: if (static_cast(r) == static_cast(c)) continue; deba@2337: _next->set((*_last)[c], (*_first)[r]); deba@2337: _last->set(c, (*_last)[r]); deba@2337: remnodes.push_back(r); deba@2337: --_node_num; deba@2337: } deba@2337: } deba@2337: deba@2337: std::vector addedges; deba@2337: std::vector remedges; deba@2337: deba@2337: for (typename AuxGraph::UEdgeIt e(*_aux_graph); deba@2337: e != INVALID; ++e) { deba@2337: Node sn = ufe.find(_aux_graph->source(e)); deba@2337: Node tn = ufe.find(_aux_graph->target(e)); deba@2337: if ((ufe.size(sn) == 1 && ufe.size(tn) == 1)) { deba@2337: continue; deba@2337: } deba@2337: if (sn == tn) { deba@2337: remedges.push_back(e); deba@2337: continue; deba@2337: } deba@2337: EdgeInfo info; deba@2337: if (sn < tn) { deba@2337: info.source = sn; deba@2337: info.target = tn; deba@2337: } else { deba@2337: info.source = tn; deba@2337: info.target = sn; deba@2337: } deba@2337: info.capacity = (*_aux_capacity)[e]; deba@2337: addedges.push_back(info); deba@2337: remedges.push_back(e); deba@2337: } deba@2337: deba@2386: for (int i = 0; i < int(remedges.size()); ++i) { deba@2337: _aux_graph->erase(remedges[i]); deba@2337: } deba@2337: deba@2337: sort(addedges.begin(), addedges.end(), EdgeInfoLess()); deba@2337: deba@2337: { deba@2337: int i = 0; deba@2386: while (i < int(addedges.size())) { deba@2337: Node sn = addedges[i].source; deba@2337: Node tn = addedges[i].target; deba@2337: Value ec = addedges[i].capacity; deba@2337: ++i; deba@2386: while (i < int(addedges.size()) && deba@2337: sn == addedges[i].source && tn == addedges[i].target) { deba@2337: ec += addedges[i].capacity; deba@2337: ++i; deba@2337: } deba@2337: typename AuxGraph::UEdge ne = _aux_graph->addEdge(sn, tn); deba@2337: (*_aux_capacity)[ne] = ec; deba@2337: } deba@2337: } deba@2337: deba@2337: for (typename Ufe::ClassIt c(ufe); c != INVALID; ++c) { deba@2337: if (ufe.size(c) == 1) continue; deba@2337: Value cutvalue = 0; deba@2337: for (typename AuxGraph::IncEdgeIt e(*_aux_graph, c); deba@2337: e != INVALID; ++e) { deba@2337: cutvalue += (*_aux_capacity)[e]; deba@2337: } deba@2337: deba@2337: (*_aux_cut_value)[c] = cutvalue; deba@2337: deba@2337: } deba@2337: deba@2386: for (int i = 0; i < int(remnodes.size()); ++i) { deba@2337: _aux_graph->erase(remnodes[i]); deba@2337: } deba@2337: deba@2284: return _node_num == 1; deba@2284: } deba@2284: deba@2284: /// \brief Executes the algorithm. deba@2284: /// deba@2284: /// Executes the algorithm. deba@2284: /// deba@2284: /// \pre init() must be called deba@2284: void start() { deba@2284: while (!processNextPhase()); deba@2284: } deba@2284: deba@2284: deba@2284: /// \brief Runs %NagamochiIbaraki algorithm. deba@2284: /// deba@2284: /// This method runs the %Min cut algorithm deba@2284: /// deba@2284: /// \note mc.run(s) is just a shortcut of the following code. deba@2284: ///\code deba@2284: /// mc.init(); deba@2284: /// mc.start(); deba@2284: ///\endcode deba@2284: void run() { deba@2284: init(); deba@2284: start(); deba@2284: } deba@2284: deba@2284: ///@} deba@2284: deba@2284: /// \name Query Functions deba@2284: /// deba@2284: /// The result of the %NagamochiIbaraki deba@2284: /// algorithm can be obtained using these functions.\n deba@2284: /// Before the use of these functions, either run() or start() deba@2284: /// must be called. deba@2284: deba@2284: ///@{ deba@2284: deba@2284: /// \brief Returns the min cut value. deba@2284: /// deba@2284: /// Returns the min cut value if the algorithm finished. deba@2284: /// After the first processNextPhase() it is a value of a deba@2284: /// valid cut in the graph. deba@2284: Value minCut() const { deba@2284: return _min_cut; deba@2284: } deba@2284: deba@2284: /// \brief Returns a min cut in a NodeMap. deba@2284: /// deba@2284: /// It sets the nodes of one of the two partitions to true in deba@2284: /// the given BoolNodeMap. The map contains a valid cut if the deba@2284: /// map have been set false previously. deba@2284: template deba@2284: Value quickMinCut(NodeMap& nodeMap) const { deba@2386: for (int i = 0; i < int(_cut.size()); ++i) { deba@2337: nodeMap.set(_cut[i], true); deba@2337: } deba@2284: return minCut(); deba@2284: } deba@2284: deba@2284: /// \brief Returns a min cut in a NodeMap. deba@2284: /// deba@2284: /// It sets the nodes of one of the two partitions to true and deba@2284: /// the other partition to false. The function first set all of the deba@2284: /// nodes to false and after it call the quickMinCut() member. deba@2284: template deba@2284: Value minCut(NodeMap& nodeMap) const { deba@2284: for (typename Graph::NodeIt it(*_graph); it != INVALID; ++it) { deba@2284: nodeMap.set(it, false); deba@2284: } deba@2284: quickMinCut(nodeMap); deba@2284: return minCut(); deba@2284: } deba@2284: deba@2284: /// \brief Returns a min cut in an EdgeMap. deba@2284: /// deba@2284: /// If an undirected edge is in a min cut then it will be deba@2284: /// set to true and the others will be set to false in the given map. deba@2284: template deba@2284: Value cutEdges(EdgeMap& edgeMap) const { deba@2284: typename Graph::template NodeMap cut(*_graph, false); deba@2284: quickMinCut(cut); deba@2284: for (typename Graph::EdgeIt it(*_graph); it != INVALID; ++it) { deba@2284: edgeMap.set(it, cut[_graph->source(it)] ^ cut[_graph->target(it)]); deba@2284: } deba@2284: return minCut(); deba@2284: } deba@2284: deba@2284: ///@} deba@2284: deba@2337: private: deba@2337: deba@2337: deba@2284: }; deba@2284: } deba@2284: deba@2284: #endif