Index: boost/graph/maximum_adjacency_search.hpp
===================================================================
--- boost/graph/maximum_adjacency_search.hpp (revision 0)
+++ boost/graph/maximum_adjacency_search.hpp (working copy)
@@ -0,0 +1,267 @@
+//
+//=======================================================================
+// Copyright 2012 Fernando Vilas
+// 2010 Daniel Trebbien
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+//
+
+// The maximum adjacency search algorithm was originally part of the
+// Stoer-Wagner min cut implementation by Daniel Trebbien. It has been
+// broken out into its own file to be a public search algorithm, with
+// visitor concepts.
+#ifndef BOOST_GRAPH_MAXIMUM_ADJACENCY_SEARCH_H
+#define BOOST_GRAPH_MAXIMUM_ADJACENCY_SEARCH_H
+
+/**
+ * This is an implementation of the maximum adjacency search on an
+ * undirected graph. It allows a visitor object to perform some
+ * operation on each vertex as that vertex is visited.
+ *
+ * The algorithm runs as follows:
+ *
+ * Initialize all nodes to be unvisited (reach count = 0)
+ * and call vis.initialize_vertex
+ * For i = number of nodes in graph downto 1
+ * Select the unvisited node with the highest reach count
+ * The user provides the starting node to break the first tie,
+ * but future ties are broken arbitrarily
+ * Visit the node by calling vis.start_vertex
+ * Increment the reach count for all unvisited neighbors
+ * and call vis.examine_edge for each of these edges
+ * Mark the node as visited and call vis.finish_vertex
+ *
+ * The algorithm returns the last 2 vertices visited (s and t), and
+ * the key from the priority queue of the last vertex (t) when
+ * removed.
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace boost {
+template
+struct MASVisitorConcept {
+ void constraints() {
+ boost::function_requires< boost::CopyConstructibleConcept >();
+ vis.initialize_vertex(u, g);
+ vis.start_vertex(u, g);
+ vis.examine_edge(e, g);
+ vis.finish_vertex(u, g);
+ }
+ Visitor vis;
+ Graph g;
+ typename boost::graph_traits::vertex_descriptor u;
+ typename boost::graph_traits::edge_descriptor e;
+};
+
+template
+class mas_visitor {
+public:
+ mas_visitor() { }
+ mas_visitor(Visitors vis) : m_vis(vis) { }
+
+ template
+ void
+ initialize_vertex(Vertex u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex());
+ }
+
+ template
+ void
+ start_vertex(Vertex u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, ::boost::on_start_vertex());
+ }
+
+ template
+ void
+ examine_edge(Edge e, Graph& g)
+ {
+ invoke_visitors(m_vis, e, g, ::boost::on_examine_edge());
+ }
+
+ template
+ void
+ finish_vertex(Vertex u, Graph& g)
+ {
+ invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex());
+ }
+
+ BOOST_GRAPH_EVENT_STUB(on_initialize_vertex,mas)
+ BOOST_GRAPH_EVENT_STUB(on_start_vertex,mas)
+ BOOST_GRAPH_EVENT_STUB(on_examine_edge,mas)
+ BOOST_GRAPH_EVENT_STUB(on_finish_vertex,mas)
+
+protected:
+ Visitors m_vis;
+};
+template
+mas_visitor
+make_mas_visitor(Visitors vis) {
+ return mas_visitor(vis);
+}
+typedef mas_visitor<> default_mas_visitor;
+
+namespace detail {
+ template
+ boost::tuple::vertex_descriptor, typename boost::graph_traits::vertex_descriptor, typename KeyedUpdatablePriorityQueue::key_type>
+ maximum_adjacency_search(const Graph& g, WeightMap weights, MASVisitor vis, const typename boost::graph_traits::vertex_descriptor start, VertexAssignmentMap assignments, KeyedUpdatablePriorityQueue pq) {
+ typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor;
+ typedef typename boost::graph_traits::vertices_size_type vertices_size_type;
+ typedef typename boost::graph_traits::edge_descriptor edge_descriptor;
+ typedef typename boost::property_traits::value_type weight_type;
+
+ std::set assignedVertices;
+
+ // initialize `assignments` (all vertices are initially
+ // assigned to themselves)
+ BGL_FORALL_VERTICES_T(v, g, Graph) {
+ put(assignments, v, v);
+ }
+
+ typename KeyedUpdatablePriorityQueue::key_map keys = pq.keys();
+
+ // set number of visited neighbors for all vertices to 0
+ BGL_FORALL_VERTICES_T(v, g, Graph) {
+ if (v == get(assignments, v)) { // foreach u \in V do
+ put(keys, v, weight_type(0)); vis.initialize_vertex(v, g);
+
+ pq.push(v);
+ }
+ }
+ assert(pq.size() >= 2);
+
+ // Give the starting vertex high priority
+ put(keys, start, get(keys, start) + num_vertices(g) + 1);
+ pq.update(start);
+
+ // start traversing the graph
+ vertex_descriptor s, t;
+ weight_type w;
+ while (!pq.empty()) { // while PQ \neq {} do
+ const vertex_descriptor u = pq.top(); // u = extractmax(PQ)
+ w = get(keys, u);
+ pq.pop(); vis.start_vertex(u, g);
+
+ // set s and t to the last and next-to-last vertices extracted
+ s = t; t = u;
+
+ BGL_FORALL_OUTEDGES_T(u, e, g, Graph) { // foreach (u, v) \in E do
+ vis.examine_edge(e, g);
+
+ const vertex_descriptor v = get(assignments, target(e, g));
+
+ if (pq.contains(v)) { // if v \in PQ then
+ put(keys, v, get(keys, v) + get(weights, e)); // increasekey(PQ, v, wA(v) + w(u, v))
+ pq.update(v);
+ }
+ }
+
+ typename std::set::const_iterator assignedVertexIt, assignedVertexEnd = assignedVertices.end();
+ for (assignedVertexIt = assignedVertices.begin(); assignedVertexIt != assignedVertexEnd; ++assignedVertexIt) {
+ const vertex_descriptor uPrime = *assignedVertexIt;
+
+ if (get(assignments, uPrime) == u) {
+ BGL_FORALL_OUTEDGES_T(uPrime, e, g, Graph) { // foreach (u, v) \in E do
+ vis.examine_edge(e, g);
+
+ const vertex_descriptor v = get(assignments, target(e, g));
+
+ if (pq.contains(v)) { // if v \in PQ then
+ put(keys, v, get(keys, v) + get(weights, e)); // increasekey(PQ, v, wA(v) + w(u, v))
+ pq.update(v);
+ }
+ }
+ }
+ }
+ vis.finish_vertex(u, g);
+ }
+ return boost::make_tuple(s,t,w);
+ }
+} // end namespace detail
+
+ template
+ boost::tuple::vertex_descriptor, typename boost::graph_traits::vertex_descriptor, typename KeyedUpdatablePriorityQueue::key_type>
+maximum_adjacency_search(const Graph& g, WeightMap weights, MASVisitor vis, const typename boost::graph_traits::vertex_descriptor start, VertexAssignmentMap assignments, KeyedUpdatablePriorityQueue pq) {
+ BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept));
+ BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept));
+ typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor;
+ typedef typename boost::graph_traits::vertices_size_type vertices_size_type;
+ typedef typename boost::graph_traits::edge_descriptor edge_descriptor;
+ BOOST_CONCEPT_ASSERT((boost::Convertible::directed_category, boost::undirected_tag>));
+ BOOST_CONCEPT_ASSERT((boost::ReadablePropertyMapConcept));
+ typedef typename boost::property_traits::value_type weight_type;
+ boost::function_requires< MASVisitorConcept >();
+ BOOST_CONCEPT_ASSERT((boost::ReadWritePropertyMapConcept));
+ BOOST_CONCEPT_ASSERT((boost::Convertible::value_type>));
+ BOOST_CONCEPT_ASSERT((boost::KeyedUpdatableQueueConcept));
+
+ vertices_size_type n = num_vertices(g);
+ if (n < 2)
+ throw boost::bad_graph("the input graph must have at least two vertices.");
+ else if (!pq.empty())
+ throw std::invalid_argument("the max-priority queue must be empty initially.");
+
+ return detail::maximum_adjacency_search(g, weights,
+ vis, start,
+ assignments, pq);
+}
+
+namespace graph {
+ namespace detail {
+ template
+ struct maximum_adjacency_search_impl {
+
+ typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor;
+
+ //TODO: This assumes that the weight map has edge_weight_t values in it.
+ // If this is not true, it may fail to compile. We should really rely on
+ // the ArgPack, but the named parameter macros require a result_type.
+ // Can this be fixed?
+ typedef typename boost::tuple::type>::value_type>
+ result_type;
+
+ template
+ result_type
+ operator() (const Graph& g, const ArgPack& arg_pack) const {
+ using namespace boost::graph::keywords;
+ typedef typename std::vector::size_type heap_container_size_type;
+ typedef typename parameter::value_type::type >::type WeightMap;
+ typedef typename boost::property_traits::value_type weight_type;
+
+ return boost::maximum_adjacency_search
+ (g,
+ arg_pack[_weight_map | get(edge_weight, g)],
+ arg_pack[_visitor | make_mas_visitor(null_visitor())],
+ arg_pack[_root_vertex | *vertices(g).first],
+ arg_pack[_vertex_assignment_map | boost::detail::make_property_map_from_arg_pack_gen(vertex_descriptor())(g, arg_pack)],
+ unwrap_ref(arg_pack[_max_priority_queue | boost::detail::make_priority_queue_from_arg_pack_gen >(choose_param(get_param(arg_pack, boost::distance_zero_t()), weight_type(0)))(g, arg_pack)]));
+ }
+ };
+ }
+ BOOST_GRAPH_MAKE_FORWARDING_FUNCTION(maximum_adjacency_search,1,5)
+}
+ // Named parameter interface
+ BOOST_GRAPH_MAKE_OLD_STYLE_PARAMETER_FUNCTION(maximum_adjacency_search, 1)
+
+} // end namespace boost
+
+#include
+
+#endif // BOOST_GRAPH_MAXIMUM_ADJACENCY_SEARCH_H
Index: boost/graph/stoer_wagner_min_cut.hpp
===================================================================
--- boost/graph/stoer_wagner_min_cut.hpp (revision 81759)
+++ boost/graph/stoer_wagner_min_cut.hpp (working copy)
@@ -15,104 +15,92 @@
#include
#include
#include
-#include
+#include
#include
+#include
#include
#include
#include
#include
+#include
namespace boost {
-
+
namespace detail {
-
- /**
- * \brief Performs a phase of the Stoer-Wagner min-cut algorithm
- *
- * Performs a phase of the Stoer-Wagner min-cut algorithm.
- *
- * As described by Stoer & Wagner (1997), a phase is simply a maximum adjacency search
- * (also called a maximum cardinality search), which results in the selection of two vertices
- * \em s and \em t, and, as a side product, a minimum s-t cut of
- * the input graph. Here, the input graph is basically \p g, but some vertices are virtually
- * assigned to others as a way of viewing \p g as a graph with some sets of
- * vertices merged together.
- *
- * This implementation is a translation of pseudocode by Professor Uri Zwick,
- * School of Computer Science, Tel Aviv University.
- *
- * \pre \p g is a connected, undirected graph
- * \param[in] g the input graph
- * \param[in] assignments a read/write property map from each vertex to the vertex that it is assigned to
- * \param[in] assignedVertices a list of vertices that are assigned to others
- * \param[in] weights a readable property map from each edge to its weight (a non-negative value)
- * \param[out] pq a keyed, updatable max-priority queue
- * \returns a tuple (\em s, \em t, \em w) of the "s" and "t"
- * of the minimum s-t cut and the cut weight \em w
- * of the minimum s-t cut.
- * \see http://www.cs.tau.ac.il/~zwick/grad-algo-08/gmc.pdf
- *
- * \author Daniel Trebbien
- * \date 2010-09-11
- */
- template
- boost::tuple::vertex_descriptor, typename boost::graph_traits::vertex_descriptor, typename boost::property_traits::value_type>
- stoer_wagner_phase(const UndirectedGraph& g, VertexAssignmentMap assignments, const std::set::vertex_descriptor>& assignedVertices, WeightMap weights, KeyedUpdatablePriorityQueue& pq) {
- typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor;
- typedef typename boost::property_traits::value_type weight_type;
-
- BOOST_ASSERT(pq.empty());
- typename KeyedUpdatablePriorityQueue::key_map keys = pq.keys();
-
- BGL_FORALL_VERTICES_T(v, g, UndirectedGraph) {
- if (v == get(assignments, v)) { // foreach u \in V do
- put(keys, v, weight_type(0));
-
- pq.push(v);
+ template < typename ParityMap, typename WeightType, typename WeightMap >
+ class mas_min_cut_visitor : public boost::default_mas_visitor {
+ public:
+ mas_min_cut_visitor(ParityMap parity,
+ WeightType& cutweight,
+ const WeightMap& weight_map)
+ : m_bestParity(parity),
+ m_parity(parity),
+ m_bestWeight(cutweight),
+ m_cutweight(0),
+ m_visited(0),
+ m_weightMap(weight_map)
+ {
+ // set here since the init list sets the reference
+ m_bestWeight = (std::numeric_limits::max)();
+
+ // reallocate the parity map since it is for internal
+ // bookkeeping here only.
+ // TODO: specific to one-bit color map. make it not depend on that.
+ m_parity.data.reset(new unsigned char[(m_parity.n + m_parity.bits_per_char - 1) / m_parity.bits_per_char]);
+ }
+
+ template < typename Vertex, typename Graph >
+ void initialize_vertex(Vertex u, const Graph & g)
+ {
+ typedef typename boost::property_traits::value_type parity_type;
+ put(m_parity, u, parity_type(0));
+ put(m_bestParity, u, parity_type(0));
+ }
+
+ template < typename Edge, typename Graph >
+ void examine_edge(Edge e, const Graph & g)
+ {
+ WeightType w = get(m_weightMap, e);
+
+ // if the target of e is already marked then decrease cutweight
+ // otherwise, increase it
+ if (get(m_parity, boost::target(e, g))) {
+ m_cutweight -= w;
+ } else {
+ m_cutweight += w;
}
}
-
- BOOST_ASSERT(pq.size() >= 2);
-
- vertex_descriptor s = boost::graph_traits::null_vertex();
- vertex_descriptor t = boost::graph_traits::null_vertex();
- weight_type w;
- while (!pq.empty()) { // while PQ \neq {} do
- const vertex_descriptor u = pq.top(); // u = extractmax(PQ)
- w = get(keys, u);
- pq.pop();
-
- s = t; t = u;
-
- BGL_FORALL_OUTEDGES_T(u, e, g, UndirectedGraph) { // foreach (u, v) \in E do
- const vertex_descriptor v = get(assignments, target(e, g));
-
- if (pq.contains(v)) { // if v \in PQ then
- put(keys, v, get(keys, v) + get(weights, e)); // increasekey(PQ, v, wA(v) + w(u, v))
- pq.update(v);
+
+ template < typename Vertex, typename Graph >
+ void finish_vertex(Vertex u, const Graph & g)
+ {
+ typedef typename boost::property_traits::value_type parity_type;
+ ++m_visited;
+ put(m_parity, u, parity_type(1));
+
+ if (m_cutweight < m_bestWeight && m_visited < num_vertices(g)) {
+ m_bestWeight = m_cutweight;
+ BGL_FORALL_VERTICES_T(i, g, Graph) {
+ put(m_bestParity,i, get(m_parity,i));
}
}
-
- typename std::set::const_iterator assignedVertexIt, assignedVertexEnd = assignedVertices.end();
- for (assignedVertexIt = assignedVertices.begin(); assignedVertexIt != assignedVertexEnd; ++assignedVertexIt) {
- const vertex_descriptor uPrime = *assignedVertexIt;
-
- if (get(assignments, uPrime) == u) {
- BGL_FORALL_OUTEDGES_T(uPrime, e, g, UndirectedGraph) { // foreach (u, v) \in E do
- const vertex_descriptor v = get(assignments, target(e, g));
-
- if (pq.contains(v)) { // if v \in PQ then
- put(keys, v, get(keys, v) + get(weights, e)); // increasekey(PQ, v, wA(v) + w(u, v))
- pq.update(v);
- }
- }
- }
- }
}
-
- return boost::make_tuple(s, t, w);
- }
-
+
+ inline void clear() {
+ m_bestWeight = (std::numeric_limits::max)();
+ m_visited = 0;
+ m_cutweight = 0;
+ }
+
+ private:
+ ParityMap m_bestParity;
+ ParityMap m_parity;
+ WeightType & m_bestWeight;
+ WeightType m_cutweight;
+ unsigned m_visited;
+ const WeightMap& m_weightMap;
+ };
+
/**
* \brief Computes a min-cut of the input graph
*
@@ -138,6 +126,54 @@
template
typename boost::property_traits::value_type
stoer_wagner_min_cut(const UndirectedGraph& g, WeightMap weights, ParityMap parities, VertexAssignmentMap assignments, KeyedUpdatablePriorityQueue& pq) {
+ typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor;
+ typedef typename boost::graph_traits::vertices_size_type vertices_size_type;
+ typedef typename boost::graph_traits::edge_descriptor edge_descriptor;
+ typedef typename boost::property_traits::value_type weight_type;
+ typedef typename boost::property_traits::value_type parity_type;
+
+ typename graph_traits::vertex_iterator u_iter, u_end;
+
+ weight_type bestW = (std::numeric_limits::max)();
+ weight_type bestThisTime = (std::numeric_limits::max)();
+ vertex_descriptor bestStart;
+
+ detail::mas_min_cut_visitor
+ vis(parities, bestThisTime, weights);
+
+ // for each node in the graph,
+ for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
+ // run the MAS and find the min cut
+ vis.clear();
+ boost::maximum_adjacency_search(g,
+ boost::vertex_assignment_map(assignments).
+ weight_map(weights).
+ visitor(vis).
+ root_vertex(*u_iter).
+ max_priority_queue(pq));
+ if (bestThisTime < bestW) {
+ bestW = bestThisTime;
+ bestStart = *u_iter;
+ }
+ }
+
+ // Run one more time, starting from the best start location, to
+ // ensure the visitor has the best values.
+ vis.clear();
+ boost::maximum_adjacency_search(g,
+ boost::vertex_assignment_map(assignments).
+ weight_map(weights).
+ visitor(vis).
+ root_vertex(bestStart).
+ max_priority_queue(pq));
+
+ return bestW;
+ }
+ } // end `namespace detail` within `namespace boost`
+
+ template
+ typename boost::property_traits::value_type
+ stoer_wagner_min_cut(const UndirectedGraph& g, WeightMap weights, ParityMap parities, VertexAssignmentMap assignments, KeyedUpdatablePriorityQueue& pq) {
BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept));
BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept));
typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor;
@@ -151,91 +187,48 @@
BOOST_CONCEPT_ASSERT((boost::ReadWritePropertyMapConcept));
BOOST_CONCEPT_ASSERT((boost::Convertible::value_type>));
BOOST_CONCEPT_ASSERT((boost::KeyedUpdatableQueueConcept));
-
+
vertices_size_type n = num_vertices(g);
if (n < 2)
throw boost::bad_graph("the input graph must have at least two vertices.");
else if (!pq.empty())
throw std::invalid_argument("the max-priority queue must be empty initially.");
-
- std::set assignedVertices;
-
- // initialize `assignments` (all vertices are initially assigned to themselves)
- BGL_FORALL_VERTICES_T(v, g, UndirectedGraph) {
- put(assignments, v, v);
+
+ return detail::stoer_wagner_min_cut(g, weights,
+ parities, assignments, pq);
+ }
+
+namespace graph {
+ namespace detail {
+ template
+ struct stoer_wagner_min_cut_impl {
+ typedef typename boost::property_traits::value_type result_type;
+ template
+ result_type operator() (const UndirectedGraph& g, WeightMap weights, const ArgPack& arg_pack) const {
+ using namespace boost::graph::keywords;
+ typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor;
+ typedef typename std::vector::size_type heap_container_size_type;
+ typedef typename boost::property_traits::value_type weight_type;
+ typedef typename boost::property_map::type index_map;
+ typedef boost::detail::make_priority_queue_from_arg_pack_gen > gen_type;
+ gen_type gen(choose_param(get_param(arg_pack, boost::distance_zero_t()), weight_type(0)));
+ typename boost::result_of::type pq = gen(g, arg_pack);
+
+ return boost::stoer_wagner_min_cut(g,
+ weights,
+ arg_pack[_parity_map | boost::make_one_bit_color_map(num_vertices(g),get(boost::vertex_index, g))],
+ boost::detail::make_property_map_from_arg_pack_gen(vertex_descriptor())(g, arg_pack),
+ pq
+ );
}
-
- vertex_descriptor s, t;
- weight_type bestW;
-
- boost::tie(s, t, bestW) = boost::detail::stoer_wagner_phase(g, assignments, assignedVertices, weights, pq);
- BOOST_ASSERT(s != t);
- BGL_FORALL_VERTICES_T(v, g, UndirectedGraph) {
- put(parities, v, parity_type(v == t ? 1 : 0));
- }
- put(assignments, t, s);
- assignedVertices.insert(t);
- --n;
-
- for (; n >= 2; --n) {
- weight_type w;
- boost::tie(s, t, w) = boost::detail::stoer_wagner_phase(g, assignments, assignedVertices, weights, pq);
- BOOST_ASSERT(s != t);
-
- if (w < bestW) {
- BGL_FORALL_VERTICES_T(v, g, UndirectedGraph) {
- put(parities, v, parity_type(get(assignments, v) == t ? 1 : 0));
-
- if (get(assignments, v) == t) // all vertices that were assigned to t are now assigned to s
- put(assignments, v, s);
- }
-
- bestW = w;
- } else {
- BGL_FORALL_VERTICES_T(v, g, UndirectedGraph) {
- if (get(assignments, v) == t) // all vertices that were assigned to t are now assigned to s
- put(assignments, v, s);
- }
- }
- put(assignments, t, s);
- assignedVertices.insert(t);
- }
-
- BOOST_ASSERT(pq.empty());
-
- return bestW;
- }
-
- } // end `namespace detail` within `namespace boost`
-
- template
- inline typename boost::property_traits::value_type
- stoer_wagner_min_cut(const UndirectedGraph& g, WeightMap weights, const boost::bgl_named_params& params) {
- typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor;
- typedef typename std::vector::size_type heap_container_size_type;
- typedef typename boost::property_traits::value_type weight_type;
-
- typedef boost::bgl_named_params params_type;
- BOOST_GRAPH_DECLARE_CONVERTED_PARAMETERS(params_type, params)
-
- typedef boost::detail::make_priority_queue_from_arg_pack_gen > gen_type;
- gen_type gen(choose_param(get_param(params, boost::distance_zero_t()), weight_type(0)));
- typename boost::result_of::type pq = gen(g, arg_pack);
-
- return boost::detail::stoer_wagner_min_cut(g,
- weights,
- choose_param(get_param(params, boost::parity_map_t()), boost::dummy_property_map()),
- boost::detail::make_property_map_from_arg_pack_gen(vertex_descriptor())(g, arg_pack),
- pq
- );
+ };
}
-
- template
- inline typename boost::property_traits::value_type
- stoer_wagner_min_cut(const UndirectedGraph& g, WeightMap weights) {
- return boost::stoer_wagner_min_cut(g, weights, boost::vertex_index_map(get(boost::vertex_index, g)));
- }
-
+ BOOST_GRAPH_MAKE_FORWARDING_FUNCTION(stoer_wagner_min_cut,2,3)
+}
+
+ // Named parameter interface
+ BOOST_GRAPH_MAKE_OLD_STYLE_PARAMETER_FUNCTION(stoer_wagner_min_cut, 2)
+
} // end `namespace boost`
#include
Index: libs/graph/doc/maximum_adjacency_search.html
===================================================================
--- libs/graph/doc/maximum_adjacency_search.html (revision 0)
+++ libs/graph/doc/maximum_adjacency_search.html (working copy)
@@ -0,0 +1,283 @@
+
+
+
+Boost Graph Library: Maximum Adjacency Search
+
+
+
+
+maximum_adjacency_search
+
+
+
+
+// named parameter versions
+template <class Graph, class class P, class T, class R>
+tuple<typename graph_traits<Graph>::vertex_descriptor,
+ typename graph_traits<Graph>::vertex_descriptor,
+ unsigned long>
+maximum_adjacency_search(const Graph& g,
+ const bgl_named_params<P, T, R>& params);
+
+// non-named parameter versions
+template <class Graph, class WeightMap, class MASVisitor>
+tuple<typename graph_traits<Graph>::vertex_descriptor,
+ typename graph_traits<Graph>::vertex_descriptor,
+ unsigned long>
+maximum_adjacency_search(const Graph& g, WeightMap weights, MASVisitor vis,
+ const typename graph_traits<Graph>::vertex_descriptor start);
+
+
+
+
+The maximum_adjacency_search() function performs a traversal
+of the vertices in an undirected graph. The next vertex visited is the
+vertex that has the most visited neighbors at any time. In the case of
+an unweighted, undirected graph, the number of visited neighbors of the
+very last vertex visited in the graph is also the number of edge-disjoint
+paths between that vertex and the next-to-last vertex visited.
+
+
+
+The maximum_adjacency_search() function invokes user-defined
+actions at certain event-points within the algorithm. This provides a
+mechanism for adapting the generic MAS algorithm to the many situations
+in which it can be used. In the pseudo-code below, the event points
+for MAS are the labels on the right. The user-defined actions must be
+provided in the form of a visitor object, that is, an object whose type
+meets the requirements for a MAS Visitor.
+
+
+
+
+
+
+MAS(G)
+ for each vertex u in V
+ reach_count[u] := 0
+ end for
+ // for the starting vertex s
+ reach_count[s] := 1
+ for each unvisited vertex u in V
+ call MAS-VISIT(G, u)
+ remove u from the list on unvisited vertices
+ for each out edge from u to t
+ if t has not yet been visited
+ increment reach_count[t]
+ end if
+ end for each out edge
+ call MAS-VISIT(G, u)
+ end for each unvisited vertex
+
+ |
+
+
+-
+-
+initialize vertex u
+-
+-
+-
+-
+examine vertex u
+-
+examine edge (u,t)
+-
+-
+-
+-
+finish vertex u
+-
+
+ |
+
+
+
+Where Defined
+
+
+boost/graph/maximum_adjacency_search.hpp
+
+Parameters
+
+IN: const UndirectedGraph& g
+
+ A connected, directed graph. The graph type must
+ be a model of Incidence Graph
+ and Vertex List Graph.
+
+
+Named Parameters
+
+IN: WeightMap weights
+
+ The weight or length of each edge in the graph. The
+ WeightMap type must be a model of
+ Readable
+ Property Map and its value type must be
+ Less Than Comparable and summable. The key type of this map
+ needs to be the graph's edge descriptor type.
+ Default: get(edge_weight, g)
+
+
+IN: visitor(MASVisitor vis)
+
+ A visitor object that is invoked inside the algorithm at the
+ event-points specified by the MAS Visitor concept. The visitor
+ object is passed by value [1].
+ Default: mas_visitor<null_visitor>
+
+
+IN: root_vertex(typename
+graph_traits<VertexListGraph>::vertex_descriptor start)
+
+ This specifies the vertex that the depth-first search should
+ originate from. The type is the type of a vertex descriptor for the
+ given graph.
+ Default: *vertices(g).first
+
+
+Expert Parameters
+
+IN: vertex_index_map(VertexIndexMap vertexIndices)
+
+ This maps each vertex to an integer in the range
+ [0, num_vertices(g)). This is only necessary if the default is
+ used for the assignment, index-in-heap, or distance maps.
+ VertexIndexMap must be a model of Readable Property
+ Map. The value type of the map must be an integer type. The
+ key type must be the graph's vertex descriptor type.
+ Default: get(boost::vertex_index, g)
+ Note: if you use this default, make sure your graph has
+ an internal vertex_index property. For example,
+ adjacency_list with VertexList=listS does
+ not have an internal vertex_index property.
+
+
+UTIL: vertex_assignment_map(AssignmentMap assignments)
+
+ AssignmentMap must be a model of Read/Write Property
+ Map. The key and value types must be the graph's vertex descriptor
+ type.
+ Default: A boost::iterator_property_map using a
+ std::vector of num_vertices(g) vertex descriptors and
+ vertexIndices for the index map.
+
+
+UTIL: max_priority_queue(MaxPriorityQueue& pq)
+
+ MaxPriorityQueue must be a model of Keyed Updatable Queue and a
+ max-
+ Updatable Priority Queue. The value type must be the graph's vertex
+ descriptor and the key type must be the weight type.
+ Default: A boost::d_ary_heap_indirect using a default
+ index-in-heap and distance map.
+
+
+UTIL: index_in_heap_map(IndexInHeapMap indicesInHeap)
+
+ This parameter only has an effect when the default max-priority queue is used.
+ IndexInHeapMap must be a model of Read/Write Property
+ Map. The key type must be the graph's vertex descriptor type. The
+ value type must be a size type
+ (typename std::vector<vertex_descriptor>::size_type).
+ Default: A boost::iterator_property_map using a
+ std::vector of num_vertices(g) size type objects and
+ vertexIndices for the index map.
+
+
+UTIL: distance_map(DistanceMap wAs)
+
+ This parameter only has an effect when the default max-priority queue is used.
+ DistanceMap must be a model of Read/Write Property
+ Map. The key type must be the graph's vertex descriptor type. The
+ value type must be the weight type
+ (typename boost::property_traits<WeightMap>::value_type).
+
+ Default: A boost::iterator_property_map using a
+ std::vector of num_vertices(g) weight type objects
+ and vertexIndices for the index map.
+
+
+Returns
+The last 2 vertices visited, and the priority of the last vertex when
+removed. In an unweighted, undirected graph, this is the number of
+edge-disjoint paths between these 2 vertices.
+
+Throws
+
+bad_graph
+
+ If num_vertices(g) is less than 2
+
+
+std::invalid_argument
+
+ If a max-priority queue is given as an argument and it is not empty
+
.
+
+
+
+
+The time complexity is O(E + V).
+
+
+References
+
+
+Visitor Event Points
+
+
+- vis.initialize_vertex(s, g) is invoked on every
+ vertex of the graph before the start of the graph search.
+
+- vis.start_vertex(s, g) is invoked on the source
+ vertex once before processing its out edges.
+
+- vis.examine_edge(e, g) is invoked on every out-edge
+ of each vertex after it is started.
+
+- vis.finish_vertex(u, g) is invoked on a vertex after
+ all of its out edges have been examined and the reach counts of the
+ unvisited targets have been updated.
+
+
+Notes
+
+[1]
+ Since the visitor parameter is passed by value, if your visitor
+ contains state then any changes to the state during the algorithm
+ will be made to a copy of the visitor object, not the visitor object
+ passed in. Therefore you may want the visitor to hold this state by
+ pointer or reference.
+
+
+
+
+Copyright © 2012 |
+Fernando Vilas
+ |
+
+
+