Consider the CPXMIP_OPTIMAL_TOL status as OPTIMAL too.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2007
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_NAGAMOCHI_IBARAKI_H
20 #define LEMON_NAGAMOCHI_IBARAKI_H
25 /// \brief Maximum cardinality search and minimum cut in undirected
28 #include <lemon/list_graph.h>
29 #include <lemon/bin_heap.h>
30 #include <lemon/bucket_heap.h>
32 #include <lemon/unionfind.h>
33 #include <lemon/topology.h>
35 #include <lemon/bits/invalid.h>
36 #include <lemon/error.h>
37 #include <lemon/maps.h>
41 #include <lemon/graph_writer.h>
42 #include <lemon/time_measure.h>
46 namespace _min_cut_bits {
48 template <typename CapacityMap>
50 template <typename Value, typename Ref>
52 typedef BinHeap<Value, Ref, std::greater<Value> > Heap;
56 template <typename CapacityKey>
57 struct HeapSelector<ConstMap<CapacityKey, Const<int, 1> > > {
58 template <typename Value, typename Ref>
60 typedef BucketHeap<Ref, false > Heap;
66 /// \brief Default traits class of MaxCardinalitySearch class.
68 /// Default traits class of MaxCardinalitySearch class.
69 /// \param Graph Graph type.
70 /// \param CapacityMap Type of length map.
71 template <typename _Graph, typename _CapacityMap>
72 struct MaxCardinalitySearchDefaultTraits {
73 /// The graph type the algorithm runs on.
76 /// \brief The type of the map that stores the edge capacities.
78 /// The type of the map that stores the edge capacities.
79 /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
80 typedef _CapacityMap CapacityMap;
82 /// \brief The type of the capacity of the edges.
83 typedef typename CapacityMap::Value Value;
85 /// \brief The cross reference type used by heap.
87 /// The cross reference type used by heap.
88 /// Usually it is \c Graph::NodeMap<int>.
89 typedef typename Graph::template NodeMap<int> HeapCrossRef;
91 /// \brief Instantiates a HeapCrossRef.
93 /// This function instantiates a \ref HeapCrossRef.
94 /// \param graph is the graph, to which we would like to define the
96 static HeapCrossRef *createHeapCrossRef(const Graph &graph) {
97 return new HeapCrossRef(graph);
100 /// \brief The heap type used by MaxCardinalitySearch algorithm.
102 /// The heap type used by MaxCardinalitySearch algorithm. It should
103 /// maximalize the priorities. The default heap type is
104 /// the \ref BinHeap, but it is specialized when the
105 /// CapacityMap is ConstMap<Graph::Node, Const<int, 1> >
108 /// \sa MaxCardinalitySearch
109 typedef typename _min_cut_bits
110 ::HeapSelector<CapacityMap>
111 ::template Selector<Value, HeapCrossRef>
114 /// \brief Instantiates a Heap.
116 /// This function instantiates a \ref Heap.
117 /// \param crossref The cross reference of the heap.
118 static Heap *createHeap(HeapCrossRef& crossref) {
119 return new Heap(crossref);
122 /// \brief The type of the map that stores whether a nodes is processed.
124 /// The type of the map that stores whether a nodes is processed.
125 /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
126 /// By default it is a NullMap.
127 typedef NullMap<typename Graph::Node, bool> ProcessedMap;
129 /// \brief Instantiates a ProcessedMap.
131 /// This function instantiates a \ref ProcessedMap.
132 /// \param graph is the graph, to which
133 /// we would like to define the \ref ProcessedMap
135 static ProcessedMap *createProcessedMap(const Graph &graph)
137 static ProcessedMap *createProcessedMap(const Graph &)
140 return new ProcessedMap();
143 /// \brief The type of the map that stores the cardinalties of the nodes.
145 /// The type of the map that stores the cardinalities of the nodes.
146 /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
147 typedef typename Graph::template NodeMap<Value> CardinalityMap;
149 /// \brief Instantiates a CardinalityMap.
151 /// This function instantiates a \ref CardinalityMap.
152 /// \param graph is the graph, to which we would like to define the \ref
154 static CardinalityMap *createCardinalityMap(const Graph &graph) {
155 return new CardinalityMap(graph);
163 /// \brief Maximum Cardinality Search algorithm class.
165 /// This class provides an efficient implementation of Maximum Cardinality
166 /// Search algorithm. The maximum cardinality search chooses first time any
167 /// node of the graph. Then every time it chooses the node which is connected
168 /// to the processed nodes at most in the sum of capacities on the out
169 /// edges. If there is a cut in the graph the algorithm should choose
170 /// again any unprocessed node of the graph. Each node cardinality is
171 /// the sum of capacities on the out edges to the nodes which are processed
172 /// before the given node.
174 /// The edge capacities are passed to the algorithm using a
175 /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
176 /// kind of capacity.
178 /// The type of the capacity is determined by the \ref
179 /// concepts::ReadMap::Value "Value" of the capacity map.
181 /// It is also possible to change the underlying priority heap.
184 /// \param _Graph The graph type the algorithm runs on. The default value
185 /// is \ref ListGraph. The value of Graph is not used directly by
186 /// the search algorithm, it is only passed to
187 /// \ref MaxCardinalitySearchDefaultTraits.
188 /// \param _CapacityMap This read-only EdgeMap determines the capacities of
189 /// the edges. It is read once for each edge, so the map may involve in
190 /// relatively time consuming process to compute the edge capacity if
191 /// it is necessary. The default map type is \ref
192 /// concepts::Graph::EdgeMap "Graph::EdgeMap<int>". The value
193 /// of CapacityMap is not used directly by search algorithm, it is only
194 /// passed to \ref MaxCardinalitySearchDefaultTraits.
195 /// \param _Traits Traits class to set various data types used by the
196 /// algorithm. The default traits class is
197 /// \ref MaxCardinalitySearchDefaultTraits
198 /// "MaxCardinalitySearchDefaultTraits<_Graph, _CapacityMap>".
199 /// See \ref MaxCardinalitySearchDefaultTraits
200 /// for the documentation of a MaxCardinalitySearch traits class.
202 /// \author Balazs Dezso
205 template <typename _Graph, typename _CapacityMap, typename _Traits>
207 template <typename _Graph = ListUGraph,
208 typename _CapacityMap = typename _Graph::template EdgeMap<int>,
210 MaxCardinalitySearchDefaultTraits<_Graph, _CapacityMap> >
212 class MaxCardinalitySearch {
214 /// \brief \ref Exception for uninitialized parameters.
216 /// This error represents problems in the initialization
217 /// of the parameters of the algorithms.
218 class UninitializedParameter : public lemon::UninitializedParameter {
220 virtual const char* what() const throw() {
221 return "lemon::MaxCardinalitySearch::UninitializedParameter";
225 typedef _Traits Traits;
226 ///The type of the underlying graph.
227 typedef typename Traits::Graph Graph;
229 ///The type of the capacity of the edges.
230 typedef typename Traits::CapacityMap::Value Value;
231 ///The type of the map that stores the edge capacities.
232 typedef typename Traits::CapacityMap CapacityMap;
233 ///The type of the map indicating if a node is processed.
234 typedef typename Traits::ProcessedMap ProcessedMap;
235 ///The type of the map that stores the cardinalities of the nodes.
236 typedef typename Traits::CardinalityMap CardinalityMap;
237 ///The cross reference type used for the current heap.
238 typedef typename Traits::HeapCrossRef HeapCrossRef;
239 ///The heap type used by the algorithm. It maximize the priorities.
240 typedef typename Traits::Heap Heap;
242 /// Pointer to the underlying graph.
244 /// Pointer to the capacity map
245 const CapacityMap *_capacity;
246 ///Pointer to the map of cardinality.
247 CardinalityMap *_cardinality;
248 ///Indicates if \ref _cardinality is locally allocated (\c true) or not.
249 bool local_cardinality;
250 ///Pointer to the map of processed status of the nodes.
251 ProcessedMap *_processed;
252 ///Indicates if \ref _processed is locally allocated (\c true) or not.
253 bool local_processed;
254 ///Pointer to the heap cross references.
255 HeapCrossRef *_heap_cross_ref;
256 ///Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not.
257 bool local_heap_cross_ref;
258 ///Pointer to the heap.
260 ///Indicates if \ref _heap is locally allocated (\c true) or not.
265 typedef MaxCardinalitySearch Create;
267 ///\name Named template parameters
272 struct DefCardinalityMapTraits : public Traits {
273 typedef T CardinalityMap;
274 static CardinalityMap *createCardinalityMap(const Graph &)
276 throw UninitializedParameter();
279 /// \brief \ref named-templ-param "Named parameter" for setting
280 /// CardinalityMap type
282 /// \ref named-templ-param "Named parameter" for setting CardinalityMap
285 struct DefCardinalityMap
286 : public MaxCardinalitySearch<Graph, CapacityMap,
287 DefCardinalityMapTraits<T> > {
288 typedef MaxCardinalitySearch<Graph, CapacityMap,
289 DefCardinalityMapTraits<T> > Create;
293 struct DefProcessedMapTraits : public Traits {
294 typedef T ProcessedMap;
295 static ProcessedMap *createProcessedMap(const Graph &) {
296 throw UninitializedParameter();
299 /// \brief \ref named-templ-param "Named parameter" for setting
300 /// ProcessedMap type
302 /// \ref named-templ-param "Named parameter" for setting ProcessedMap type
305 struct DefProcessedMap
306 : public MaxCardinalitySearch<Graph, CapacityMap,
307 DefProcessedMapTraits<T> > {
308 typedef MaxCardinalitySearch<Graph, CapacityMap,
309 DefProcessedMapTraits<T> > Create;
312 template <class H, class CR>
313 struct DefHeapTraits : public Traits {
314 typedef CR HeapCrossRef;
316 static HeapCrossRef *createHeapCrossRef(const Graph &) {
317 throw UninitializedParameter();
319 static Heap *createHeap(HeapCrossRef &) {
320 throw UninitializedParameter();
323 /// \brief \ref named-templ-param "Named parameter" for setting heap
324 /// and cross reference type
326 /// \ref named-templ-param "Named parameter" for setting heap and cross
328 template <class H, class CR = typename Graph::template NodeMap<int> >
330 : public MaxCardinalitySearch<Graph, CapacityMap,
331 DefHeapTraits<H, CR> > {
332 typedef MaxCardinalitySearch< Graph, CapacityMap,
333 DefHeapTraits<H, CR> > Create;
336 template <class H, class CR>
337 struct DefStandardHeapTraits : public Traits {
338 typedef CR HeapCrossRef;
340 static HeapCrossRef *createHeapCrossRef(const Graph &graph) {
341 return new HeapCrossRef(graph);
343 static Heap *createHeap(HeapCrossRef &crossref) {
344 return new Heap(crossref);
348 /// \brief \ref named-templ-param "Named parameter" for setting heap and
349 /// cross reference type with automatic allocation
351 /// \ref named-templ-param "Named parameter" for setting heap and cross
352 /// reference type. It can allocate the heap and the cross reference
353 /// object if the cross reference's constructor waits for the graph as
354 /// parameter and the heap's constructor waits for the cross reference.
355 template <class H, class CR = typename Graph::template NodeMap<int> >
356 struct DefStandardHeap
357 : public MaxCardinalitySearch<Graph, CapacityMap,
358 DefStandardHeapTraits<H, CR> > {
359 typedef MaxCardinalitySearch<Graph, CapacityMap,
360 DefStandardHeapTraits<H, CR> >
369 MaxCardinalitySearch() {}
373 /// \brief Constructor.
375 ///\param graph the graph the algorithm will run on.
376 ///\param capacity the capacity map used by the algorithm.
377 MaxCardinalitySearch(const Graph& graph, const CapacityMap& capacity) :
378 _graph(&graph), _capacity(&capacity),
379 _cardinality(0), local_cardinality(false),
380 _processed(0), local_processed(false),
381 _heap_cross_ref(0), local_heap_cross_ref(false),
382 _heap(0), local_heap(false)
385 /// \brief Destructor.
386 ~MaxCardinalitySearch() {
387 if(local_cardinality) delete _cardinality;
388 if(local_processed) delete _processed;
389 if(local_heap_cross_ref) delete _heap_cross_ref;
390 if(local_heap) delete _heap;
393 /// \brief Sets the capacity map.
395 /// Sets the capacity map.
396 /// \return <tt> (*this) </tt>
397 MaxCardinalitySearch &capacityMap(const CapacityMap &m) {
402 /// \brief Sets the map storing the cardinalities calculated by the
405 /// Sets the map storing the cardinalities calculated by the algorithm.
406 /// If you don't use this function before calling \ref run(),
407 /// it will allocate one. The destuctor deallocates this
408 /// automatically allocated map, of course.
409 /// \return <tt> (*this) </tt>
410 MaxCardinalitySearch &cardinalityMap(CardinalityMap &m) {
411 if(local_cardinality) {
413 local_cardinality=false;
419 /// \brief Sets the map storing the processed nodes.
421 /// Sets the map storing the processed nodes.
422 /// If you don't use this function before calling \ref run(),
423 /// it will allocate one. The destuctor deallocates this
424 /// automatically allocated map, of course.
425 /// \return <tt> (*this) </tt>
426 MaxCardinalitySearch &processedMap(ProcessedMap &m)
428 if(local_processed) {
430 local_processed=false;
436 /// \brief Sets the heap and the cross reference used by algorithm.
438 /// Sets the heap and the cross reference used by algorithm.
439 /// If you don't use this function before calling \ref run(),
440 /// it will allocate one. The destuctor deallocates this
441 /// automatically allocated map, of course.
442 /// \return <tt> (*this) </tt>
443 MaxCardinalitySearch &heap(Heap& hp, HeapCrossRef &cr) {
444 if(local_heap_cross_ref) {
445 delete _heap_cross_ref;
446 local_heap_cross_ref = false;
448 _heap_cross_ref = &cr;
459 typedef typename Graph::Node Node;
460 typedef typename Graph::NodeIt NodeIt;
461 typedef typename Graph::Edge Edge;
462 typedef typename Graph::InEdgeIt InEdgeIt;
466 local_cardinality = true;
467 _cardinality = Traits::createCardinalityMap(*_graph);
470 local_processed = true;
471 _processed = Traits::createProcessedMap(*_graph);
473 if (!_heap_cross_ref) {
474 local_heap_cross_ref = true;
475 _heap_cross_ref = Traits::createHeapCrossRef(*_graph);
479 _heap = Traits::createHeap(*_heap_cross_ref);
483 void finalizeNodeData(Node node, Value capacity) {
484 _processed->set(node, true);
485 _cardinality->set(node, capacity);
489 /// \name Execution control
490 /// The simplest way to execute the algorithm is to use
491 /// one of the member functions called \c run(...).
493 /// If you need more control on the execution,
494 /// first you must call \ref init(), then you can add several source nodes
495 /// with \ref addSource().
496 /// Finally \ref start() will perform the actual path
501 /// \brief Initializes the internal data structures.
503 /// Initializes the internal data structures.
507 for (NodeIt it(*_graph) ; it != INVALID ; ++it) {
508 _processed->set(it, false);
509 _heap_cross_ref->set(it, Heap::PRE_HEAP);
513 /// \brief Adds a new source node.
515 /// Adds a new source node to the priority heap.
517 /// It checks if the node has not yet been added to the heap.
518 void addSource(Node source, Value capacity = 0) {
519 if(_heap->state(source) == Heap::PRE_HEAP) {
520 _heap->push(source, capacity);
524 /// \brief Processes the next node in the priority heap
526 /// Processes the next node in the priority heap.
528 /// \return The processed node.
530 /// \warning The priority heap must not be empty!
531 Node processNextNode() {
532 Node node = _heap->top();
533 finalizeNodeData(node, _heap->prio());
536 for (InEdgeIt it(*_graph, node); it != INVALID; ++it) {
537 Node source = _graph->source(it);
538 switch (_heap->state(source)) {
540 _heap->push(source, (*_capacity)[it]);
543 _heap->decrease(source, (*_heap)[source] + (*_capacity)[it]);
545 case Heap::POST_HEAP:
552 /// \brief Next node to be processed.
554 /// Next node to be processed.
556 /// \return The next node to be processed or INVALID if the
557 /// priority heap is empty.
559 return _heap->empty() ? _heap->top() : INVALID;
562 /// \brief Returns \c false if there are nodes
563 /// to be processed in the priority heap
565 /// Returns \c false if there are nodes
566 /// to be processed in the priority heap
567 bool emptyQueue() { return _heap->empty(); }
568 /// \brief Returns the number of the nodes to be processed
569 /// in the priority heap
571 /// Returns the number of the nodes to be processed in the priority heap
572 int queueSize() { return _heap->size(); }
574 /// \brief Executes the algorithm.
576 /// Executes the algorithm.
578 ///\pre init() must be called and at least one node should be added
579 /// with addSource() before using this function.
581 /// This method runs the Maximum Cardinality Search algorithm from the
584 while ( !_heap->empty() ) processNextNode();
587 /// \brief Executes the algorithm until \c dest is reached.
589 /// Executes the algorithm until \c dest is reached.
591 /// \pre init() must be called and at least one node should be added
592 /// with addSource() before using this function.
594 /// This method runs the %MaxCardinalitySearch algorithm from the source
596 void start(Node dest) {
597 while ( !_heap->empty() && _heap->top()!=dest ) processNextNode();
598 if ( !_heap->empty() ) finalizeNodeData(_heap->top(), _heap->prio());
601 /// \brief Executes the algorithm until a condition is met.
603 /// Executes the algorithm until a condition is met.
605 /// \pre init() must be called and at least one node should be added
606 /// with addSource() before using this function.
608 /// \param nm must be a bool (or convertible) node map. The algorithm
609 /// will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
610 template <typename NodeBoolMap>
611 void start(const NodeBoolMap &nm) {
612 while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
613 if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio());
616 /// \brief Runs the maximal cardinality search algorithm from node \c s.
618 /// This method runs the %MaxCardinalitySearch algorithm from a root
621 ///\note d.run(s) is just a shortcut of the following code.
633 /// \brief Runs the maximal cardinality search algorithm for the
636 /// This method runs the %MaxCardinalitySearch algorithm from all
637 /// unprocessed node of the graph.
639 ///\note d.run(s) is just a shortcut of the following code.
642 /// for (NodeIt it(graph); it != INVALID; ++it) {
643 /// if (!d.reached(it)) {
651 for (NodeIt it(*_graph); it != INVALID; ++it) {
661 /// \name Query Functions
662 /// The result of the maximum cardinality search algorithm can be
663 /// obtained using these functions.
665 /// Before the use of these functions, either run() or start() must be
670 /// \brief The cardinality of a node.
672 /// Returns the cardinality of a node.
673 /// \pre \ref run() must be called before using this function.
674 /// \warning If node \c v in unreachable from the root the return value
675 /// of this funcion is undefined.
676 Value cardinality(Node node) const { return (*_cardinality)[node]; }
678 /// \brief The current cardinality of a node.
680 /// Returns the current cardinality of a node.
681 /// \pre the given node should be reached but not processed
682 Value currentCardinality(Node node) const { return (*_heap)[node]; }
684 /// \brief Returns a reference to the NodeMap of cardinalities.
686 /// Returns a reference to the NodeMap of cardinalities. \pre \ref run()
687 /// must be called before using this function.
688 const CardinalityMap &cardinalityMap() const { return *_cardinality;}
690 /// \brief Checks if a node is reachable from the root.
692 /// Returns \c true if \c v is reachable from the root.
693 /// \warning The source nodes are inditated as unreached.
694 /// \pre \ref run() must be called before using this function.
695 bool reached(Node v) { return (*_heap_cross_ref)[v] != Heap::PRE_HEAP; }
697 /// \brief Checks if a node is processed.
699 /// Returns \c true if \c v is processed, i.e. the shortest
700 /// path to \c v has already found.
701 /// \pre \ref run() must be called before using this function.
702 bool processed(Node v) { return (*_heap_cross_ref)[v] == Heap::POST_HEAP; }
707 /// \brief Default traits class of NagamochiIbaraki class.
709 /// Default traits class of NagamochiIbaraki class.
710 /// \param Graph Graph type.
711 /// \param CapacityMap Type of length map.
712 template <typename _Graph, typename _CapacityMap>
713 struct NagamochiIbarakiDefaultTraits {
714 /// \brief The type of the capacity of the edges.
715 typedef typename _CapacityMap::Value Value;
717 /// The graph type the algorithm runs on.
718 typedef _Graph Graph;
720 /// The AuxGraph type which is an Graph
721 typedef ListUGraph AuxGraph;
723 /// \brief Instantiates a AuxGraph.
725 /// This function instantiates a \ref AuxGraph.
726 static AuxGraph *createAuxGraph() {
727 return new AuxGraph();
730 /// \brief The type of the map that stores the edge capacities.
732 /// The type of the map that stores the edge capacities.
733 /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
734 typedef _CapacityMap CapacityMap;
736 /// \brief Instantiates a CapacityMap.
738 /// This function instantiates a \ref CapacityMap.
740 static CapacityMap *createCapacityMap(const Graph& graph)
742 static CapacityMap *createCapacityMap(const Graph&)
745 throw UninitializedParameter();
748 /// \brief The CutValueMap type
750 /// The type of the map that stores the cut value of a node.
751 typedef AuxGraph::NodeMap<Value> AuxCutValueMap;
753 /// \brief Instantiates a AuxCutValueMap.
755 /// This function instantiates a \ref AuxCutValueMap.
756 static AuxCutValueMap *createAuxCutValueMap(const AuxGraph& graph) {
757 return new AuxCutValueMap(graph);
760 /// \brief The AuxCapacityMap type
762 /// The type of the map that stores the auxiliary edge capacities.
763 typedef AuxGraph::UEdgeMap<Value> AuxCapacityMap;
765 /// \brief Instantiates a AuxCapacityMap.
767 /// This function instantiates a \ref AuxCapacityMap.
768 static AuxCapacityMap *createAuxCapacityMap(const AuxGraph& graph) {
769 return new AuxCapacityMap(graph);
772 /// \brief The cross reference type used by heap.
774 /// The cross reference type used by heap.
775 /// Usually it is \c Graph::NodeMap<int>.
776 typedef AuxGraph::NodeMap<int> HeapCrossRef;
778 /// \brief Instantiates a HeapCrossRef.
780 /// This function instantiates a \ref HeapCrossRef.
781 /// \param graph is the graph, to which we would like to define the
783 static HeapCrossRef *createHeapCrossRef(const AuxGraph &graph) {
784 return new HeapCrossRef(graph);
787 /// \brief The heap type used by NagamochiIbaraki algorithm.
789 /// The heap type used by NagamochiIbaraki algorithm. It should
790 /// maximalize the priorities and the heap's key type is
791 /// the aux graph's node.
794 /// \sa NagamochiIbaraki
795 typedef typename _min_cut_bits
796 ::HeapSelector<CapacityMap>
797 ::template Selector<Value, HeapCrossRef>
800 /// \brief Instantiates a Heap.
802 /// This function instantiates a \ref Heap.
803 /// \param crossref The cross reference of the heap.
804 static Heap *createHeap(HeapCrossRef& crossref) {
805 return new Heap(crossref);
808 /// \brief Map from the AuxGraph's node type to the Graph's node type.
810 /// Map from the AuxGraph's node type to the Graph's node type.
811 typedef typename AuxGraph
812 ::template NodeMap<typename Graph::Node> NodeRefMap;
814 /// \brief Instantiates a NodeRefMap.
816 /// This function instantiates a \ref NodeRefMap.
817 static NodeRefMap *createNodeRefMap(const AuxGraph& graph) {
818 return new NodeRefMap(graph);
821 /// \brief Map from the Graph's node type to the Graph's node type.
823 /// Map from the Graph's node type to the Graph's node type.
824 typedef typename Graph
825 ::template NodeMap<typename Graph::Node> ListRefMap;
827 /// \brief Instantiates a ListRefMap.
829 /// This function instantiates a \ref ListRefMap.
830 static ListRefMap *createListRefMap(const Graph& graph) {
831 return new ListRefMap(graph);
839 /// \brief Calculates the minimum cut in an undirected graph.
841 /// Calculates the minimum cut in an undirected graph with the
842 /// Nagamochi-Ibaraki algorithm. The algorithm separates the graph's
843 /// nodes into two partitions with the minimum sum of edge capacities
844 /// between the two partitions. The algorithm can be used to test
845 /// the network reliability specifically to test how many links have
846 /// to be destroyed in the network to split it at least two
847 /// distinict subnetwork.
849 /// The complexity of the algorithm is \f$ O(ne\log(n)) \f$ but with
850 /// Fibonacci heap it can be decreased to \f$ O(ne+n^2\log(n)) \f$.
851 /// When capacity map is neutral then it uses BucketHeap which
852 /// results \f$ O(ne) \f$ time complexity.
854 /// \warning The value type of the capacity map should be able to hold
855 /// any cut value of the graph, otherwise the result can overflow.
857 template <typename _Graph, typename _CapacityMap, typename _Traits>
859 template <typename _Graph = ListUGraph,
860 typename _CapacityMap = typename _Graph::template UEdgeMap<int>,
862 = NagamochiIbarakiDefaultTraits<_Graph, _CapacityMap> >
864 class NagamochiIbaraki {
866 /// \brief \ref Exception for uninitialized parameters.
868 /// This error represents problems in the initialization
869 /// of the parameters of the algorithms.
870 class UninitializedParameter : public lemon::UninitializedParameter {
872 virtual const char* what() const throw() {
873 return "lemon::NagamochiIbaraki::UninitializedParameter";
880 typedef _Traits Traits;
881 /// The type of the underlying graph.
882 typedef typename Traits::Graph Graph;
884 /// The type of the capacity of the edges.
885 typedef typename Traits::CapacityMap::Value Value;
886 /// The type of the map that stores the edge capacities.
887 typedef typename Traits::CapacityMap CapacityMap;
888 /// The type of the aux graph
889 typedef typename Traits::AuxGraph AuxGraph;
890 /// The type of the aux capacity map
891 typedef typename Traits::AuxCapacityMap AuxCapacityMap;
892 /// The type of the aux cut value map
893 typedef typename Traits::AuxCutValueMap AuxCutValueMap;
894 /// The cross reference type used for the current heap.
895 typedef typename Traits::HeapCrossRef HeapCrossRef;
896 /// The heap type used by the max cardinality algorithm.
897 typedef typename Traits::Heap Heap;
898 /// The node refrefernces between the original and aux graph type.
899 typedef typename Traits::NodeRefMap NodeRefMap;
900 /// The list node refrefernces in the original graph type.
901 typedef typename Traits::ListRefMap ListRefMap;
905 ///\name Named template parameters
909 struct DefNeutralCapacityTraits : public Traits {
910 typedef ConstMap<typename Graph::UEdge, Const<int, 1> > CapacityMap;
911 static CapacityMap *createCapacityMap(const Graph&) {
912 return new CapacityMap();
915 /// \brief \ref named-templ-param "Named parameter" for setting
916 /// the capacity type to constMap<UEdge, int, 1>()
918 /// \ref named-templ-param "Named parameter" for setting
919 /// the capacity type to constMap<UEdge, int, 1>()
920 struct DefNeutralCapacity
921 : public NagamochiIbaraki<Graph, CapacityMap,
922 DefNeutralCapacityTraits> {
923 typedef NagamochiIbaraki<Graph, CapacityMap,
924 DefNeutralCapacityTraits> Create;
928 template <class H, class CR>
929 struct DefHeapTraits : public Traits {
930 typedef CR HeapCrossRef;
932 static HeapCrossRef *createHeapCrossRef(const AuxGraph &) {
933 throw UninitializedParameter();
935 static Heap *createHeap(HeapCrossRef &) {
936 throw UninitializedParameter();
939 /// \brief \ref named-templ-param "Named parameter" for setting heap
940 /// and cross reference type
942 /// \ref named-templ-param "Named parameter" for setting heap and cross
944 template <class H, class CR = typename Graph::template NodeMap<int> >
946 : public NagamochiIbaraki<Graph, CapacityMap,
947 DefHeapTraits<H, CR> > {
948 typedef NagamochiIbaraki< Graph, CapacityMap,
949 DefHeapTraits<H, CR> > Create;
952 template <class H, class CR>
953 struct DefStandardHeapTraits : public Traits {
954 typedef CR HeapCrossRef;
956 static HeapCrossRef *createHeapCrossRef(const AuxGraph &graph) {
957 return new HeapCrossRef(graph);
959 static Heap *createHeap(HeapCrossRef &crossref) {
960 return new Heap(crossref);
964 /// \brief \ref named-templ-param "Named parameter" for setting heap and
965 /// cross reference type with automatic allocation
967 /// \ref named-templ-param "Named parameter" for setting heap and cross
968 /// reference type. It can allocate the heap and the cross reference
969 /// object if the cross reference's constructor waits for the graph as
970 /// parameter and the heap's constructor waits for the cross reference.
971 template <class H, class CR = typename Graph::template NodeMap<int> >
972 struct DefStandardHeap
973 : public NagamochiIbaraki<Graph, CapacityMap,
974 DefStandardHeapTraits<H, CR> > {
975 typedef NagamochiIbaraki<Graph, CapacityMap,
976 DefStandardHeapTraits<H, CR> >
984 /// Pointer to the underlying graph.
986 /// Pointer to the capacity map
987 const CapacityMap *_capacity;
988 /// \brief Indicates if \ref _capacity is locally allocated
989 /// (\c true) or not.
992 /// Pointer to the aux graph.
993 AuxGraph *_aux_graph;
994 /// \brief Indicates if \ref _aux_graph is locally allocated
995 /// (\c true) or not.
996 bool local_aux_graph;
997 /// Pointer to the aux capacity map
998 AuxCapacityMap *_aux_capacity;
999 /// \brief Indicates if \ref _aux_capacity is locally allocated
1000 /// (\c true) or not.
1001 bool local_aux_capacity;
1002 /// Pointer to the aux cut value map
1003 AuxCutValueMap *_aux_cut_value;
1004 /// \brief Indicates if \ref _aux_cut_value is locally allocated
1005 /// (\c true) or not.
1006 bool local_aux_cut_value;
1007 /// Pointer to the heap cross references.
1008 HeapCrossRef *_heap_cross_ref;
1009 /// \brief Indicates if \ref _heap_cross_ref is locally allocated
1010 /// (\c true) or not.
1011 bool local_heap_cross_ref;
1012 /// Pointer to the heap.
1014 /// Indicates if \ref _heap is locally allocated (\c true) or not.
1017 /// The min cut value.
1019 /// The number of the nodes of the aux graph.
1021 /// The first and last node of the min cut in the next list.
1022 std::vector<typename Graph::Node> _cut;
1024 /// \brief The first and last element in the list associated
1025 /// to the aux graph node.
1026 NodeRefMap *_first, *_last;
1027 /// \brief The next node in the node lists.
1030 void createStructures() {
1032 local_capacity = true;
1033 _capacity = Traits::createCapacityMap(*_graph);
1036 local_aux_graph = true;
1037 _aux_graph = Traits::createAuxGraph();
1039 if(!_aux_capacity) {
1040 local_aux_capacity = true;
1041 _aux_capacity = Traits::createAuxCapacityMap(*_aux_graph);
1043 if(!_aux_cut_value) {
1044 local_aux_cut_value = true;
1045 _aux_cut_value = Traits::createAuxCutValueMap(*_aux_graph);
1048 _first = Traits::createNodeRefMap(*_aux_graph);
1049 _last = Traits::createNodeRefMap(*_aux_graph);
1051 _next = Traits::createListRefMap(*_graph);
1053 if (!_heap_cross_ref) {
1054 local_heap_cross_ref = true;
1055 _heap_cross_ref = Traits::createHeapCrossRef(*_aux_graph);
1059 _heap = Traits::createHeap(*_heap_cross_ref);
1063 void createAuxGraph() {
1064 typename Graph::template NodeMap<typename AuxGraph::Node> ref(*_graph);
1066 for (typename Graph::NodeIt n(*_graph); n != INVALID; ++n) {
1067 _next->set(n, INVALID);
1068 typename AuxGraph::Node node = _aux_graph->addNode();
1069 _first->set(node, n);
1070 _last->set(node, n);
1074 typename AuxGraph::template NodeMap<typename AuxGraph::UEdge>
1075 edges(*_aux_graph, INVALID);
1077 for (typename Graph::NodeIt n(*_graph); n != INVALID; ++n) {
1078 for (typename Graph::IncEdgeIt e(*_graph, n); e != INVALID; ++e) {
1079 typename Graph::Node tn = _graph->runningNode(e);
1080 if (n < tn || n == tn) continue;
1081 if (edges[ref[tn]] != INVALID) {
1083 (*_aux_capacity)[edges[ref[tn]]] + (*_capacity)[e];
1084 _aux_capacity->set(edges[ref[tn]], value);
1086 edges.set(ref[tn], _aux_graph->addEdge(ref[n], ref[tn]));
1087 Value value = (*_capacity)[e];
1088 _aux_capacity->set(edges[ref[tn]], value);
1091 for (typename Graph::IncEdgeIt e(*_graph, n); e != INVALID; ++e) {
1092 typename Graph::Node tn = _graph->runningNode(e);
1093 edges.set(ref[tn], INVALID);
1097 _cut.resize(1, INVALID);
1098 _min_cut = std::numeric_limits<Value>::max();
1099 for (typename AuxGraph::NodeIt n(*_aux_graph); n != INVALID; ++n) {
1101 for (typename AuxGraph::IncEdgeIt e(*_aux_graph, n);
1102 e != INVALID; ++e) {
1103 value += (*_aux_capacity)[e];
1105 if (_min_cut > value) {
1107 _cut[0] = (*_first)[n];
1109 (*_aux_cut_value)[n] = value;
1116 typedef NagamochiIbaraki Create;
1119 /// \brief Constructor.
1121 ///\param graph the graph the algorithm will run on.
1122 ///\param capacity the capacity map used by the algorithm.
1123 NagamochiIbaraki(const Graph& graph, const CapacityMap& capacity)
1125 _capacity(&capacity), local_capacity(false),
1126 _aux_graph(0), local_aux_graph(false),
1127 _aux_capacity(0), local_aux_capacity(false),
1128 _aux_cut_value(0), local_aux_cut_value(false),
1129 _heap_cross_ref(0), local_heap_cross_ref(false),
1130 _heap(0), local_heap(false),
1131 _first(0), _last(0), _next(0) {}
1133 /// \brief Constructor.
1135 /// This constructor can be used only when the Traits class
1136 /// defines how can we instantiate a local capacity map.
1137 /// If the DefNeutralCapacity used the algorithm automatically
1138 /// construct the capacity map.
1140 ///\param graph the graph the algorithm will run on.
1141 NagamochiIbaraki(const Graph& graph)
1143 _capacity(0), local_capacity(false),
1144 _aux_graph(0), local_aux_graph(false),
1145 _aux_capacity(0), local_aux_capacity(false),
1146 _aux_cut_value(0), local_aux_cut_value(false),
1147 _heap_cross_ref(0), local_heap_cross_ref(false),
1148 _heap(0), local_heap(false),
1149 _first(0), _last(0), _next(0) {}
1151 /// \brief Destructor.
1154 ~NagamochiIbaraki() {
1155 if (local_heap) delete _heap;
1156 if (local_heap_cross_ref) delete _heap_cross_ref;
1157 if (_first) delete _first;
1158 if (_last) delete _last;
1159 if (_next) delete _next;
1160 if (local_aux_capacity) delete _aux_capacity;
1161 if (local_aux_cut_value) delete _aux_cut_value;
1162 if (local_aux_graph) delete _aux_graph;
1163 if (local_capacity) delete _capacity;
1166 /// \brief Sets the heap and the cross reference used by algorithm.
1168 /// Sets the heap and the cross reference used by algorithm.
1169 /// If you don't use this function before calling \ref run(),
1170 /// it will allocate one. The destuctor deallocates this
1171 /// automatically allocated heap and cross reference, of course.
1172 /// \return <tt> (*this) </tt>
1173 NagamochiIbaraki &heap(Heap& hp, HeapCrossRef &cr)
1175 if (local_heap_cross_ref) {
1176 delete _heap_cross_ref;
1177 local_heap_cross_ref=false;
1179 _heap_cross_ref = &cr;
1188 /// \brief Sets the aux graph.
1190 /// Sets the aux graph used by algorithm.
1191 /// If you don't use this function before calling \ref run(),
1192 /// it will allocate one. The destuctor deallocates this
1193 /// automatically allocated graph, of course.
1194 /// \return <tt> (*this) </tt>
1195 NagamochiIbaraki &auxGraph(AuxGraph& aux_graph)
1197 if(local_aux_graph) {
1199 local_aux_graph=false;
1201 _aux_graph = &aux_graph;
1205 /// \brief Sets the aux capacity map.
1207 /// Sets the aux capacity map used by algorithm.
1208 /// If you don't use this function before calling \ref run(),
1209 /// it will allocate one. The destuctor deallocates this
1210 /// automatically allocated graph, of course.
1211 /// \return <tt> (*this) </tt>
1212 NagamochiIbaraki &auxCapacityMap(AuxCapacityMap& aux_capacity_map)
1214 if(local_aux_capacity) {
1215 delete _aux_capacity;
1216 local_aux_capacity=false;
1218 _aux_capacity = &aux_capacity_map;
1222 /// \name Execution control
1223 /// The simplest way to execute the algorithm is to use
1224 /// one of the member functions called \c run().
1226 /// If you need more control on the execution,
1227 /// first you must call \ref init() and then call the start()
1228 /// or proper times the processNextPhase() member functions.
1232 /// \brief Initializes the internal data structures.
1234 /// Initializes the internal data structures.
1236 _node_num = countNodes(*_graph);
1244 typename AuxGraph::Node source, target;
1248 struct EdgeInfoLess {
1249 bool operator()(const EdgeInfo& left, const EdgeInfo& right) const {
1250 return (left.source < right.source) ||
1251 (left.source == right.source && left.target < right.target);
1258 /// \brief Processes the next phase
1260 /// Processes the next phase in the algorithm. The function should
1261 /// be called at most countNodes(graph) - 1 times to get surely
1262 /// the min cut in the graph.
1264 ///\return %True when the algorithm finished.
1265 bool processNextPhase() {
1266 if (_node_num <= 1) return true;
1268 typedef typename AuxGraph::Node Node;
1269 typedef typename AuxGraph::NodeIt NodeIt;
1270 typedef typename AuxGraph::UEdge UEdge;
1271 typedef typename AuxGraph::UEdgeIt UEdgeIt;
1272 typedef typename AuxGraph::IncEdgeIt IncEdgeIt;
1274 typename AuxGraph::template UEdgeMap<Value> _edge_cut(*_aux_graph);
1277 for (NodeIt n(*_aux_graph); n != INVALID; ++n) {
1278 _heap_cross_ref->set(n, Heap::PRE_HEAP);
1281 std::vector<Node> nodes;
1282 nodes.reserve(_node_num);
1286 Value emc = std::numeric_limits<Value>::max();
1288 _heap->push(typename AuxGraph::NodeIt(*_aux_graph), 0);
1289 while (!_heap->empty()) {
1290 Node node = _heap->top();
1291 Value value = _heap->prio();
1294 for (typename AuxGraph::IncEdgeIt e(*_aux_graph, node);
1295 e != INVALID; ++e) {
1296 Node tn = _aux_graph->runningNode(e);
1297 switch (_heap->state(tn)) {
1298 case Heap::PRE_HEAP:
1299 _heap->push(tn, (*_aux_capacity)[e]);
1300 _edge_cut[e] = (*_heap)[tn];
1303 _heap->decrease(tn, (*_aux_capacity)[e] + (*_heap)[tn]);
1304 _edge_cut[e] = (*_heap)[tn];
1306 case Heap::POST_HEAP:
1311 alpha += (*_aux_cut_value)[node];
1314 nodes.push_back(node);
1315 if (!_heap->empty()) {
1323 if (int(nodes.size()) < _node_num) {
1324 _aux_graph->clear();
1327 for (int i = 0; i < int(nodes.size()); ++i) {
1328 typename Graph::Node n = (*_first)[nodes[i]];
1329 while (n != INVALID) {
1338 if (emc < _min_cut) {
1340 for (int i = 0; i < sep; ++i) {
1341 typename Graph::Node n = (*_first)[nodes[i]];
1342 while (n != INVALID) {
1350 typedef typename AuxGraph::template NodeMap<int> UfeCr;
1351 UfeCr ufecr(*_aux_graph);
1352 typedef UnionFindEnum<UfeCr> Ufe;
1355 for (typename AuxGraph::NodeIt n(*_aux_graph); n != INVALID; ++n) {
1359 for (typename AuxGraph::UEdgeIt e(*_aux_graph); e != INVALID; ++e) {
1360 if (_edge_cut[e] >= emc) {
1361 ufe.join(_aux_graph->source(e), _aux_graph->target(e));
1365 typedef typename Ufe::ClassIt UfeCIt;
1366 if (ufe.size(UfeCIt(ufe)) == _node_num) {
1367 _aux_graph->clear();
1372 std::vector<typename AuxGraph::Node> remnodes;
1374 typename AuxGraph::template NodeMap<UEdge> edges(*_aux_graph, INVALID);
1375 for (typename Ufe::ClassIt c(ufe); c != INVALID; ++c) {
1376 if (ufe.size(c) == 1) continue;
1377 for (typename Ufe::ItemIt r(ufe, c); r != INVALID; ++r) {
1378 if (static_cast<Node>(r) == static_cast<Node>(c)) continue;
1379 _next->set((*_last)[c], (*_first)[r]);
1380 _last->set(c, (*_last)[r]);
1381 remnodes.push_back(r);
1386 std::vector<EdgeInfo> addedges;
1387 std::vector<UEdge> remedges;
1389 for (typename AuxGraph::UEdgeIt e(*_aux_graph);
1390 e != INVALID; ++e) {
1391 Node sn = ufe.find(_aux_graph->source(e));
1392 Node tn = ufe.find(_aux_graph->target(e));
1393 if ((ufe.size(sn) == 1 && ufe.size(tn) == 1)) {
1397 remedges.push_back(e);
1408 info.capacity = (*_aux_capacity)[e];
1409 addedges.push_back(info);
1410 remedges.push_back(e);
1413 for (int i = 0; i < int(remedges.size()); ++i) {
1414 _aux_graph->erase(remedges[i]);
1417 sort(addedges.begin(), addedges.end(), EdgeInfoLess());
1421 while (i < int(addedges.size())) {
1422 Node sn = addedges[i].source;
1423 Node tn = addedges[i].target;
1424 Value ec = addedges[i].capacity;
1426 while (i < int(addedges.size()) &&
1427 sn == addedges[i].source && tn == addedges[i].target) {
1428 ec += addedges[i].capacity;
1431 typename AuxGraph::UEdge ne = _aux_graph->addEdge(sn, tn);
1432 (*_aux_capacity)[ne] = ec;
1436 for (typename Ufe::ClassIt c(ufe); c != INVALID; ++c) {
1437 if (ufe.size(c) == 1) continue;
1439 for (typename AuxGraph::IncEdgeIt e(*_aux_graph, c);
1440 e != INVALID; ++e) {
1441 cutvalue += (*_aux_capacity)[e];
1444 (*_aux_cut_value)[c] = cutvalue;
1448 for (int i = 0; i < int(remnodes.size()); ++i) {
1449 _aux_graph->erase(remnodes[i]);
1452 return _node_num == 1;
1455 /// \brief Executes the algorithm.
1457 /// Executes the algorithm.
1459 /// \pre init() must be called
1461 while (!processNextPhase());
1465 /// \brief Runs %NagamochiIbaraki algorithm.
1467 /// This method runs the %Min cut algorithm
1469 /// \note mc.run(s) is just a shortcut of the following code.
1481 /// \name Query Functions
1483 /// The result of the %NagamochiIbaraki
1484 /// algorithm can be obtained using these functions.\n
1485 /// Before the use of these functions, either run() or start()
1490 /// \brief Returns the min cut value.
1492 /// Returns the min cut value if the algorithm finished.
1493 /// After the first processNextPhase() it is a value of a
1494 /// valid cut in the graph.
1495 Value minCut() const {
1499 /// \brief Returns a min cut in a NodeMap.
1501 /// It sets the nodes of one of the two partitions to true in
1502 /// the given BoolNodeMap. The map contains a valid cut if the
1503 /// map have been set false previously.
1504 template <typename NodeMap>
1505 Value quickMinCut(NodeMap& nodeMap) const {
1506 for (int i = 0; i < int(_cut.size()); ++i) {
1507 nodeMap.set(_cut[i], true);
1512 /// \brief Returns a min cut in a NodeMap.
1514 /// It sets the nodes of one of the two partitions to true and
1515 /// the other partition to false. The function first set all of the
1516 /// nodes to false and after it call the quickMinCut() member.
1517 template <typename NodeMap>
1518 Value minCut(NodeMap& nodeMap) const {
1519 for (typename Graph::NodeIt it(*_graph); it != INVALID; ++it) {
1520 nodeMap.set(it, false);
1522 quickMinCut(nodeMap);
1526 /// \brief Returns a min cut in an EdgeMap.
1528 /// If an undirected edge is in a min cut then it will be
1529 /// set to true and the others will be set to false in the given map.
1530 template <typename EdgeMap>
1531 Value cutEdges(EdgeMap& edgeMap) const {
1532 typename Graph::template NodeMap<bool> cut(*_graph, false);
1534 for (typename Graph::EdgeIt it(*_graph); it != INVALID; ++it) {
1535 edgeMap.set(it, cut[_graph->source(it)] ^ cut[_graph->target(it)]);