[Lemon-commits] Balazs Dezso: New implementation for Nagamochi-I...
Lemon HG
hg at lemon.cs.elte.hu
Mon Nov 15 07:54:43 CET 2010
details: http://lemon.cs.elte.hu/hg/lemon/rev/5087694945e4
changeset: 1017:5087694945e4
user: Balazs Dezso <deba [at] inf.elte.hu>
date: Sun Nov 14 09:25:03 2010 +0100
description:
New implementation for Nagamochi-Ibaraki algorithm
diffstat:
lemon/Makefile.am | 1 +
lemon/nagamochi_ibaraki.h | 697 +++++++++++++++++++++++++++++++++++++++++++
test/CMakeLists.txt | 1 +
test/Makefile.am | 2 +
test/nagamochi_ibaraki_test.cc | 141 ++++++++
5 files changed, 842 insertions(+), 0 deletions(-)
diffs (truncated from 889 to 300 lines):
diff --git a/lemon/Makefile.am b/lemon/Makefile.am
--- a/lemon/Makefile.am
+++ b/lemon/Makefile.am
@@ -107,6 +107,7 @@
lemon/matching.h \
lemon/math.h \
lemon/min_cost_arborescence.h \
+ lemon/nagamochi_ibaraki.h \
lemon/nauty_reader.h \
lemon/network_simplex.h \
lemon/pairing_heap.h \
diff --git a/lemon/nagamochi_ibaraki.h b/lemon/nagamochi_ibaraki.h
new file mode 100644
--- /dev/null
+++ b/lemon/nagamochi_ibaraki.h
@@ -0,0 +1,697 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_NAGAMOCHI_IBARAKI_H
+#define LEMON_NAGAMOCHI_IBARAKI_H
+
+
+/// \ingroup min_cut
+/// \file
+/// \brief Implementation of the Nagamochi-Ibaraki algorithm.
+
+#include <lemon/core.h>
+#include <lemon/bin_heap.h>
+#include <lemon/bucket_heap.h>
+#include <lemon/maps.h>
+#include <lemon/radix_sort.h>
+#include <lemon/unionfind.h>
+
+#include <cassert>
+
+namespace lemon {
+
+ /// \brief Default traits class for NagamochiIbaraki class.
+ ///
+ /// Default traits class for NagamochiIbaraki class.
+ /// \param GR The undirected graph type.
+ /// \param CM Type of capacity map.
+ template <typename GR, typename CM>
+ struct NagamochiIbarakiDefaultTraits {
+ /// The type of the capacity map.
+ typedef typename CM::Value Value;
+
+ /// The undirected graph type the algorithm runs on.
+ typedef GR Graph;
+
+ /// \brief The type of the map that stores the edge capacities.
+ ///
+ /// The type of the map that stores the edge capacities.
+ /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+ typedef CM CapacityMap;
+
+ /// \brief Instantiates a CapacityMap.
+ ///
+ /// This function instantiates a \ref CapacityMap.
+#ifdef DOXYGEN
+ static CapacityMap *createCapacityMap(const Graph& graph)
+#else
+ static CapacityMap *createCapacityMap(const Graph&)
+#endif
+ {
+ LEMON_ASSERT(false, "CapacityMap is not initialized");
+ return 0; // ignore warnings
+ }
+
+ /// \brief The cross reference type used by heap.
+ ///
+ /// The cross reference type used by heap.
+ /// Usually \c Graph::NodeMap<int>.
+ typedef typename Graph::template NodeMap<int> HeapCrossRef;
+
+ /// \brief Instantiates a HeapCrossRef.
+ ///
+ /// This function instantiates a \ref HeapCrossRef.
+ /// \param g is the graph, to which we would like to define the
+ /// \ref HeapCrossRef.
+ static HeapCrossRef *createHeapCrossRef(const Graph& g) {
+ return new HeapCrossRef(g);
+ }
+
+ /// \brief The heap type used by NagamochiIbaraki algorithm.
+ ///
+ /// The heap type used by NagamochiIbaraki algorithm. It has to
+ /// maximize the priorities.
+ ///
+ /// \sa BinHeap
+ /// \sa NagamochiIbaraki
+ typedef BinHeap<Value, HeapCrossRef, std::greater<Value> > Heap;
+
+ /// \brief Instantiates a Heap.
+ ///
+ /// This function instantiates a \ref Heap.
+ /// \param r is the cross reference of the heap.
+ static Heap *createHeap(HeapCrossRef& r) {
+ return new Heap(r);
+ }
+ };
+
+ /// \ingroup min_cut
+ ///
+ /// \brief Calculates the minimum cut in an undirected graph.
+ ///
+ /// Calculates the minimum cut in an undirected graph with the
+ /// Nagamochi-Ibaraki algorithm. The algorithm separates the graph's
+ /// nodes into two partitions with the minimum sum of edge capacities
+ /// between the two partitions. The algorithm can be used to test
+ /// the network reliability, especially to test how many links have
+ /// to be destroyed in the network to split it to at least two
+ /// distinict subnetworks.
+ ///
+ /// The complexity of the algorithm is \f$ O(nm\log(n)) \f$ but with
+ /// \ref FibHeap "Fibonacci heap" it can be decreased to
+ /// \f$ O(nm+n^2\log(n)) \f$. When the edges have unit capacities,
+ /// \c BucketHeap can be used which yields \f$ O(nm) \f$ time
+ /// complexity.
+ ///
+ /// \warning The value type of the capacity map should be able to
+ /// hold any cut value of the graph, otherwise the result can
+ /// overflow.
+ /// \note This capacity is supposed to be integer type.
+#ifdef DOXYGEN
+ template <typename GR, typename CM, typename TR>
+#else
+ template <typename GR,
+ typename CM = typename GR::template EdgeMap<int>,
+ typename TR = NagamochiIbarakiDefaultTraits<GR, CM> >
+#endif
+ class NagamochiIbaraki {
+ public:
+
+ typedef TR Traits;
+ /// The type of the underlying graph.
+ typedef typename Traits::Graph Graph;
+
+ /// The type of the capacity map.
+ typedef typename Traits::CapacityMap CapacityMap;
+ /// The value type of the capacity map.
+ typedef typename Traits::CapacityMap::Value Value;
+
+ /// The heap type used by the algorithm.
+ typedef typename Traits::Heap Heap;
+ /// The cross reference type used for the heap.
+ typedef typename Traits::HeapCrossRef HeapCrossRef;
+
+ ///\name Named template parameters
+
+ ///@{
+
+ struct SetUnitCapacityTraits : public Traits {
+ typedef ConstMap<typename Graph::Edge, Const<int, 1> > CapacityMap;
+ static CapacityMap *createCapacityMap(const Graph&) {
+ return new CapacityMap();
+ }
+ };
+
+ /// \brief \ref named-templ-param "Named parameter" for setting
+ /// the capacity map to a constMap<Edge, int, 1>() instance
+ ///
+ /// \ref named-templ-param "Named parameter" for setting
+ /// the capacity map to a constMap<Edge, int, 1>() instance
+ struct SetUnitCapacity
+ : public NagamochiIbaraki<Graph, CapacityMap,
+ SetUnitCapacityTraits> {
+ typedef NagamochiIbaraki<Graph, CapacityMap,
+ SetUnitCapacityTraits> Create;
+ };
+
+
+ template <class H, class CR>
+ struct SetHeapTraits : public Traits {
+ typedef CR HeapCrossRef;
+ typedef H Heap;
+ static HeapCrossRef *createHeapCrossRef(int num) {
+ LEMON_ASSERT(false, "HeapCrossRef is not initialized");
+ return 0; // ignore warnings
+ }
+ static Heap *createHeap(HeapCrossRef &) {
+ LEMON_ASSERT(false, "Heap is not initialized");
+ return 0; // ignore warnings
+ }
+ };
+
+ /// \brief \ref named-templ-param "Named parameter" for setting
+ /// heap and cross reference type
+ ///
+ /// \ref named-templ-param "Named parameter" for setting heap and
+ /// cross reference type. The heap has to maximize the priorities.
+ template <class H, class CR = RangeMap<int> >
+ struct SetHeap
+ : public NagamochiIbaraki<Graph, CapacityMap, SetHeapTraits<H, CR> > {
+ typedef NagamochiIbaraki< Graph, CapacityMap, SetHeapTraits<H, CR> >
+ Create;
+ };
+
+ template <class H, class CR>
+ struct SetStandardHeapTraits : public Traits {
+ typedef CR HeapCrossRef;
+ typedef H Heap;
+ static HeapCrossRef *createHeapCrossRef(int size) {
+ return new HeapCrossRef(size);
+ }
+ static Heap *createHeap(HeapCrossRef &crossref) {
+ return new Heap(crossref);
+ }
+ };
+
+ /// \brief \ref named-templ-param "Named parameter" for setting
+ /// heap and cross reference type with automatic allocation
+ ///
+ /// \ref named-templ-param "Named parameter" for setting heap and
+ /// cross reference type with automatic allocation. They should
+ /// have standard constructor interfaces to be able to
+ /// automatically created by the algorithm (i.e. the graph should
+ /// be passed to the constructor of the cross reference and the
+ /// cross reference should be passed to the constructor of the
+ /// heap). However, external heap and cross reference objects
+ /// could also be passed to the algorithm using the \ref heap()
+ /// function before calling \ref run() or \ref init(). The heap
+ /// has to maximize the priorities.
+ /// \sa SetHeap
+ template <class H, class CR = RangeMap<int> >
+ struct SetStandardHeap
+ : public NagamochiIbaraki<Graph, CapacityMap,
+ SetStandardHeapTraits<H, CR> > {
+ typedef NagamochiIbaraki<Graph, CapacityMap,
+ SetStandardHeapTraits<H, CR> > Create;
+ };
+
+ ///@}
+
+
+ private:
+
+ const Graph &_graph;
+ const CapacityMap *_capacity;
+ bool _local_capacity; // unit capacity
+
+ struct ArcData {
+ typename Graph::Node target;
+ int prev, next;
+ };
+ struct EdgeData {
+ Value capacity;
+ Value cut;
+ };
+
+ struct NodeData {
+ int first_arc;
+ typename Graph::Node prev, next;
+ int curr_arc;
+ typename Graph::Node last_rep;
+ Value sum;
+ };
+
+ typename Graph::template NodeMap<NodeData> *_nodes;
+ std::vector<ArcData> _arcs;
+ std::vector<EdgeData> _edges;
+
+ typename Graph::Node _first_node;
+ int _node_num;
+
+ Value _min_cut;
+
+ HeapCrossRef *_heap_cross_ref;
+ bool _local_heap_cross_ref;
+ Heap *_heap;
+ bool _local_heap;
+
+ typedef typename Graph::template NodeMap<typename Graph::Node> NodeList;
+ NodeList *_next_rep;
+
+ typedef typename Graph::template NodeMap<bool> MinCutMap;
+ MinCutMap *_cut_map;
+
+ void createStructures() {
+ if (!_nodes) {
+ _nodes = new (typename Graph::template NodeMap<NodeData>)(_graph);
+ }
+ if (!_capacity) {
+ _local_capacity = true;
More information about the Lemon-commits
mailing list