2 * lemon/min_cut.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
17 #ifndef LEMON_NAGAMOCHI_IBARAKI_H
18 #define LEMON_NAGAMOCHI_IBARAKI_H
23 /// \brief Maximum cardinality search and minimum cut in undirected
26 #include <lemon/list_graph.h>
27 #include <lemon/bin_heap.h>
28 #include <lemon/bucket_heap.h>
30 #include <lemon/unionfind.h>
31 #include <lemon/topology.h>
33 #include <lemon/bits/invalid.h>
34 #include <lemon/error.h>
35 #include <lemon/maps.h>
39 #include <lemon/graph_writer.h>
40 #include <lemon/time_measure.h>
44 namespace _min_cut_bits {
46 template <typename CapacityMap>
48 template <typename Value, typename Ref>
50 typedef BinHeap<Value, Ref, std::greater<Value> > Heap;
54 template <typename CapacityKey>
55 struct HeapSelector<ConstMap<CapacityKey, Const<int, 1> > > {
56 template <typename Value, typename Ref>
58 typedef BucketHeap<Ref, false > Heap;
64 /// \brief Default traits class of MaxCardinalitySearch class.
66 /// Default traits class of MaxCardinalitySearch class.
67 /// \param Graph Graph type.
68 /// \param CapacityMap Type of length map.
69 template <typename _Graph, typename _CapacityMap>
70 struct MaxCardinalitySearchDefaultTraits {
71 /// The graph type the algorithm runs on.
74 /// \brief The type of the map that stores the edge capacities.
76 /// The type of the map that stores the edge capacities.
77 /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
78 typedef _CapacityMap CapacityMap;
80 /// \brief The type of the capacity of the edges.
81 typedef typename CapacityMap::Value Value;
83 /// \brief The cross reference type used by heap.
85 /// The cross reference type used by heap.
86 /// Usually it is \c Graph::NodeMap<int>.
87 typedef typename Graph::template NodeMap<int> HeapCrossRef;
89 /// \brief Instantiates a HeapCrossRef.
91 /// This function instantiates a \ref HeapCrossRef.
92 /// \param graph is the graph, to which we would like to define the
94 static HeapCrossRef *createHeapCrossRef(const Graph &graph) {
95 return new HeapCrossRef(graph);
98 /// \brief The heap type used by MaxCardinalitySearch algorithm.
100 /// The heap type used by MaxCardinalitySearch algorithm. It should
101 /// maximalize the priorities. The default heap type is
102 /// the \ref BinHeap, but it is specialized when the
103 /// CapacityMap is ConstMap<Graph::Node, Const<int, 1> >
106 /// \sa MaxCardinalitySearch
107 typedef typename _min_cut_bits
108 ::HeapSelector<CapacityMap>
109 ::template Selector<Value, HeapCrossRef>
112 /// \brief Instantiates a Heap.
114 /// This function instantiates a \ref Heap.
115 /// \param crossref The cross reference of the heap.
116 static Heap *createHeap(HeapCrossRef& crossref) {
117 return new Heap(crossref);
120 /// \brief The type of the map that stores whether a nodes is processed.
122 /// The type of the map that stores whether a nodes is processed.
123 /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
124 /// By default it is a NullMap.
125 typedef NullMap<typename Graph::Node, bool> ProcessedMap;
127 /// \brief Instantiates a ProcessedMap.
129 /// This function instantiates a \ref ProcessedMap.
130 /// \param graph is the graph, to which
131 /// we would like to define the \ref ProcessedMap
133 static ProcessedMap *createProcessedMap(const Graph &graph)
135 static ProcessedMap *createProcessedMap(const Graph &)
138 return new ProcessedMap();
141 /// \brief The type of the map that stores the cardinalties of the nodes.
143 /// The type of the map that stores the cardinalities of the nodes.
144 /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
145 typedef typename Graph::template NodeMap<Value> CardinalityMap;
147 /// \brief Instantiates a CardinalityMap.
149 /// This function instantiates a \ref CardinalityMap.
150 /// \param graph is the graph, to which we would like to define the \ref
152 static CardinalityMap *createCardinalityMap(const Graph &graph) {
153 return new CardinalityMap(graph);
159 /// \ingroup topology
161 /// \brief Maximum Cardinality Search algorithm class.
163 /// This class provides an efficient implementation of Maximum Cardinality
164 /// Search algorithm. The maximum cardinality search chooses first time any
165 /// node of the graph. Then every time it chooses the node which is connected
166 /// to the processed nodes at most in the sum of capacities on the out
167 /// edges. If there is a cut in the graph the algorithm should choose
168 /// again any unprocessed node of the graph. Each node cardinality is
169 /// the sum of capacities on the out edges to the nodes which are processed
170 /// before the given node.
172 /// The edge capacities are passed to the algorithm using a
173 /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
174 /// kind of capacity.
176 /// The type of the capacity is determined by the \ref
177 /// concepts::ReadMap::Value "Value" of the capacity map.
179 /// It is also possible to change the underlying priority heap.
182 /// \param _Graph The graph type the algorithm runs on. The default value
183 /// is \ref ListGraph. The value of Graph is not used directly by
184 /// the search algorithm, it is only passed to
185 /// \ref MaxCardinalitySearchDefaultTraits.
186 /// \param _CapacityMap This read-only EdgeMap determines the capacities of
187 /// the edges. It is read once for each edge, so the map may involve in
188 /// relatively time consuming process to compute the edge capacity if
189 /// it is necessary. The default map type is \ref
190 /// concepts::Graph::EdgeMap "Graph::EdgeMap<int>". The value
191 /// of CapacityMap is not used directly by search algorithm, it is only
192 /// passed to \ref MaxCardinalitySearchDefaultTraits.
193 /// \param _Traits Traits class to set various data types used by the
194 /// algorithm. The default traits class is
195 /// \ref MaxCardinalitySearchDefaultTraits
196 /// "MaxCardinalitySearchDefaultTraits<_Graph, _CapacityMap>".
197 /// See \ref MaxCardinalitySearchDefaultTraits
198 /// for the documentation of a MaxCardinalitySearch traits class.
200 /// \author Balazs Dezso
203 template <typename _Graph, typename _CapacityMap, typename _Traits>
205 template <typename _Graph = ListUGraph,
206 typename _CapacityMap = typename _Graph::template EdgeMap<int>,
208 MaxCardinalitySearchDefaultTraits<_Graph, _CapacityMap> >
210 class MaxCardinalitySearch {
212 /// \brief \ref Exception for uninitialized parameters.
214 /// This error represents problems in the initialization
215 /// of the parameters of the algorithms.
216 class UninitializedParameter : public lemon::UninitializedParameter {
218 virtual const char* what() const throw() {
219 return "lemon::MaxCardinalitySearch::UninitializedParameter";
223 typedef _Traits Traits;
224 ///The type of the underlying graph.
225 typedef typename Traits::Graph Graph;
227 ///The type of the capacity of the edges.
228 typedef typename Traits::CapacityMap::Value Value;
229 ///The type of the map that stores the edge capacities.
230 typedef typename Traits::CapacityMap CapacityMap;
231 ///The type of the map indicating if a node is processed.
232 typedef typename Traits::ProcessedMap ProcessedMap;
233 ///The type of the map that stores the cardinalities of the nodes.
234 typedef typename Traits::CardinalityMap CardinalityMap;
235 ///The cross reference type used for the current heap.
236 typedef typename Traits::HeapCrossRef HeapCrossRef;
237 ///The heap type used by the algorithm. It maximize the priorities.
238 typedef typename Traits::Heap Heap;
240 /// Pointer to the underlying graph.
242 /// Pointer to the capacity map
243 const CapacityMap *_capacity;
244 ///Pointer to the map of cardinality.
245 CardinalityMap *_cardinality;
246 ///Indicates if \ref _cardinality is locally allocated (\c true) or not.
247 bool local_cardinality;
248 ///Pointer to the map of processed status of the nodes.
249 ProcessedMap *_processed;
250 ///Indicates if \ref _processed is locally allocated (\c true) or not.
251 bool local_processed;
252 ///Pointer to the heap cross references.
253 HeapCrossRef *_heap_cross_ref;
254 ///Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not.
255 bool local_heap_cross_ref;
256 ///Pointer to the heap.
258 ///Indicates if \ref _heap is locally allocated (\c true) or not.
263 typedef MaxCardinalitySearch Create;
265 ///\name Named template parameters
270 struct DefCardinalityMapTraits : public Traits {
271 typedef T CardinalityMap;
272 static CardinalityMap *createCardinalityMap(const Graph &)
274 throw UninitializedParameter();
277 /// \brief \ref named-templ-param "Named parameter" for setting
278 /// CardinalityMap type
280 /// \ref named-templ-param "Named parameter" for setting CardinalityMap
283 struct DefCardinalityMap
284 : public MaxCardinalitySearch<Graph, CapacityMap,
285 DefCardinalityMapTraits<T> > {
286 typedef MaxCardinalitySearch<Graph, CapacityMap,
287 DefCardinalityMapTraits<T> > Create;
291 struct DefProcessedMapTraits : public Traits {
292 typedef T ProcessedMap;
293 static ProcessedMap *createProcessedMap(const Graph &) {
294 throw UninitializedParameter();
297 /// \brief \ref named-templ-param "Named parameter" for setting
298 /// ProcessedMap type
300 /// \ref named-templ-param "Named parameter" for setting ProcessedMap type
303 struct DefProcessedMap
304 : public MaxCardinalitySearch<Graph, CapacityMap,
305 DefProcessedMapTraits<T> > {
306 typedef MaxCardinalitySearch<Graph, CapacityMap,
307 DefProcessedMapTraits<T> > Create;
310 template <class H, class CR>
311 struct DefHeapTraits : public Traits {
312 typedef CR HeapCrossRef;
314 static HeapCrossRef *createHeapCrossRef(const Graph &) {
315 throw UninitializedParameter();
317 static Heap *createHeap(HeapCrossRef &) {
318 throw UninitializedParameter();
321 /// \brief \ref named-templ-param "Named parameter" for setting heap
322 /// and cross reference type
324 /// \ref named-templ-param "Named parameter" for setting heap and cross
326 template <class H, class CR = typename Graph::template NodeMap<int> >
328 : public MaxCardinalitySearch<Graph, CapacityMap,
329 DefHeapTraits<H, CR> > {
330 typedef MaxCardinalitySearch< Graph, CapacityMap,
331 DefHeapTraits<H, CR> > Create;
334 template <class H, class CR>
335 struct DefStandardHeapTraits : public Traits {
336 typedef CR HeapCrossRef;
338 static HeapCrossRef *createHeapCrossRef(const Graph &graph) {
339 return new HeapCrossRef(graph);
341 static Heap *createHeap(HeapCrossRef &crossref) {
342 return new Heap(crossref);
346 /// \brief \ref named-templ-param "Named parameter" for setting heap and
347 /// cross reference type with automatic allocation
349 /// \ref named-templ-param "Named parameter" for setting heap and cross
350 /// reference type. It can allocate the heap and the cross reference
351 /// object if the cross reference's constructor waits for the graph as
352 /// parameter and the heap's constructor waits for the cross reference.
353 template <class H, class CR = typename Graph::template NodeMap<int> >
354 struct DefStandardHeap
355 : public MaxCardinalitySearch<Graph, CapacityMap,
356 DefStandardHeapTraits<H, CR> > {
357 typedef MaxCardinalitySearch<Graph, CapacityMap,
358 DefStandardHeapTraits<H, CR> >
367 MaxCardinalitySearch() {}
371 /// \brief Constructor.
373 ///\param graph the graph the algorithm will run on.
374 ///\param capacity the capacity map used by the algorithm.
375 MaxCardinalitySearch(const Graph& graph, const CapacityMap& capacity) :
376 _graph(&graph), _capacity(&capacity),
377 _cardinality(0), local_cardinality(false),
378 _processed(0), local_processed(false),
379 _heap_cross_ref(0), local_heap_cross_ref(false),
380 _heap(0), local_heap(false)
383 /// \brief Destructor.
384 ~MaxCardinalitySearch() {
385 if(local_cardinality) delete _cardinality;
386 if(local_processed) delete _processed;
387 if(local_heap_cross_ref) delete _heap_cross_ref;
388 if(local_heap) delete _heap;
391 /// \brief Sets the capacity map.
393 /// Sets the capacity map.
394 /// \return <tt> (*this) </tt>
395 MaxCardinalitySearch &capacityMap(const CapacityMap &m) {
400 /// \brief Sets the map storing the cardinalities calculated by the
403 /// Sets the map storing the cardinalities calculated by the algorithm.
404 /// If you don't use this function before calling \ref run(),
405 /// it will allocate one. The destuctor deallocates this
406 /// automatically allocated map, of course.
407 /// \return <tt> (*this) </tt>
408 MaxCardinalitySearch &cardinalityMap(CardinalityMap &m) {
409 if(local_cardinality) {
411 local_cardinality=false;
417 /// \brief Sets the map storing the processed nodes.
419 /// Sets the map storing the processed nodes.
420 /// If you don't use this function before calling \ref run(),
421 /// it will allocate one. The destuctor deallocates this
422 /// automatically allocated map, of course.
423 /// \return <tt> (*this) </tt>
424 MaxCardinalitySearch &processedMap(ProcessedMap &m)
426 if(local_processed) {
428 local_processed=false;
434 /// \brief Sets the heap and the cross reference used by algorithm.
436 /// Sets the heap and the cross reference used by algorithm.
437 /// If you don't use this function before calling \ref run(),
438 /// it will allocate one. The destuctor deallocates this
439 /// automatically allocated map, of course.
440 /// \return <tt> (*this) </tt>
441 MaxCardinalitySearch &heap(Heap& heap, HeapCrossRef &crossRef) {
442 if(local_heap_cross_ref) {
443 delete _heap_cross_ref;
444 local_heap_cross_ref = false;
446 _heap_cross_ref = &crossRef;
457 typedef typename Graph::Node Node;
458 typedef typename Graph::NodeIt NodeIt;
459 typedef typename Graph::Edge Edge;
460 typedef typename Graph::InEdgeIt InEdgeIt;
464 local_cardinality = true;
465 _cardinality = Traits::createCardinalityMap(*_graph);
468 local_processed = true;
469 _processed = Traits::createProcessedMap(*_graph);
471 if (!_heap_cross_ref) {
472 local_heap_cross_ref = true;
473 _heap_cross_ref = Traits::createHeapCrossRef(*_graph);
477 _heap = Traits::createHeap(*_heap_cross_ref);
481 void finalizeNodeData(Node node, Value capacity) {
482 _processed->set(node, true);
483 _cardinality->set(node, capacity);
487 /// \name Execution control
488 /// The simplest way to execute the algorithm is to use
489 /// one of the member functions called \c run(...).
491 /// If you need more control on the execution,
492 /// first you must call \ref init(), then you can add several source nodes
493 /// with \ref addSource().
494 /// Finally \ref start() will perform the actual path
499 /// \brief Initializes the internal data structures.
501 /// Initializes the internal data structures.
505 for (NodeIt it(*_graph) ; it != INVALID ; ++it) {
506 _processed->set(it, false);
507 _heap_cross_ref->set(it, Heap::PRE_HEAP);
511 /// \brief Adds a new source node.
513 /// Adds a new source node to the priority heap.
515 /// It checks if the node has not yet been added to the heap.
516 void addSource(Node source, Value capacity = 0) {
517 if(_heap->state(source) == Heap::PRE_HEAP) {
518 _heap->push(source, capacity);
522 /// \brief Processes the next node in the priority heap
524 /// Processes the next node in the priority heap.
526 /// \return The processed node.
528 /// \warning The priority heap must not be empty!
529 Node processNextNode() {
530 Node node = _heap->top();
531 finalizeNodeData(node, _heap->prio());
534 for (InEdgeIt it(*_graph, node); it != INVALID; ++it) {
535 Node source = _graph->source(it);
536 switch (_heap->state(source)) {
538 _heap->push(source, (*_capacity)[it]);
541 _heap->decrease(source, (*_heap)[source] + (*_capacity)[it]);
543 case Heap::POST_HEAP:
550 /// \brief Next node to be processed.
552 /// Next node to be processed.
554 /// \return The next node to be processed or INVALID if the
555 /// priority heap is empty.
557 return _heap->empty() ? _heap->top() : INVALID;
560 /// \brief Returns \c false if there are nodes
561 /// to be processed in the priority heap
563 /// Returns \c false if there are nodes
564 /// to be processed in the priority heap
565 bool emptyQueue() { return _heap->empty(); }
566 /// \brief Returns the number of the nodes to be processed
567 /// in the priority heap
569 /// Returns the number of the nodes to be processed in the priority heap
570 int queueSize() { return _heap->size(); }
572 /// \brief Executes the algorithm.
574 /// Executes the algorithm.
576 ///\pre init() must be called and at least one node should be added
577 /// with addSource() before using this function.
579 /// This method runs the Maximum Cardinality Search algorithm from the
582 while ( !_heap->empty() ) processNextNode();
585 /// \brief Executes the algorithm until \c dest is reached.
587 /// Executes the algorithm until \c dest is reached.
589 /// \pre init() must be called and at least one node should be added
590 /// with addSource() before using this function.
592 /// This method runs the %MaxCardinalitySearch algorithm from the source
594 void start(Node dest) {
595 while ( !_heap->empty() && _heap->top()!=dest ) processNextNode();
596 if ( !_heap->empty() ) finalizeNodeData(_heap->top(), _heap->prio());
599 /// \brief Executes the algorithm until a condition is met.
601 /// Executes the algorithm until a condition is met.
603 /// \pre init() must be called and at least one node should be added
604 /// with addSource() before using this function.
606 /// \param nm must be a bool (or convertible) node map. The algorithm
607 /// will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
608 template <typename NodeBoolMap>
609 void start(const NodeBoolMap &nm) {
610 while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
611 if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio());
614 /// \brief Runs the maximal cardinality search algorithm from node \c s.
616 /// This method runs the %MaxCardinalitySearch algorithm from a root
619 ///\note d.run(s) is just a shortcut of the following code.
631 /// \brief Runs the maximal cardinality search algorithm for the
634 /// This method runs the %MaxCardinalitySearch algorithm from all
635 /// unprocessed node of the graph.
637 ///\note d.run(s) is just a shortcut of the following code.
640 /// for (NodeIt it(graph); it != INVALID; ++it) {
641 /// if (!d.reached(it)) {
649 for (NodeIt it(*_graph); it != INVALID; ++it) {
659 /// \name Query Functions
660 /// The result of the maximum cardinality search algorithm can be
661 /// obtained using these functions.
663 /// Before the use of these functions, either run() or start() must be
668 /// \brief The cardinality of a node.
670 /// Returns the cardinality of a node.
671 /// \pre \ref run() must be called before using this function.
672 /// \warning If node \c v in unreachable from the root the return value
673 /// of this funcion is undefined.
674 Value cardinality(Node node) const { return (*_cardinality)[node]; }
676 /// \brief The current cardinality of a node.
678 /// Returns the current cardinality of a node.
679 /// \pre the given node should be reached but not processed
680 Value currentCardinality(Node node) const { return (*_heap)[node]; }
682 /// \brief Returns a reference to the NodeMap of cardinalities.
684 /// Returns a reference to the NodeMap of cardinalities. \pre \ref run()
685 /// must be called before using this function.
686 const CardinalityMap &cardinalityMap() const { return *_cardinality;}
688 /// \brief Checks if a node is reachable from the root.
690 /// Returns \c true if \c v is reachable from the root.
691 /// \warning The source nodes are inditated as unreached.
692 /// \pre \ref run() must be called before using this function.
693 bool reached(Node v) { return (*_heap_cross_ref)[v] != Heap::PRE_HEAP; }
695 /// \brief Checks if a node is processed.
697 /// Returns \c true if \c v is processed, i.e. the shortest
698 /// path to \c v has already found.
699 /// \pre \ref run() must be called before using this function.
700 bool processed(Node v) { return (*_heap_cross_ref)[v] == Heap::POST_HEAP; }
705 /// \brief Default traits class of NagamochiIbaraki class.
707 /// Default traits class of NagamochiIbaraki class.
708 /// \param Graph Graph type.
709 /// \param CapacityMap Type of length map.
710 template <typename _Graph, typename _CapacityMap>
711 struct NagamochiIbarakiDefaultTraits {
712 /// \brief The type of the capacity of the edges.
713 typedef typename _CapacityMap::Value Value;
715 /// The graph type the algorithm runs on.
716 typedef _Graph Graph;
718 /// The AuxGraph type which is an Graph
719 typedef ListUGraph AuxGraph;
721 /// \brief Instantiates a AuxGraph.
723 /// This function instantiates a \ref AuxGraph.
724 static AuxGraph *createAuxGraph() {
725 return new AuxGraph();
728 /// \brief The type of the map that stores the edge capacities.
730 /// The type of the map that stores the edge capacities.
731 /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
732 typedef _CapacityMap CapacityMap;
734 /// \brief Instantiates a CapacityMap.
736 /// This function instantiates a \ref CapacityMap.
738 static CapacityMap *createCapacityMap(const Graph& graph)
740 static CapacityMap *createCapacityMap(const Graph&)
743 throw UninitializedParameter();
746 /// \brief The CutValueMap type
748 /// The type of the map that stores the cut value of a node.
749 typedef AuxGraph::NodeMap<Value> AuxCutValueMap;
751 /// \brief Instantiates a AuxCutValueMap.
753 /// This function instantiates a \ref AuxCutValueMap.
754 static AuxCutValueMap *createAuxCutValueMap(const AuxGraph& graph) {
755 return new AuxCutValueMap(graph);
758 /// \brief The AuxCapacityMap type
760 /// The type of the map that stores the auxiliary edge capacities.
761 typedef AuxGraph::UEdgeMap<Value> AuxCapacityMap;
763 /// \brief Instantiates a AuxCapacityMap.
765 /// This function instantiates a \ref AuxCapacityMap.
766 static AuxCapacityMap *createAuxCapacityMap(const AuxGraph& graph) {
767 return new AuxCapacityMap(graph);
770 /// \brief The cross reference type used by heap.
772 /// The cross reference type used by heap.
773 /// Usually it is \c Graph::NodeMap<int>.
774 typedef AuxGraph::NodeMap<int> HeapCrossRef;
776 /// \brief Instantiates a HeapCrossRef.
778 /// This function instantiates a \ref HeapCrossRef.
779 /// \param graph is the graph, to which we would like to define the
781 static HeapCrossRef *createHeapCrossRef(const AuxGraph &graph) {
782 return new HeapCrossRef(graph);
785 /// \brief The heap type used by NagamochiIbaraki algorithm.
787 /// The heap type used by NagamochiIbaraki algorithm. It should
788 /// maximalize the priorities and the heap's key type is
789 /// the aux graph's node.
792 /// \sa NagamochiIbaraki
793 typedef typename _min_cut_bits
794 ::HeapSelector<CapacityMap>
795 ::template Selector<Value, HeapCrossRef>
798 /// \brief Instantiates a Heap.
800 /// This function instantiates a \ref Heap.
801 /// \param crossref The cross reference of the heap.
802 static Heap *createHeap(HeapCrossRef& crossref) {
803 return new Heap(crossref);
806 /// \brief Map from the AuxGraph's node type to the Graph's node type.
808 /// Map from the AuxGraph's node type to the Graph's node type.
809 typedef typename AuxGraph
810 ::template NodeMap<typename Graph::Node> NodeRefMap;
812 /// \brief Instantiates a NodeRefMap.
814 /// This function instantiates a \ref NodeRefMap.
815 static NodeRefMap *createNodeRefMap(const AuxGraph& graph) {
816 return new NodeRefMap(graph);
819 /// \brief Map from the Graph's node type to the Graph's node type.
821 /// Map from the Graph's node type to the Graph's node type.
822 typedef typename Graph
823 ::template NodeMap<typename Graph::Node> ListRefMap;
825 /// \brief Instantiates a ListRefMap.
827 /// This function instantiates a \ref ListRefMap.
828 static ListRefMap *createListRefMap(const Graph& graph) {
829 return new ListRefMap(graph);
835 /// \ingroup topology
837 /// \brief Calculates the minimum cut in an undirected graph.
839 /// Calculates the minimum cut in an undirected graph with the
840 /// Nagamochi-Ibaraki algorithm. The algorithm separates the graph's
841 /// nodes into two partitions with the minimum sum of edge capacities
842 /// between the two partitions. The algorithm can be used to test
843 /// the network reliability specifically to test how many links have
844 /// to be destroyed in the network to split it at least two
845 /// distinict subnetwork.
847 /// The complexity of the algorithm is \f$ O(ne\log(n)) \f$ but with
848 /// Fibonacci heap it can be decreased to \f$ O(ne+n^2\log(n)) \f$.
849 /// When capacity map is neutral then it uses BucketHeap which
850 /// results \f$ O(ne) \f$ time complexity.
852 /// \warning The value type of the capacity map should be able to hold
853 /// any cut value of the graph, otherwise the result can overflow.
855 template <typename _Graph, typename _CapacityMap, typename _Traits>
857 template <typename _Graph = ListUGraph,
858 typename _CapacityMap = typename _Graph::template UEdgeMap<int>,
860 = NagamochiIbarakiDefaultTraits<_Graph, _CapacityMap> >
862 class NagamochiIbaraki {
864 /// \brief \ref Exception for uninitialized parameters.
866 /// This error represents problems in the initialization
867 /// of the parameters of the algorithms.
868 class UninitializedParameter : public lemon::UninitializedParameter {
870 virtual const char* what() const throw() {
871 return "lemon::NagamochiIbaraki::UninitializedParameter";
878 typedef _Traits Traits;
879 /// The type of the underlying graph.
880 typedef typename Traits::Graph Graph;
882 /// The type of the capacity of the edges.
883 typedef typename Traits::CapacityMap::Value Value;
884 /// The type of the map that stores the edge capacities.
885 typedef typename Traits::CapacityMap CapacityMap;
886 /// The type of the aux graph
887 typedef typename Traits::AuxGraph AuxGraph;
888 /// The type of the aux capacity map
889 typedef typename Traits::AuxCapacityMap AuxCapacityMap;
890 /// The type of the aux cut value map
891 typedef typename Traits::AuxCutValueMap AuxCutValueMap;
892 /// The cross reference type used for the current heap.
893 typedef typename Traits::HeapCrossRef HeapCrossRef;
894 /// The heap type used by the max cardinality algorithm.
895 typedef typename Traits::Heap Heap;
896 /// The node refrefernces between the original and aux graph type.
897 typedef typename Traits::NodeRefMap NodeRefMap;
898 /// The list node refrefernces in the original graph type.
899 typedef typename Traits::ListRefMap ListRefMap;
903 ///\name Named template parameters
907 struct DefNeutralCapacityTraits : public Traits {
908 typedef ConstMap<typename Graph::UEdge, Const<int, 1> > CapacityMap;
909 static CapacityMap *createCapacityMap(const Graph&) {
910 return new CapacityMap();
913 /// \brief \ref named-templ-param "Named parameter" for setting
914 /// the capacity type to constMap<UEdge, int, 1>()
916 /// \ref named-templ-param "Named parameter" for setting
917 /// the capacity type to constMap<UEdge, int, 1>()
918 struct DefNeutralCapacity
919 : public NagamochiIbaraki<Graph, CapacityMap,
920 DefNeutralCapacityTraits> {
921 typedef NagamochiIbaraki<Graph, CapacityMap,
922 DefNeutralCapacityTraits> Create;
926 template <class H, class CR>
927 struct DefHeapTraits : public Traits {
928 typedef CR HeapCrossRef;
930 static HeapCrossRef *createHeapCrossRef(const AuxGraph &) {
931 throw UninitializedParameter();
933 static Heap *createHeap(HeapCrossRef &) {
934 throw UninitializedParameter();
937 /// \brief \ref named-templ-param "Named parameter" for setting heap
938 /// and cross reference type
940 /// \ref named-templ-param "Named parameter" for setting heap and cross
942 template <class H, class CR = typename Graph::template NodeMap<int> >
944 : public NagamochiIbaraki<Graph, CapacityMap,
945 DefHeapTraits<H, CR> > {
946 typedef NagamochiIbaraki< Graph, CapacityMap,
947 DefHeapTraits<H, CR> > Create;
950 template <class H, class CR>
951 struct DefStandardHeapTraits : public Traits {
952 typedef CR HeapCrossRef;
954 static HeapCrossRef *createHeapCrossRef(const AuxGraph &graph) {
955 return new HeapCrossRef(graph);
957 static Heap *createHeap(HeapCrossRef &crossref) {
958 return new Heap(crossref);
962 /// \brief \ref named-templ-param "Named parameter" for setting heap and
963 /// cross reference type with automatic allocation
965 /// \ref named-templ-param "Named parameter" for setting heap and cross
966 /// reference type. It can allocate the heap and the cross reference
967 /// object if the cross reference's constructor waits for the graph as
968 /// parameter and the heap's constructor waits for the cross reference.
969 template <class H, class CR = typename Graph::template NodeMap<int> >
970 struct DefStandardHeap
971 : public NagamochiIbaraki<Graph, CapacityMap,
972 DefStandardHeapTraits<H, CR> > {
973 typedef NagamochiIbaraki<Graph, CapacityMap,
974 DefStandardHeapTraits<H, CR> >
982 /// Pointer to the underlying graph.
984 /// Pointer to the capacity map
985 const CapacityMap *_capacity;
986 /// \brief Indicates if \ref _capacity is locally allocated
987 /// (\c true) or not.
990 /// Pointer to the aux graph.
991 AuxGraph *_aux_graph;
992 /// \brief Indicates if \ref _aux_graph is locally allocated
993 /// (\c true) or not.
994 bool local_aux_graph;
995 /// Pointer to the aux capacity map
996 AuxCapacityMap *_aux_capacity;
997 /// \brief Indicates if \ref _aux_capacity is locally allocated
998 /// (\c true) or not.
999 bool local_aux_capacity;
1000 /// Pointer to the aux cut value map
1001 AuxCutValueMap *_aux_cut_value;
1002 /// \brief Indicates if \ref _aux_cut_value is locally allocated
1003 /// (\c true) or not.
1004 bool local_aux_cut_value;
1005 /// Pointer to the heap cross references.
1006 HeapCrossRef *_heap_cross_ref;
1007 /// \brief Indicates if \ref _heap_cross_ref is locally allocated
1008 /// (\c true) or not.
1009 bool local_heap_cross_ref;
1010 /// Pointer to the heap.
1012 /// Indicates if \ref _heap is locally allocated (\c true) or not.
1015 /// The min cut value.
1017 /// The number of the nodes of the aux graph.
1019 /// The first and last node of the min cut in the next list.
1020 std::vector<typename Graph::Node> _cut;
1022 /// \brief The first and last element in the list associated
1023 /// to the aux graph node.
1024 NodeRefMap *_first, *_last;
1025 /// \brief The next node in the node lists.
1028 void createStructures() {
1030 local_capacity = true;
1031 _capacity = Traits::createCapacityMap(*_graph);
1034 local_aux_graph = true;
1035 _aux_graph = Traits::createAuxGraph();
1037 if(!_aux_capacity) {
1038 local_aux_capacity = true;
1039 _aux_capacity = Traits::createAuxCapacityMap(*_aux_graph);
1041 if(!_aux_cut_value) {
1042 local_aux_cut_value = true;
1043 _aux_cut_value = Traits::createAuxCutValueMap(*_aux_graph);
1046 _first = Traits::createNodeRefMap(*_aux_graph);
1047 _last = Traits::createNodeRefMap(*_aux_graph);
1049 _next = Traits::createListRefMap(*_graph);
1051 if (!_heap_cross_ref) {
1052 local_heap_cross_ref = true;
1053 _heap_cross_ref = Traits::createHeapCrossRef(*_aux_graph);
1057 _heap = Traits::createHeap(*_heap_cross_ref);
1061 void createAuxGraph() {
1062 typename Graph::template NodeMap<typename AuxGraph::Node> ref(*_graph);
1064 for (typename Graph::NodeIt n(*_graph); n != INVALID; ++n) {
1065 _next->set(n, INVALID);
1066 typename AuxGraph::Node node = _aux_graph->addNode();
1067 _first->set(node, n);
1068 _last->set(node, n);
1072 typename AuxGraph::template NodeMap<typename AuxGraph::UEdge>
1073 edges(*_aux_graph, INVALID);
1075 for (typename Graph::NodeIt n(*_graph); n != INVALID; ++n) {
1076 for (typename Graph::IncEdgeIt e(*_graph, n); e != INVALID; ++e) {
1077 typename Graph::Node tn = _graph->runningNode(e);
1078 if (n < tn || n == tn) continue;
1079 if (edges[ref[tn]] != INVALID) {
1081 (*_aux_capacity)[edges[ref[tn]]] + (*_capacity)[e];
1082 _aux_capacity->set(edges[ref[tn]], value);
1084 edges.set(ref[tn], _aux_graph->addEdge(ref[n], ref[tn]));
1085 Value value = (*_capacity)[e];
1086 _aux_capacity->set(edges[ref[tn]], value);
1089 for (typename Graph::IncEdgeIt e(*_graph, n); e != INVALID; ++e) {
1090 typename Graph::Node tn = _graph->runningNode(e);
1091 edges.set(ref[tn], INVALID);
1095 _cut.resize(1, INVALID);
1096 _min_cut = std::numeric_limits<Value>::max();
1097 for (typename AuxGraph::NodeIt n(*_aux_graph); n != INVALID; ++n) {
1099 for (typename AuxGraph::IncEdgeIt e(*_aux_graph, n);
1100 e != INVALID; ++e) {
1101 value += (*_aux_capacity)[e];
1103 if (_min_cut > value) {
1105 _cut[0] = (*_first)[n];
1107 (*_aux_cut_value)[n] = value;
1114 typedef NagamochiIbaraki Create;
1117 /// \brief Constructor.
1119 ///\param graph the graph the algorithm will run on.
1120 ///\param capacity the capacity map used by the algorithm.
1121 NagamochiIbaraki(const Graph& graph, const CapacityMap& capacity)
1123 _capacity(&capacity), local_capacity(false),
1124 _aux_graph(0), local_aux_graph(false),
1125 _aux_capacity(0), local_aux_capacity(false),
1126 _aux_cut_value(0), local_aux_cut_value(false),
1127 _heap_cross_ref(0), local_heap_cross_ref(false),
1128 _heap(0), local_heap(false),
1129 _first(0), _last(0), _next(0) {}
1131 /// \brief Constructor.
1133 /// This constructor can be used only when the Traits class
1134 /// defines how can we instantiate a local capacity map.
1135 /// If the DefNeutralCapacity used the algorithm automatically
1136 /// construct the capacity map.
1138 ///\param graph the graph the algorithm will run on.
1139 NagamochiIbaraki(const Graph& graph)
1141 _capacity(0), local_capacity(false),
1142 _aux_graph(0), local_aux_graph(false),
1143 _aux_capacity(0), local_aux_capacity(false),
1144 _aux_cut_value(0), local_aux_cut_value(false),
1145 _heap_cross_ref(0), local_heap_cross_ref(false),
1146 _heap(0), local_heap(false),
1147 _first(0), _last(0), _next(0) {}
1149 /// \brief Destructor.
1152 ~NagamochiIbaraki() {
1153 if (local_heap) delete _heap;
1154 if (local_heap_cross_ref) delete _heap_cross_ref;
1155 if (_first) delete _first;
1156 if (_last) delete _last;
1157 if (_next) delete _next;
1158 if (local_aux_capacity) delete _aux_capacity;
1159 if (local_aux_cut_value) delete _aux_cut_value;
1160 if (local_aux_graph) delete _aux_graph;
1161 if (local_capacity) delete _capacity;
1164 /// \brief Sets the heap and the cross reference used by algorithm.
1166 /// Sets the heap and the cross reference used by algorithm.
1167 /// If you don't use this function before calling \ref run(),
1168 /// it will allocate one. The destuctor deallocates this
1169 /// automatically allocated heap and cross reference, of course.
1170 /// \return <tt> (*this) </tt>
1171 NagamochiIbaraki &heap(Heap& heap, HeapCrossRef &crossRef)
1173 if (local_heap_cross_ref) {
1174 delete _heap_cross_ref;
1175 local_heap_cross_ref=false;
1177 _heap_cross_ref = &crossRef;
1186 /// \brief Sets the aux graph.
1188 /// Sets the aux graph used by algorithm.
1189 /// If you don't use this function before calling \ref run(),
1190 /// it will allocate one. The destuctor deallocates this
1191 /// automatically allocated graph, of course.
1192 /// \return <tt> (*this) </tt>
1193 NagamochiIbaraki &auxGraph(AuxGraph& aux_graph)
1195 if(local_aux_graph) {
1197 local_aux_graph=false;
1199 _aux_graph = &aux_graph;
1203 /// \brief Sets the aux capacity map.
1205 /// Sets the aux capacity map used by algorithm.
1206 /// If you don't use this function before calling \ref run(),
1207 /// it will allocate one. The destuctor deallocates this
1208 /// automatically allocated graph, of course.
1209 /// \return <tt> (*this) </tt>
1210 NagamochiIbaraki &auxCapacityMap(AuxCapacityMap& aux_capacity_map)
1212 if(local_aux_capacity) {
1213 delete _aux_capacity;
1214 local_aux_capacity=false;
1216 _aux_capacity = &aux_capacity_map;
1220 /// \name Execution control
1221 /// The simplest way to execute the algorithm is to use
1222 /// one of the member functions called \c run().
1224 /// If you need more control on the execution,
1225 /// first you must call \ref init() and then call the start()
1226 /// or proper times the processNextPhase() member functions.
1230 /// \brief Initializes the internal data structures.
1232 /// Initializes the internal data structures.
1234 _node_num = countNodes(*_graph);
1242 typename AuxGraph::Node source, target;
1246 struct EdgeInfoLess {
1247 bool operator()(const EdgeInfo& left, const EdgeInfo& right) const {
1248 return (left.source < right.source) ||
1249 (left.source == right.source && left.target < right.target);
1256 /// \brief Processes the next phase
1258 /// Processes the next phase in the algorithm. The function should
1259 /// be called at most countNodes(graph) - 1 times to get surely
1260 /// the min cut in the graph.
1262 ///\return %True when the algorithm finished.
1263 bool processNextPhase() {
1264 if (_node_num <= 1) return true;
1266 typedef typename AuxGraph::Node Node;
1267 typedef typename AuxGraph::NodeIt NodeIt;
1268 typedef typename AuxGraph::UEdge UEdge;
1269 typedef typename AuxGraph::UEdgeIt UEdgeIt;
1270 typedef typename AuxGraph::IncEdgeIt IncEdgeIt;
1272 typename AuxGraph::template UEdgeMap<Value> _edge_cut(*_aux_graph);
1275 for (NodeIt n(*_aux_graph); n != INVALID; ++n) {
1276 _heap_cross_ref->set(n, Heap::PRE_HEAP);
1279 std::vector<Node> nodes;
1280 nodes.reserve(_node_num);
1284 Value emc = std::numeric_limits<Value>::max();
1286 _heap->push(typename AuxGraph::NodeIt(*_aux_graph), 0);
1287 while (!_heap->empty()) {
1288 Node node = _heap->top();
1289 Value value = _heap->prio();
1292 for (typename AuxGraph::IncEdgeIt e(*_aux_graph, node);
1293 e != INVALID; ++e) {
1294 Node tn = _aux_graph->runningNode(e);
1295 switch (_heap->state(tn)) {
1296 case Heap::PRE_HEAP:
1297 _heap->push(tn, (*_aux_capacity)[e]);
1298 _edge_cut[e] = (*_heap)[tn];
1301 _heap->decrease(tn, (*_aux_capacity)[e] + (*_heap)[tn]);
1302 _edge_cut[e] = (*_heap)[tn];
1304 case Heap::POST_HEAP:
1309 alpha += (*_aux_cut_value)[node];
1312 nodes.push_back(node);
1313 if (!_heap->empty()) {
1321 if ((int)nodes.size() < _node_num) {
1322 _aux_graph->clear();
1325 for (int i = 0; i < (int)nodes.size(); ++i) {
1326 typename Graph::Node n = (*_first)[nodes[i]];
1327 while (n != INVALID) {
1336 if (emc < _min_cut) {
1338 for (int i = 0; i < sep; ++i) {
1339 typename Graph::Node n = (*_first)[nodes[i]];
1340 while (n != INVALID) {
1348 typedef typename AuxGraph::template NodeMap<int> UfeCr;
1349 UfeCr ufecr(*_aux_graph);
1350 typedef UnionFindEnum<UfeCr> Ufe;
1353 for (typename AuxGraph::NodeIt n(*_aux_graph); n != INVALID; ++n) {
1357 for (typename AuxGraph::UEdgeIt e(*_aux_graph); e != INVALID; ++e) {
1358 if (_edge_cut[e] >= emc) {
1359 ufe.join(_aux_graph->source(e), _aux_graph->target(e));
1363 if (ufe.size((typename Ufe::ClassIt)(ufe)) == _node_num) {
1364 _aux_graph->clear();
1369 std::vector<typename AuxGraph::Node> remnodes;
1371 typename AuxGraph::template NodeMap<UEdge> edges(*_aux_graph, INVALID);
1372 for (typename Ufe::ClassIt c(ufe); c != INVALID; ++c) {
1373 if (ufe.size(c) == 1) continue;
1374 for (typename Ufe::ItemIt r(ufe, c); r != INVALID; ++r) {
1375 if ((Node)r == (Node)c) continue;
1376 _next->set((*_last)[c], (*_first)[r]);
1377 _last->set(c, (*_last)[r]);
1378 remnodes.push_back(r);
1383 std::vector<EdgeInfo> addedges;
1384 std::vector<UEdge> remedges;
1386 for (typename AuxGraph::UEdgeIt e(*_aux_graph);
1387 e != INVALID; ++e) {
1388 Node sn = ufe.find(_aux_graph->source(e));
1389 Node tn = ufe.find(_aux_graph->target(e));
1390 if ((ufe.size(sn) == 1 && ufe.size(tn) == 1)) {
1394 remedges.push_back(e);
1405 info.capacity = (*_aux_capacity)[e];
1406 addedges.push_back(info);
1407 remedges.push_back(e);
1410 for (int i = 0; i < (int)remedges.size(); ++i) {
1411 _aux_graph->erase(remedges[i]);
1414 sort(addedges.begin(), addedges.end(), EdgeInfoLess());
1418 while (i < (int)addedges.size()) {
1419 Node sn = addedges[i].source;
1420 Node tn = addedges[i].target;
1421 Value ec = addedges[i].capacity;
1423 while (i < (int)addedges.size() &&
1424 sn == addedges[i].source && tn == addedges[i].target) {
1425 ec += addedges[i].capacity;
1428 typename AuxGraph::UEdge ne = _aux_graph->addEdge(sn, tn);
1429 (*_aux_capacity)[ne] = ec;
1433 for (typename Ufe::ClassIt c(ufe); c != INVALID; ++c) {
1434 if (ufe.size(c) == 1) continue;
1436 for (typename AuxGraph::IncEdgeIt e(*_aux_graph, c);
1437 e != INVALID; ++e) {
1438 cutvalue += (*_aux_capacity)[e];
1441 (*_aux_cut_value)[c] = cutvalue;
1445 for (int i = 0; i < (int)remnodes.size(); ++i) {
1446 _aux_graph->erase(remnodes[i]);
1449 return _node_num == 1;
1452 /// \brief Executes the algorithm.
1454 /// Executes the algorithm.
1456 /// \pre init() must be called
1458 while (!processNextPhase());
1462 /// \brief Runs %NagamochiIbaraki algorithm.
1464 /// This method runs the %Min cut algorithm
1466 /// \note mc.run(s) is just a shortcut of the following code.
1478 /// \name Query Functions
1480 /// The result of the %NagamochiIbaraki
1481 /// algorithm can be obtained using these functions.\n
1482 /// Before the use of these functions, either run() or start()
1487 /// \brief Returns the min cut value.
1489 /// Returns the min cut value if the algorithm finished.
1490 /// After the first processNextPhase() it is a value of a
1491 /// valid cut in the graph.
1492 Value minCut() const {
1496 /// \brief Returns a min cut in a NodeMap.
1498 /// It sets the nodes of one of the two partitions to true in
1499 /// the given BoolNodeMap. The map contains a valid cut if the
1500 /// map have been set false previously.
1501 template <typename NodeMap>
1502 Value quickMinCut(NodeMap& nodeMap) const {
1503 for (int i = 0; i < (int)_cut.size(); ++i) {
1504 nodeMap.set(_cut[i], true);
1509 /// \brief Returns a min cut in a NodeMap.
1511 /// It sets the nodes of one of the two partitions to true and
1512 /// the other partition to false. The function first set all of the
1513 /// nodes to false and after it call the quickMinCut() member.
1514 template <typename NodeMap>
1515 Value minCut(NodeMap& nodeMap) const {
1516 for (typename Graph::NodeIt it(*_graph); it != INVALID; ++it) {
1517 nodeMap.set(it, false);
1519 quickMinCut(nodeMap);
1523 /// \brief Returns a min cut in an EdgeMap.
1525 /// If an undirected edge is in a min cut then it will be
1526 /// set to true and the others will be set to false in the given map.
1527 template <typename EdgeMap>
1528 Value cutEdges(EdgeMap& edgeMap) const {
1529 typename Graph::template NodeMap<bool> cut(*_graph, false);
1531 for (typename Graph::EdgeIt it(*_graph); it != INVALID; ++it) {
1532 edgeMap.set(it, cut[_graph->source(it)] ^ cut[_graph->target(it)]);