|
Boost-Commit : |
From: troy_at_[hidden]
Date: 2008-07-01 12:48:13
Author: troy
Date: 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
New Revision: 46964
URL: http://svn.boost.org/trac/boost/changeset/46964
Log:
use modularize targets, not externals to manage modularization
Added:
branches/CMake/release/libs/graph/include/boost/graph/
branches/CMake/release/libs/graph/include/boost/graph/adj_list_serialize.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/adjacency_iterator.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/adjacency_list.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/adjacency_list_io.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/adjacency_matrix.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/astar_search.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/bandwidth.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/bc_clustering.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/bellman_ford_shortest_paths.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/betweenness_centrality.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/biconnected_components.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/boyer_myrvold_planar_test.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/breadth_first_search.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/chrobak_payne_drawing.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/circle_layout.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/compressed_sparse_row_graph.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/connected_components.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/copy.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/create_condensation_graph.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/cuthill_mckee_ordering.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/dag_shortest_paths.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/depth_first_search.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/
branches/CMake/release/libs/graph/include/boost/graph/detail/adj_list_edge_iterator.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/adjacency_list.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/array_binary_tree.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/connected_components.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/edge.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/incidence_iterator.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/incremental_components.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/indexed_properties.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/is_same.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/list_base.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/permutation.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/read_graphviz_spirit.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/self_avoiding_walk.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/set_adaptor.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/shadow_iterator.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/detail/sparse_ordering.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/dijkstra_shortest_paths.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/dominator_tree.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/edge_connectivity.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/edge_list.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/edmunds_karp_max_flow.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/erdos_renyi_generator.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/exception.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/filtered_graph.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/floyd_warshall_shortest.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/fruchterman_reingold.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/graph_archetypes.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/graph_as_tree.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/graph_concepts.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/graph_selectors.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/graph_test.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/graph_traits.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/graph_utility.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/graphml.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/graphviz.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/gursoy_atun_layout.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/howard_cycle_ratio.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/incremental_components.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/is_kuratowski_subgraph.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/is_straight_line_drawing.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/isomorphism.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/iteration_macros.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/iteration_macros_undef.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/johnson_all_pairs_shortest.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/kamada_kawai_spring_layout.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/king_ordering.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/kolmogorov_max_flow.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/kruskal_min_spanning_tree.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/leda_graph.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/make_biconnected_planar.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/make_connected.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/make_maximal_planar.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/matrix_as_graph.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/max_cardinality_matching.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/minimum_degree_ordering.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/named_function_params.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/neighbor_bfs.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/page_rank.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/planar_canonical_ordering.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/planar_detail/
branches/CMake/release/libs/graph/include/boost/graph/planar_detail/add_edge_visitors.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/planar_detail/boyer_myrvold_impl.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/planar_detail/bucket_sort.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/planar_detail/face_handles.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/planar_detail/face_iterators.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/planar_face_traversal.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/plod_generator.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/prim_minimum_spanning_tree.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/profile.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/properties.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/property_iter_range.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/push_relabel_max_flow.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/random.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/random_layout.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/read_dimacs.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/relax.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/reverse_graph.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/sequential_vertex_coloring.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/simple_point.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/sloan_ordering.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/small_world_generator.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/smallest_last_ordering.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/stanford_graph.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/strong_components.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/subgraph.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/topological_sort.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/transitive_closure.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/transpose_graph.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/tree_traits.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/two_bit_color_map.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/undirected_dfs.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/vector_as_graph.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/visitors.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/wavefront.hpp (contents, props changed)
branches/CMake/release/libs/graph/include/boost/graph/write_dimacs.hpp (contents, props changed)
Properties modified:
branches/CMake/release/libs/graph/include/boost/ (props changed)
Added: branches/CMake/release/libs/graph/include/boost/graph/adj_list_serialize.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/adj_list_serialize.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,114 @@
+//=======================================================================
+// Copyright 2005 Jeremy G. Siek
+// Authors: Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+#ifndef ADJ_LIST_SERIALIZE_HPP
+#define ADJ_LIST_SERIALIZE_HPP
+
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/pending/property_serialize.hpp>
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+#include <boost/serialization/collections_save_imp.hpp>
+#include <boost/serialization/collections_load_imp.hpp>
+#include <boost/serialization/split_free.hpp>
+
+namespace boost {
+
+namespace serialization {
+
+// Turn off tracking for adjacency_list. It's not polymorphic, and we
+// need to do this to enable saving of non-const adjacency lists.
+template<class OEL, class VL, class D, class VP, class EP, class GP, class EL>
+struct tracking_level<boost::adjacency_list<OEL,VL,D,VP,EP,GP,EL> > {
+ typedef mpl::integral_c_tag tag;
+ typedef mpl::int_<track_never> type;
+ BOOST_STATIC_CONSTANT(int, value = tracking_level::type::value);
+};
+
+template<class Archive, class OEL, class VL, class D,
+ class VP, class EP, class GP, class EL>
+inline void save(
+ Archive & ar,
+ const boost::adjacency_list<OEL,VL,D,VP,EP,GP,EL> &graph,
+ const unsigned int /* file_version */
+){
+ typedef adjacency_list<OEL,VL,D,VP,EP,GP,EL> Graph;
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+
+ int V = num_vertices(graph);
+ int E = num_edges(graph);
+ ar << BOOST_SERIALIZATION_NVP(V);
+ ar << BOOST_SERIALIZATION_NVP(E);
+
+ // assign indices to vertices
+ std::map<Vertex,int> indices;
+ int num = 0;
+ typename graph_traits<Graph>::vertex_iterator vi;
+ for (vi = vertices(graph).first; vi != vertices(graph).second; ++vi) {
+ indices[*vi] = num++;
+ ar << serialization::make_nvp("vertex_property", get(vertex_all_t(), graph, *vi) );
+ }
+
+ // write edges
+ typename graph_traits<Graph>::edge_iterator ei;
+ for (ei = edges(graph).first; ei != edges(graph).second; ++ei){
+ ar << serialization::make_nvp("u" , indices[source(*ei,graph)]);
+ ar << serialization::make_nvp("v" , indices[target(*ei,graph)]);
+ ar << serialization::make_nvp("edge_property", get(edge_all_t(), graph, *ei) );
+ }
+}
+
+
+template<class Archive, class OEL, class VL, class D,
+ class VP, class EP, class GP, class EL>
+inline void load(
+ Archive & ar,
+ boost::adjacency_list<OEL,VL,D,VP,EP,GP,EL> &graph,
+ const unsigned int /* file_version */
+){
+ typedef adjacency_list<OEL,VL,D,VP,EP,GP,EL> Graph;
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename graph_traits<Graph>::edge_descriptor Edge;
+
+ unsigned int V;
+ ar >> BOOST_SERIALIZATION_NVP(V);
+ unsigned int E;
+ ar >> BOOST_SERIALIZATION_NVP(E);
+
+ std::vector<Vertex> verts(V);
+ int i = 0;
+ while(V-- > 0){
+ Vertex v = add_vertex(graph);
+ verts[i++] = v;
+ ar >> serialization::make_nvp("vertex_property", get(vertex_all_t(), graph, v) );
+ }
+ while(E-- > 0){
+ int u; int v;
+ ar >> BOOST_SERIALIZATION_NVP(u);
+ ar >> BOOST_SERIALIZATION_NVP(v);
+ Edge e; bool inserted;
+ tie(e,inserted) = add_edge(verts[u], verts[v], graph);
+ ar >> serialization::make_nvp("edge_property", get(edge_all_t(), graph, e) );
+ }
+}
+
+template<class Archive, class OEL, class VL, class D, class VP, class EP, class GP, class EL>
+inline void serialize(
+ Archive & ar,
+ boost::adjacency_list<OEL,VL,D,VP,EP,GP,EL> &graph,
+ const unsigned int file_version
+){
+ boost::serialization::split_free(ar, graph, file_version);
+}
+
+}//serialization
+}//boost
+
+
+#endif // ADJ_LIST_SERIALIZE_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/adjacency_iterator.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/adjacency_iterator.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,102 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_ADJACENCY_ITERATOR_HPP
+#define BOOST_ADJACENCY_ITERATOR_HPP
+
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/graph/graph_traits.hpp>
+
+namespace boost
+{
+
+ template <class Graph, class Vertex, class OutEdgeIter, class Difference>
+ struct adjacency_iterator
+ : iterator_adaptor<
+ adjacency_iterator<Graph,Vertex,OutEdgeIter,Difference>
+ , OutEdgeIter
+ , Vertex
+ , use_default
+ , Vertex
+ , Difference
+ >
+ {
+ typedef iterator_adaptor<
+ adjacency_iterator<Graph,Vertex,OutEdgeIter,Difference>
+ , OutEdgeIter
+ , Vertex
+ , use_default
+ , Vertex
+ , Difference
+ > super_t;
+
+ inline adjacency_iterator() {}
+ inline adjacency_iterator(OutEdgeIter const& i, const Graph* g) : super_t(i), m_g(g) { }
+
+ inline Vertex
+ dereference() const
+ { return target(*this->base(), *m_g); }
+
+ const Graph* m_g;
+ };
+
+ template <class Graph,
+ class Vertex = typename graph_traits<Graph>::vertex_descriptor,
+ class OutEdgeIter=typename graph_traits<Graph>::out_edge_iterator>
+ class adjacency_iterator_generator
+ {
+ typedef typename boost::detail::iterator_traits<OutEdgeIter>
+ ::difference_type difference_type;
+ public:
+ typedef adjacency_iterator<Graph,Vertex,OutEdgeIter,difference_type> type;
+ };
+
+ template <class Graph, class Vertex, class InEdgeIter, class Difference>
+ struct inv_adjacency_iterator
+ : iterator_adaptor<
+ inv_adjacency_iterator<Graph,Vertex,InEdgeIter,Difference>
+ , InEdgeIter
+ , Vertex
+ , use_default
+ , Vertex
+ , Difference
+ >
+ {
+ typedef iterator_adaptor<
+ inv_adjacency_iterator<Graph,Vertex,InEdgeIter,Difference>
+ , InEdgeIter
+ , Vertex
+ , use_default
+ , Vertex
+ , Difference
+ > super_t;
+
+ inline inv_adjacency_iterator() { }
+ inline inv_adjacency_iterator(InEdgeIter const& i, const Graph* g) : super_t(i), m_g(g) { }
+
+ inline Vertex
+ dereference() const
+ { return source(*this->base(), *m_g); }
+
+ const Graph* m_g;
+ };
+
+ template <class Graph,
+ class Vertex = typename graph_traits<Graph>::vertex_descriptor,
+ class InEdgeIter = typename graph_traits<Graph>::in_edge_iterator>
+ class inv_adjacency_iterator_generator {
+ typedef typename boost::detail::iterator_traits<InEdgeIter>
+ ::difference_type difference_type;
+ public:
+ typedef inv_adjacency_iterator<Graph, Vertex, InEdgeIter, difference_type> type;
+ };
+
+} // namespace boost
+
+#endif // BOOST_DETAIL_ADJACENCY_ITERATOR_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/adjacency_list.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/adjacency_list.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,564 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_ADJACENCY_LIST_HPP
+#define BOOST_GRAPH_ADJACENCY_LIST_HPP
+
+
+#include <boost/config.hpp>
+
+#include <vector>
+#include <list>
+#include <set>
+
+#if !defined BOOST_NO_HASH
+# ifdef BOOST_HASH_SET_HEADER
+# include BOOST_HASH_SET_HEADER
+# else
+# include <hash_set>
+# endif
+#endif
+
+#if !defined BOOST_NO_SLIST
+# ifdef BOOST_SLIST_HEADER
+# include BOOST_SLIST_HEADER
+# else
+# include <slist>
+# endif
+#endif
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_selectors.hpp>
+#include <boost/property_map.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/graph/detail/edge.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/graph/properties.hpp>
+
+namespace boost {
+
+ //===========================================================================
+ // Selectors for the VertexList and EdgeList template parameters of
+ // adjacency_list, and the container_gen traits class which is used
+ // to map the selectors to the container type used to implement the
+ // graph.
+ //
+ // The main container_gen traits class uses partial specialization,
+ // so we also include a workaround.
+
+#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+#if !defined BOOST_NO_SLIST
+ struct slistS {};
+#endif
+
+ struct vecS { };
+ struct listS { };
+ struct setS { };
+ struct multisetS { };
+ struct mapS { };
+#if !defined BOOST_NO_HASH
+ struct hash_mapS { };
+ struct hash_setS { };
+#endif
+
+ template <class Selector, class ValueType>
+ struct container_gen { };
+
+ template <class ValueType>
+ struct container_gen<listS, ValueType> {
+ typedef std::list<ValueType> type;
+ };
+#if !defined BOOST_NO_SLIST
+ template <class ValueType>
+ struct container_gen<slistS, ValueType> {
+ typedef BOOST_STD_EXTENSION_NAMESPACE::slist<ValueType> type;
+ };
+#endif
+ template <class ValueType>
+ struct container_gen<vecS, ValueType> {
+ typedef std::vector<ValueType> type;
+ };
+
+ template <class ValueType>
+ struct container_gen<mapS, ValueType> {
+ typedef std::set<ValueType> type;
+ };
+
+ template <class ValueType>
+ struct container_gen<setS, ValueType> {
+ typedef std::set<ValueType> type;
+ };
+
+ template <class ValueType>
+ struct container_gen<multisetS, ValueType> {
+ typedef std::multiset<ValueType> type;
+ };
+
+#if !defined BOOST_NO_HASH
+ template <class ValueType>
+ struct container_gen<hash_mapS, ValueType> {
+ typedef BOOST_STD_EXTENSION_NAMESPACE::hash_set<ValueType> type;
+ };
+
+ template <class ValueType>
+ struct container_gen<hash_setS, ValueType> {
+ typedef BOOST_STD_EXTENSION_NAMESPACE::hash_set<ValueType> type;
+ };
+#endif
+
+#else // !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+#if !defined BOOST_NO_SLIST
+ struct slistS {
+ template <class T>
+ struct bind_ { typedef BOOST_STD_EXTENSION_NAMESPACE::slist<T> type; };
+ };
+#endif
+
+ struct vecS {
+ template <class T>
+ struct bind_ { typedef std::vector<T> type; };
+ };
+
+ struct listS {
+ template <class T>
+ struct bind_ { typedef std::list<T> type; };
+ };
+
+ struct setS {
+ template <class T>
+ struct bind_ { typedef std::set<T, std::less<T> > type; };
+ };
+
+ struct multisetS {
+ template <class T>
+ struct bind_ { typedef std::multiset<T, std::less<T> > type; };
+ };
+
+#if !defined BOOST_NO_HASH
+ struct hash_setS {
+ template <class T>
+ struct bind_ { typedef BOOST_STD_EXTENSION_NAMESPACE::hash_set<T, std::less<T> > type; };
+ };
+#endif
+
+ struct mapS {
+ template <class T>
+ struct bind_ { typedef std::set<T, std::less<T> > type; };
+ };
+
+#if !defined BOOST_NO_HASH
+ struct hash_mapS {
+ template <class T>
+ struct bind_ { typedef BOOST_STD_EXTENSION_NAMESPACE::hash_set<T, std::less<T> > type; };
+ };
+#endif
+
+ template <class Selector> struct container_selector {
+ typedef vecS type;
+ };
+
+#define BOOST_CONTAINER_SELECTOR(NAME) \
+ template <> struct container_selector<NAME> { \
+ typedef NAME type; \
+ }
+
+ BOOST_CONTAINER_SELECTOR(vecS);
+ BOOST_CONTAINER_SELECTOR(listS);
+ BOOST_CONTAINER_SELECTOR(mapS);
+ BOOST_CONTAINER_SELECTOR(setS);
+ BOOST_CONTAINER_SELECTOR(multisetS);
+#if !defined BOOST_NO_HASH
+ BOOST_CONTAINER_SELECTOR(hash_mapS);
+#endif
+#if !defined BOOST_NO_SLIST
+ BOOST_CONTAINER_SELECTOR(slistS);
+#endif
+
+ template <class Selector, class ValueType>
+ struct container_gen {
+ typedef typename container_selector<Selector>::type Select;
+ typedef typename Select:: template bind_<ValueType>::type type;
+ };
+
+#endif // !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+ template <class StorageSelector>
+ struct parallel_edge_traits { };
+
+ template <>
+ struct parallel_edge_traits<vecS> {
+ typedef allow_parallel_edge_tag type; };
+
+ template <>
+ struct parallel_edge_traits<listS> {
+ typedef allow_parallel_edge_tag type; };
+
+#if !defined BOOST_NO_SLIST
+ template <>
+ struct parallel_edge_traits<slistS> {
+ typedef allow_parallel_edge_tag type; };
+#endif
+
+ template <>
+ struct parallel_edge_traits<setS> {
+ typedef disallow_parallel_edge_tag type; };
+
+ template <>
+ struct parallel_edge_traits<multisetS> {
+ typedef allow_parallel_edge_tag type; };
+
+#if !defined BOOST_NO_HASH
+ template <>
+ struct parallel_edge_traits<hash_setS> {
+ typedef disallow_parallel_edge_tag type;
+ };
+#endif
+
+ // mapS is obsolete, replaced with setS
+ template <>
+ struct parallel_edge_traits<mapS> {
+ typedef disallow_parallel_edge_tag type; };
+
+#if !defined BOOST_NO_HASH
+ template <>
+ struct parallel_edge_traits<hash_mapS> {
+ typedef disallow_parallel_edge_tag type;
+ };
+#endif
+
+ namespace detail {
+ template <class Directed> struct is_random_access {
+ enum { value = false};
+ typedef mpl::false_ type;
+ };
+ template <>
+ struct is_random_access<vecS> {
+ enum { value = true };
+ typedef mpl::true_ type;
+ };
+
+ } // namespace detail
+
+
+
+ //===========================================================================
+ // The adjacency_list_traits class, which provides a way to access
+ // some of the associated types of an adjacency_list type without
+ // having to first create the adjacency_list type. This is useful
+ // when trying to create interior vertex or edge properties who's
+ // value type is a vertex or edge descriptor.
+
+ template <class OutEdgeListS = vecS,
+ class VertexListS = vecS,
+ class DirectedS = directedS,
+ class EdgeListS = listS>
+ struct adjacency_list_traits
+ {
+ typedef typename detail::is_random_access<VertexListS>::type
+ is_rand_access;
+ typedef typename DirectedS::is_bidir_t is_bidir;
+ typedef typename DirectedS::is_directed_t is_directed;
+
+ typedef typename mpl::if_<is_bidir,
+ bidirectional_tag,
+ typename mpl::if_<is_directed,
+ directed_tag, undirected_tag
+ >::type
+ >::type directed_category;
+
+ typedef typename parallel_edge_traits<OutEdgeListS>::type
+ edge_parallel_category;
+
+ typedef void* vertex_ptr;
+ typedef typename mpl::if_<is_rand_access,
+ std::size_t, vertex_ptr>::type vertex_descriptor;
+ typedef detail::edge_desc_impl<directed_category, vertex_descriptor>
+ edge_descriptor;
+
+ typedef std::size_t vertices_size_type;
+
+ private:
+ // Logic to figure out the edges_size_type
+ struct dummy {};
+ typedef typename container_gen<EdgeListS, dummy>::type EdgeContainer;
+ typedef typename DirectedS::is_bidir_t BidirectionalT;
+ typedef typename DirectedS::is_directed_t DirectedT;
+ typedef typename mpl::and_<DirectedT,
+ typename mpl::not_<BidirectionalT>::type >::type on_edge_storage;
+ public:
+ typedef typename mpl::if_<on_edge_storage,
+ std::size_t, typename EdgeContainer::size_type
+ >::type edges_size_type;
+
+ };
+
+} // namespace boost
+
+#include <boost/graph/detail/adjacency_list.hpp>
+
+namespace boost {
+
+ //===========================================================================
+ // The adjacency_list class.
+ //
+
+ template <class OutEdgeListS = vecS, // a Sequence or an AssociativeContainer
+ class VertexListS = vecS, // a Sequence or a RandomAccessContainer
+ class DirectedS = directedS,
+ class VertexProperty = no_property,
+ class EdgeProperty = no_property,
+ class GraphProperty = no_property,
+ class EdgeListS = listS>
+ class adjacency_list
+ : public detail::adj_list_gen<
+ adjacency_list<OutEdgeListS,VertexListS,DirectedS,
+ VertexProperty,EdgeProperty,GraphProperty,EdgeListS>,
+ VertexListS, OutEdgeListS, DirectedS,
+#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
+ typename detail::retag_property_list<vertex_bundle_t,
+ VertexProperty>::type,
+ typename detail::retag_property_list<edge_bundle_t, EdgeProperty>::type,
+#else
+ VertexProperty, EdgeProperty,
+#endif
+ GraphProperty, EdgeListS>::type
+ {
+#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
+ typedef typename detail::retag_property_list<vertex_bundle_t,
+ VertexProperty>::retagged
+ maybe_vertex_bundled;
+
+ typedef typename detail::retag_property_list<edge_bundle_t,
+ EdgeProperty>::retagged
+ maybe_edge_bundled;
+#endif
+
+ public:
+#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
+ typedef typename detail::retag_property_list<vertex_bundle_t,
+ VertexProperty>::type
+ vertex_property_type;
+ typedef typename detail::retag_property_list<edge_bundle_t,
+ EdgeProperty>::type
+ edge_property_type;
+
+ // The types that are actually bundled
+ typedef typename mpl::if_c<(is_same<maybe_vertex_bundled, no_property>::value),
+ no_vertex_bundle,
+ maybe_vertex_bundled>::type vertex_bundled;
+ typedef typename mpl::if_c<(is_same<maybe_edge_bundled, no_property>::value),
+ no_edge_bundle,
+ maybe_edge_bundled>::type edge_bundled;
+#else
+ typedef VertexProperty vertex_property_type;
+ typedef EdgeProperty edge_property_type;
+ typedef no_vertex_bundle vertex_bundled;
+ typedef no_edge_bundle edge_bundled;
+#endif
+
+ private:
+ typedef adjacency_list self;
+ typedef typename detail::adj_list_gen<
+ self, VertexListS, OutEdgeListS, DirectedS,
+ vertex_property_type, edge_property_type, GraphProperty, EdgeListS
+ >::type Base;
+
+ public:
+ typedef typename Base::stored_vertex stored_vertex;
+ typedef typename Base::vertices_size_type vertices_size_type;
+ typedef typename Base::edges_size_type edges_size_type;
+ typedef typename Base::degree_size_type degree_size_type;
+ typedef typename Base::vertex_descriptor vertex_descriptor;
+ typedef typename Base::edge_descriptor edge_descriptor;
+ typedef OutEdgeListS out_edge_list_selector;
+ typedef VertexListS vertex_list_selector;
+ typedef DirectedS directed_selector;
+ typedef EdgeListS edge_list_selector;
+
+ typedef GraphProperty graph_property_type;
+
+ inline adjacency_list(const GraphProperty& p = GraphProperty())
+ : m_property(p) { }
+
+ inline adjacency_list(const adjacency_list& x)
+ : Base(x), m_property(x.m_property) { }
+
+ inline adjacency_list& operator=(const adjacency_list& x) {
+ // TBD: probably should give the strong guarantee
+ if (&x != this) {
+ Base::operator=(x);
+ m_property = x.m_property;
+ }
+ return *this;
+ }
+
+ // Required by Mutable Graph
+ inline adjacency_list(vertices_size_type num_vertices,
+ const GraphProperty& p = GraphProperty())
+ : Base(num_vertices), m_property(p) { }
+
+#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300
+ // Required by Iterator Constructible Graph
+ template <class EdgeIterator>
+ inline adjacency_list(EdgeIterator first, EdgeIterator last,
+ vertices_size_type n,
+ edges_size_type = 0,
+ const GraphProperty& p = GraphProperty())
+ : Base(n, first, last), m_property(p) { }
+
+ template <class EdgeIterator, class EdgePropertyIterator>
+ inline adjacency_list(EdgeIterator first, EdgeIterator last,
+ EdgePropertyIterator ep_iter,
+ vertices_size_type n,
+ edges_size_type = 0,
+ const GraphProperty& p = GraphProperty())
+ : Base(n, first, last, ep_iter), m_property(p) { }
+#endif
+
+ void swap(adjacency_list& x) {
+ // Is there a more efficient way to do this?
+ adjacency_list tmp(x);
+ x = *this;
+ *this = tmp;
+ }
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ // Directly access a vertex or edge bundle
+ vertex_bundled& operator[](vertex_descriptor v)
+ { return get(vertex_bundle, *this)[v]; }
+
+ const vertex_bundled& operator[](vertex_descriptor v) const
+ { return get(vertex_bundle, *this)[v]; }
+
+ edge_bundled& operator[](edge_descriptor e)
+ { return get(edge_bundle, *this)[e]; }
+
+ const edge_bundled& operator[](edge_descriptor e) const
+ { return get(edge_bundle, *this)[e]; }
+#endif
+
+ // protected: (would be protected if friends were more portable)
+ GraphProperty m_property;
+ };
+
+ template <class OEL, class VL, class DirS, class VP,class EP, class GP,
+ class EL, class Tag, class Value>
+ inline void
+ set_property(adjacency_list<OEL,VL,DirS,VP,EP,GP,EL>& g, Tag,
+ const Value& value) {
+ get_property_value(g.m_property, Tag()) = value;;
+ }
+
+ template <class OEL, class VL, class DirS, class VP, class EP, class GP,
+ class Tag, class EL>
+ inline
+ typename graph_property<adjacency_list<OEL,VL,DirS,VP,EP,GP,EL>, Tag>::type&
+ get_property(adjacency_list<OEL,VL,DirS,VP,EP,GP,EL>& g, Tag) {
+ return get_property_value(g.m_property, Tag());
+ }
+
+ template <class OEL, class VL, class DirS, class VP, class EP, class GP,
+ class Tag, class EL>
+ inline
+ const
+ typename graph_property<adjacency_list<OEL,VL,DirS,VP,EP,GP,EL>, Tag>::type&
+ get_property(const adjacency_list<OEL,VL,DirS,VP,EP,GP,EL>& g, Tag) {
+ return get_property_value(g.m_property, Tag());
+ }
+
+ // dwa 09/25/00 - needed to be more explicit so reverse_graph would work.
+ template <class Directed, class Vertex,
+ class OutEdgeListS,
+ class VertexListS,
+ class DirectedS,
+ class VertexProperty,
+ class EdgeProperty,
+ class GraphProperty, class EdgeListS>
+ inline Vertex
+ source(const detail::edge_base<Directed,Vertex>& e,
+ const adjacency_list<OutEdgeListS, VertexListS, DirectedS,
+ VertexProperty, EdgeProperty, GraphProperty, EdgeListS>&)
+ {
+ return e.m_source;
+ }
+
+ template <class Directed, class Vertex, class OutEdgeListS,
+ class VertexListS, class DirectedS, class VertexProperty,
+ class EdgeProperty, class GraphProperty, class EdgeListS>
+ inline Vertex
+ target(const detail::edge_base<Directed,Vertex>& e,
+ const adjacency_list<OutEdgeListS, VertexListS, DirectedS,
+ VertexProperty, EdgeProperty, GraphProperty, EdgeListS>&)
+ {
+ return e.m_target;
+ }
+
+ // Support for bundled properties
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ template<typename OutEdgeListS, typename VertexListS, typename DirectedS, typename VertexProperty,
+ typename EdgeProperty, typename GraphProperty, typename EdgeListS, typename T, typename Bundle>
+ inline
+ typename property_map<adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty, EdgeProperty,
+ GraphProperty, EdgeListS>, T Bundle::*>::type
+ get(T Bundle::* p, adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty, EdgeProperty,
+ GraphProperty, EdgeListS>& g)
+ {
+ typedef typename property_map<adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty,
+ EdgeProperty, GraphProperty, EdgeListS>, T Bundle::*>::type
+ result_type;
+ return result_type(&g, p);
+ }
+
+ template<typename OutEdgeListS, typename VertexListS, typename DirectedS, typename VertexProperty,
+ typename EdgeProperty, typename GraphProperty, typename EdgeListS, typename T, typename Bundle>
+ inline
+ typename property_map<adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty, EdgeProperty,
+ GraphProperty, EdgeListS>, T Bundle::*>::const_type
+ get(T Bundle::* p, adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty, EdgeProperty,
+ GraphProperty, EdgeListS> const & g)
+ {
+ typedef typename property_map<adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty,
+ EdgeProperty, GraphProperty, EdgeListS>, T Bundle::*>::const_type
+ result_type;
+ return result_type(&g, p);
+ }
+
+ template<typename OutEdgeListS, typename VertexListS, typename DirectedS, typename VertexProperty,
+ typename EdgeProperty, typename GraphProperty, typename EdgeListS, typename T, typename Bundle,
+ typename Key>
+ inline T
+ get(T Bundle::* p, adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty, EdgeProperty,
+ GraphProperty, EdgeListS> const & g, const Key& key)
+ {
+ return get(get(p, g), key);
+ }
+
+ template<typename OutEdgeListS, typename VertexListS, typename DirectedS, typename VertexProperty,
+ typename EdgeProperty, typename GraphProperty, typename EdgeListS, typename T, typename Bundle,
+ typename Key>
+ inline void
+ put(T Bundle::* p, adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty, EdgeProperty,
+ GraphProperty, EdgeListS>& g, const Key& key, const T& value)
+ {
+ put(get(p, g), key, value);
+ }
+
+#endif
+
+
+} // namespace boost
+
+
+#endif // BOOST_GRAPH_ADJACENCY_LIST_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/adjacency_list_io.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/adjacency_list_io.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,408 @@
+//=======================================================================
+// Copyright 2001 Universite Joseph Fourier, Grenoble.
+// Author: François Faure
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_GRAPH_ADJACENCY_LIST_IO_HPP
+#define BOOST_GRAPH_ADJACENCY_LIST_IO_HPP
+
+#include <iostream>
+#include <vector>
+#include <boost/graph/adjacency_list.hpp>
+#include <cctype>
+
+// Method read to parse an adjacency list from an input stream. Examples:
+// cin >> read( G );
+// cin >> read( G, NodePropertySubset(), EdgepropertySubset() );
+//
+// Method write to print an adjacency list to an output stream. Examples:
+// cout << write( G );
+// cout << write( G, NodePropertySubset(), EdgepropertySubset() );
+
+namespace boost {
+
+/* outline
+ - basic property input
+ - get property subset
+ - graph parser
+ - property printer
+ - graph printer
+ - user methods
+*/
+
+//===========================================================================
+// basic property input
+
+template<class Tag, class Value, class Next>
+std::istream& operator >> ( std::istream& in, property<Tag,Value,Next>& p )
+{
+ in >> p.m_value >> *(static_cast<Next*>(&p)); // houpla !!
+ return in;
+}
+
+template<class Tag, class Value>
+std::istream& operator >> ( std::istream& in, property<Tag,Value,no_property>& p )
+{
+ in >> p.m_value;
+ return in;
+}
+
+inline std::istream& operator >> ( std::istream& in, no_property& )
+{
+ return in;
+}
+
+// basic property input
+//===========================================================================
+// get property subsets
+
+// get a single property tagged Stag
+template<class Tag, class Value, class Next, class V, class Stag>
+void get
+( property<Tag,Value,Next>& p, const V& v, Stag s )
+{
+ get( *(static_cast<Next*>(&p)),v,s );
+}
+
+template<class Value, class Next, class V, class Stag>
+void get
+( property<Stag,Value,Next>& p, const V& v, Stag )
+{
+ p.m_value = v;
+}
+
+// get a subset of properties tagged Stag
+template<class Tag, class Value, class Next,
+ class Stag, class Svalue, class Snext>
+void getSubset
+( property<Tag,Value,Next>& p, const property<Stag,Svalue,Snext>& s )
+{
+ get( p, s.m_value, Stag() );
+ getSubset( p, Snext(s) );
+}
+
+template<class Tag, class Value, class Next,
+ class Stag, class Svalue>
+void getSubset
+( property<Tag,Value,Next>& p, const property<Stag,Svalue,no_property>& s)
+{
+ get( p, s.m_value, Stag() );
+}
+
+inline void getSubset
+( no_property& p, const no_property& s )
+{
+}
+
+#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
+template<typename T, typename U>
+void getSubset(T& p, const U& s)
+{
+ p = s;
+}
+
+template<typename T>
+void getSubset(T&, const no_property&)
+{
+}
+
+
+#endif
+
+// get property subset
+//===========================================================================
+// graph parser
+typedef enum{ PARSE_NUM_NODES, PARSE_VERTEX, PARSE_EDGE } GraphParserState;
+
+template<class Graph_t, class VertexProperty, class EdgeProperty, class VertexPropertySubset,
+class EdgePropertySubset>
+struct GraphParser
+{
+
+ typedef Graph_t Graph;
+
+ GraphParser( Graph* g ): graph(g)
+ {}
+
+ GraphParser& operator () ( std::istream& in )
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ std::vector<Vertex> nodes;
+
+ GraphParserState state = PARSE_VERTEX;
+
+ unsigned int numLine = 1;
+ char c;
+ while ( in.get(c) )
+ {
+ if( c== '#' ) skip(in);
+ else if( c== 'n' ) state = PARSE_NUM_NODES;
+ else if( c== 'v' ) state = PARSE_VERTEX;
+ else if( c== 'e' ) state = PARSE_EDGE;
+ else if( c== '\n' ) numLine++;
+ else if( !std::isspace(c) ){
+ in.putback(c);
+ if( state == PARSE_VERTEX ){
+ VertexPropertySubset readProp;
+ if( in >> readProp )
+ {
+ VertexProperty vp;
+ getSubset( vp, readProp );
+ nodes.push_back( add_vertex(vp, *graph) );
+ }
+ else
+ std::cerr<<"read vertex, parse error at line"<<numLine<<std::endl;
+ }
+ else if( state == PARSE_EDGE ) {
+ int source, target;
+ EdgePropertySubset readProp;
+ in >> source >> target;
+ if( in >> readProp )
+ {
+ EdgeProperty ep;
+ getSubset( ep, readProp );
+ add_edge(nodes[source], nodes[target], ep, *graph);
+ }
+ else
+ std::cerr<<"read edge, parse error at line"<<numLine<<std::endl;
+ }
+ else { // state == PARSE_NUM_NODES
+ int n;
+ if( in >> n ){
+ for( int i=0; i<n; ++i )
+ nodes.push_back( add_vertex( *graph ));
+ }
+ else
+ std::cerr<<"read num_nodes, parse error at line "<< numLine << std::endl;
+ }
+ }
+ }
+ return (*this);
+ }
+
+
+protected:
+
+ Graph* graph;
+
+ void skip( std::istream& in )
+ {
+ char c = 0;
+ while( c!='\n' && !in.eof() )
+ in.get(c);
+ in.putback(c);
+ }
+};
+
+// parser
+//=======================================================================
+// property printer
+
+#if defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
+template<class Graph, class Property>
+struct PropertyPrinter
+{
+ typedef typename Property::value_type Value;
+ typedef typename Property::tag_type Tag;
+ typedef typename Property::next_type Next;
+
+ PropertyPrinter( const Graph& g ):graph(&g){}
+
+ template<class Iterator>
+ PropertyPrinter& operator () ( std::ostream& out, Iterator it )
+ {
+ typename property_map<Graph,Tag>::type ps = get(Tag(), *graph);
+ out << ps[ *it ] <<" ";
+ PropertyPrinter<Graph,Next> print(*graph);
+ print(out, it);
+ return (*this);
+ }
+private:
+ const Graph* graph;
+};
+#else
+template<class Graph, typename Property>
+struct PropertyPrinter
+{
+ PropertyPrinter( const Graph& g ):graph(&g){}
+
+ template<class Iterator>
+ PropertyPrinter& operator () ( std::ostream& out, Iterator it )
+ {
+ out << (*graph)[ *it ] <<" ";
+ return (*this);
+ }
+private:
+ const Graph* graph;
+};
+
+template<class Graph, typename Tag, typename Value, typename Next>
+struct PropertyPrinter<Graph, property<Tag, Value, Next> >
+{
+ PropertyPrinter( const Graph& g ):graph(&g){}
+
+ template<class Iterator>
+ PropertyPrinter& operator () ( std::ostream& out, Iterator it )
+ {
+ typename property_map<Graph,Tag>::type ps = get(Tag(), *graph);
+ out << ps[ *it ] <<" ";
+ PropertyPrinter<Graph,Next> print(*graph);
+ print(out, it);
+ return (*this);
+ }
+private:
+ const Graph* graph;
+};
+#endif
+
+template<class Graph>
+struct PropertyPrinter<Graph, no_property>
+{
+ PropertyPrinter( const Graph& ){}
+
+ template<class Iterator>
+ PropertyPrinter& operator () ( std::ostream&, Iterator it ){ return *this; }
+};
+
+// property printer
+//=========================================================================
+// graph printer
+
+template<class Graph_t, class EdgeProperty>
+struct EdgePrinter
+{
+
+ typedef Graph_t Graph;
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+
+ EdgePrinter( const Graph& g )
+ : graph(g)
+ {}
+
+ const EdgePrinter& operator () ( std::ostream& out ) const
+ {
+ // assign indices to vertices
+ std::map<Vertex,int> indices;
+ int num = 0;
+ typename graph_traits<Graph>::vertex_iterator vi;
+ for (vi = vertices(graph).first; vi != vertices(graph).second; ++vi){
+ indices[*vi] = num++;
+ }
+
+ // write edges
+ PropertyPrinter<Graph, EdgeProperty> print_Edge(graph);
+ out << "e" << std::endl;
+ typename graph_traits<Graph>::edge_iterator ei;
+ for (ei = edges(graph).first; ei != edges(graph).second; ++ei){
+ out << indices[source(*ei,graph)] << " " << indices[target(*ei,graph)] << " ";
+ print_Edge(out,ei);
+ out << std::endl;
+ }
+ out << std::endl;
+ return (*this);
+ }
+
+protected:
+
+ const Graph& graph;
+
+};
+
+template<class Graph, class V, class E>
+struct GraphPrinter: public EdgePrinter<Graph,E>
+{
+ GraphPrinter( const Graph& g )
+ : EdgePrinter<Graph,E>(g)
+ {}
+
+ const GraphPrinter& operator () ( std::ostream& out ) const
+ {
+ PropertyPrinter<Graph, V> printNode(this->graph);
+ out << "v"<<std::endl;
+ typename graph_traits<Graph>::vertex_iterator vi;
+ for (vi = vertices(this->graph).first; vi != vertices(this->graph).second; ++vi){
+ printNode(out,vi);
+ out << std::endl;
+ }
+
+ EdgePrinter<Graph,E>::operator ()( out );
+ return (*this);
+ }
+};
+
+template<class Graph, class E>
+struct GraphPrinter<Graph,no_property,E>
+ : public EdgePrinter<Graph,E>
+{
+ GraphPrinter( const Graph& g )
+ : EdgePrinter<Graph,E>(g)
+ {}
+
+ const GraphPrinter& operator () ( std::ostream& out ) const
+ {
+ out << "n "<< num_vertices(this->graph) << std::endl;
+ EdgePrinter<Graph,E>::operator ()( out );
+ return (*this);
+ }
+};
+
+// graph printer
+//=========================================================================
+// user methods
+
+/// input stream for reading a graph
+template<class Graph, class VP, class EP, class VPS, class EPS>
+std::istream& operator >> ( std::istream& in, GraphParser<Graph,VP,EP,VPS,EPS> gp )
+{
+ gp(in);
+ return in;
+}
+
+/// graph parser for given subsets of internal vertex and edge properties
+template<class EL, class VL, class D, class VP, class EP, class GP, class VPS, class EPS>
+GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VPS,EPS>
+read( adjacency_list<EL,VL,D,VP,EP,GP>& g, VPS vps, EPS eps )
+{
+ return GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VPS,EPS>(&g);
+}
+
+/// graph parser for all internal vertex and edge properties
+template<class EL, class VL, class D, class VP, class EP, class GP>
+GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VP,EP>
+read( adjacency_list<EL,VL,D,VP,EP,GP>& g )
+{
+ return GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VP,EP>(&g);
+}
+
+
+/// output stream for writing a graph
+template<class Graph, class VP, class EP>
+std::ostream& operator << ( std::ostream& out, const GraphPrinter<Graph,VP,EP>& gp )
+{
+ gp(out);
+ return out;
+}
+
+/// write the graph with given property subsets
+template<class EL, class VL, class D, class VP, class EP, class GP, class VPS, class EPS>
+GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VPS,EPS>
+write( const adjacency_list<EL,VL,D,VP,EP,GP>& g, VPS, EPS )
+{
+ return GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VPS,EPS>(g);
+}
+
+/// write the graph with all internal vertex and edge properties
+template<class EL, class VL, class D, class VP, class EP, class GP>
+GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP>
+write( const adjacency_list<EL,VL,D,VP,EP,GP>& g )
+{
+ return GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP>(g);
+}
+
+// user methods
+//=========================================================================
+}// boost
+#endif
Added: branches/CMake/release/libs/graph/include/boost/graph/adjacency_matrix.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/adjacency_matrix.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,1278 @@
+//=======================================================================
+// Copyright 2001 University of Notre Dame.
+// Copyright 2006 Trustees of Indiana University
+// Authors: Jeremy G. Siek and Douglas Gregor <dgregor_at_[hidden]>
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_ADJACENCY_MATRIX_HPP
+#define BOOST_ADJACENCY_MATRIX_HPP
+
+#include <boost/config.hpp>
+#include <vector>
+#include <memory>
+#include <cassert>
+#include <boost/limits.hpp>
+#include <boost/iterator.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_selectors.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/graph/adjacency_iterator.hpp>
+#include <boost/graph/detail/edge.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/filter_iterator.hpp>
+#include <boost/pending/integer_range.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/ice.hpp>
+
+namespace boost {
+
+ namespace detail {
+
+ template <class Directed, class Vertex>
+ class matrix_edge_desc_impl : public edge_desc_impl<Directed,Vertex>
+ {
+ typedef edge_desc_impl<Directed,Vertex> Base;
+ public:
+ matrix_edge_desc_impl() { }
+ matrix_edge_desc_impl(bool exists, Vertex s, Vertex d,
+ const void* ep = 0)
+ : Base(s, d, ep), m_exists(exists) { }
+ bool exists() const { return m_exists; }
+ private:
+ bool m_exists;
+ };
+
+ struct does_edge_exist {
+ template <class Edge>
+ bool operator()(const Edge& e) const { return e.exists(); }
+ };
+
+ template <typename EdgeProperty>
+ bool get_edge_exists(const std::pair<bool, EdgeProperty>& stored_edge, int) {
+ return stored_edge.first;
+ }
+ template <typename EdgeProperty>
+ void set_edge_exists(
+ std::pair<bool, EdgeProperty>& stored_edge,
+ bool flag,
+ int
+ ) {
+ stored_edge.first = flag;
+ }
+
+ template <typename EdgeProxy>
+ bool get_edge_exists(const EdgeProxy& edge_proxy, ...) {
+ return edge_proxy;
+ }
+ template <typename EdgeProxy>
+ EdgeProxy& set_edge_exists(EdgeProxy& edge_proxy, bool flag, ...) {
+ edge_proxy = flag;
+ return edge_proxy; // just to avoid never used warning
+ }
+
+
+
+ template <typename EdgeProperty>
+ const EdgeProperty&
+ get_property(const std::pair<bool, EdgeProperty>& stored_edge) {
+ return stored_edge.second;
+ }
+ template <typename EdgeProperty>
+ EdgeProperty&
+ get_property(std::pair<bool, EdgeProperty>& stored_edge) {
+ return stored_edge.second;
+ }
+
+ template <typename StoredEdgeProperty, typename EdgeProperty>
+ inline void
+ set_property(std::pair<bool, StoredEdgeProperty>& stored_edge,
+ const EdgeProperty& ep, int) {
+ stored_edge.second = ep;
+ }
+
+ inline const no_property& get_property(const char&) {
+ static no_property s_prop;
+ return s_prop;
+ }
+ inline no_property& get_property(char&) {
+ static no_property s_prop;
+ return s_prop;
+ }
+ template <typename EdgeProxy, typename EdgeProperty>
+ inline void
+ set_property(EdgeProxy, const EdgeProperty&, ...) {}
+
+ //=======================================================================
+ // Directed Out Edge Iterator
+
+ template <
+ typename VertexDescriptor, typename MatrixIter
+ , typename VerticesSizeType, typename EdgeDescriptor
+ >
+ struct dir_adj_matrix_out_edge_iter
+ : iterator_adaptor<
+ dir_adj_matrix_out_edge_iter<VertexDescriptor, MatrixIter, VerticesSizeType, EdgeDescriptor>
+ , MatrixIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , std::ptrdiff_t
+ >
+ {
+ typedef iterator_adaptor<
+ dir_adj_matrix_out_edge_iter<VertexDescriptor, MatrixIter, VerticesSizeType, EdgeDescriptor>
+ , MatrixIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , std::ptrdiff_t
+ > super_t;
+
+ dir_adj_matrix_out_edge_iter() { }
+
+ dir_adj_matrix_out_edge_iter(
+ const MatrixIter& i
+ , const VertexDescriptor& src
+ , const VerticesSizeType& n
+ )
+ : super_t(i), m_src(src), m_targ(0), m_n(n)
+ { }
+
+ void increment() {
+ ++this->base_reference();
+ ++m_targ;
+ }
+
+ inline EdgeDescriptor
+ dereference() const
+ {
+ return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, m_targ,
+ &get_property(*this->base()));
+ }
+ VertexDescriptor m_src, m_targ;
+ VerticesSizeType m_n;
+ };
+
+ //=======================================================================
+ // Directed In Edge Iterator
+
+ template <
+ typename VertexDescriptor, typename MatrixIter
+ , typename VerticesSizeType, typename EdgeDescriptor
+ >
+ struct dir_adj_matrix_in_edge_iter
+ : iterator_adaptor<
+ dir_adj_matrix_in_edge_iter<VertexDescriptor, MatrixIter, VerticesSizeType, EdgeDescriptor>
+ , MatrixIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , std::ptrdiff_t
+ >
+ {
+ typedef iterator_adaptor<
+ dir_adj_matrix_in_edge_iter<VertexDescriptor, MatrixIter, VerticesSizeType, EdgeDescriptor>
+ , MatrixIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , std::ptrdiff_t
+ > super_t;
+
+ dir_adj_matrix_in_edge_iter() { }
+
+ dir_adj_matrix_in_edge_iter(
+ const MatrixIter& i
+ , const MatrixIter& last
+ , const VertexDescriptor& tgt
+ , const VerticesSizeType& n
+ )
+ : super_t(i), m_last(last), m_src(0), m_targ(tgt), m_n(n)
+ { }
+
+ void increment() {
+ if (VerticesSizeType(m_last - this->base_reference()) >= m_n) {
+ this->base_reference() += m_n;
+ ++m_src;
+ } else {
+ this->base_reference() = m_last;
+ }
+ }
+
+ inline EdgeDescriptor
+ dereference() const
+ {
+ return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, m_targ,
+ &get_property(*this->base()));
+ }
+ MatrixIter m_last;
+ VertexDescriptor m_src, m_targ;
+ VerticesSizeType m_n;
+ };
+
+ //=======================================================================
+ // Undirected Out Edge Iterator
+
+ template <
+ typename VertexDescriptor, typename MatrixIter
+ , typename VerticesSizeType, typename EdgeDescriptor
+ >
+ struct undir_adj_matrix_out_edge_iter
+ : iterator_adaptor<
+ undir_adj_matrix_out_edge_iter<VertexDescriptor, MatrixIter, VerticesSizeType, EdgeDescriptor>
+ , MatrixIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , std::ptrdiff_t
+ >
+ {
+ typedef iterator_adaptor<
+ undir_adj_matrix_out_edge_iter<VertexDescriptor, MatrixIter, VerticesSizeType, EdgeDescriptor>
+ , MatrixIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , std::ptrdiff_t
+ > super_t;
+
+ undir_adj_matrix_out_edge_iter() { }
+
+ undir_adj_matrix_out_edge_iter(
+ const MatrixIter& i
+ , const VertexDescriptor& src
+ , const VerticesSizeType& n
+ )
+ : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n)
+ {}
+
+ void increment()
+ {
+ if (m_targ < m_src) // first half
+ {
+ ++this->base_reference();
+ }
+ else if (m_targ < m_n - 1)
+ { // second half
+ ++m_inc;
+ this->base_reference() += m_inc;
+ }
+ else
+ { // past-the-end
+ this->base_reference() += m_n - m_src;
+ }
+ ++m_targ;
+ }
+
+ inline EdgeDescriptor
+ dereference() const
+ {
+ return EdgeDescriptor(
+ get_edge_exists(*this->base(), 0), m_src, m_targ
+ , &get_property(*this->base())
+ );
+ }
+
+ VertexDescriptor m_src, m_inc, m_targ;
+ VerticesSizeType m_n;
+ };
+
+ //=======================================================================
+ // Undirected In Edge Iterator
+
+ template <
+ typename VertexDescriptor, typename MatrixIter
+ , typename VerticesSizeType, typename EdgeDescriptor
+ >
+ struct undir_adj_matrix_in_edge_iter
+ : iterator_adaptor<
+ undir_adj_matrix_in_edge_iter<VertexDescriptor, MatrixIter, VerticesSizeType, EdgeDescriptor>
+ , MatrixIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , std::ptrdiff_t
+ >
+ {
+ typedef iterator_adaptor<
+ undir_adj_matrix_in_edge_iter<VertexDescriptor, MatrixIter, VerticesSizeType, EdgeDescriptor>
+ , MatrixIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , std::ptrdiff_t
+ > super_t;
+
+ undir_adj_matrix_in_edge_iter() { }
+
+ undir_adj_matrix_in_edge_iter(
+ const MatrixIter& i
+ , const VertexDescriptor& src
+ , const VerticesSizeType& n
+ )
+ : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n)
+ {}
+
+ void increment()
+ {
+ if (m_targ < m_src) // first half
+ {
+ ++this->base_reference();
+ }
+ else if (m_targ < m_n - 1)
+ { // second half
+ ++m_inc;
+ this->base_reference() += m_inc;
+ }
+ else
+ { // past-the-end
+ this->base_reference() += m_n - m_src;
+ }
+ ++m_targ;
+ }
+
+ inline EdgeDescriptor
+ dereference() const
+ {
+ return EdgeDescriptor(
+ get_edge_exists(*this->base(), 0), m_targ, m_src
+ , &get_property(*this->base())
+ );
+ }
+
+ VertexDescriptor m_src, m_inc, m_targ;
+ VerticesSizeType m_n;
+ };
+
+ //=======================================================================
+ // Edge Iterator
+
+ template <typename Directed, typename MatrixIter,
+ typename VerticesSizeType, typename EdgeDescriptor>
+ struct adj_matrix_edge_iter
+ : iterator_adaptor<
+ adj_matrix_edge_iter<Directed, MatrixIter, VerticesSizeType, EdgeDescriptor>
+ , MatrixIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , std::ptrdiff_t
+ >
+ {
+ typedef iterator_adaptor<
+ adj_matrix_edge_iter<Directed, MatrixIter, VerticesSizeType, EdgeDescriptor>
+ , MatrixIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , std::ptrdiff_t
+ > super_t;
+
+ adj_matrix_edge_iter() { }
+
+ adj_matrix_edge_iter(const MatrixIter& i, const MatrixIter& start, const VerticesSizeType& n)
+ : super_t(i), m_start(start), m_src(0), m_targ(0), m_n(n) { }
+
+ void increment()
+ {
+ increment_dispatch(this->base_reference(), Directed());
+ }
+
+ void increment_dispatch(MatrixIter& i, directedS)
+ {
+ ++i;
+ if (m_targ == m_n - 1)
+ {
+ m_targ = 0;
+ ++m_src;
+ }
+ else
+ {
+ ++m_targ;
+ }
+ }
+
+ void increment_dispatch(MatrixIter& i, undirectedS)
+ {
+ ++i;
+ if (m_targ == m_src)
+ {
+ m_targ = 0;
+ ++m_src;
+ }
+ else
+ {
+ ++m_targ;
+ }
+ }
+
+ inline EdgeDescriptor
+ dereference() const
+ {
+ return EdgeDescriptor(
+ get_edge_exists(
+ *this->base(), 0), m_src, m_targ, &get_property(*this->base())
+ );
+ }
+
+ MatrixIter m_start;
+ VerticesSizeType m_src, m_targ, m_n;
+ };
+
+ } // namespace detail
+
+ //=========================================================================
+ // Adjacency Matrix Traits
+ template <typename Directed = directedS>
+ class adjacency_matrix_traits {
+ typedef typename Directed::is_directed_t is_directed;
+ public:
+ // The bidirectionalS tag is not allowed with the adjacency_matrix
+ // graph type. Instead, use directedS, which also provides the
+ // functionality required for a Bidirectional Graph (in_edges,
+ // in_degree, etc.).
+#if !defined(_MSC_VER) || _MSC_VER > 1300
+ BOOST_STATIC_ASSERT(type_traits::ice_not<(is_same<Directed, bidirectionalS>::value)>::value);
+#endif
+
+ typedef typename mpl::if_<is_directed,
+ bidirectional_tag, undirected_tag>::type
+ directed_category;
+
+ typedef disallow_parallel_edge_tag edge_parallel_category;
+
+ typedef std::size_t vertex_descriptor;
+
+ typedef detail::matrix_edge_desc_impl<directed_category,
+ vertex_descriptor> edge_descriptor;
+ };
+
+ struct adjacency_matrix_class_tag { };
+
+ struct adj_matrix_traversal_tag :
+ public virtual adjacency_matrix_tag,
+ public virtual vertex_list_graph_tag,
+ public virtual incidence_graph_tag,
+ public virtual adjacency_graph_tag,
+ public virtual edge_list_graph_tag { };
+
+ //=========================================================================
+ // Adjacency Matrix Class
+ template <typename Directed = directedS,
+ typename VertexProperty = no_property,
+ typename EdgeProperty = no_property,
+ typename GraphProperty = no_property,
+ typename Allocator = std::allocator<bool> >
+ class adjacency_matrix {
+ typedef adjacency_matrix self;
+ typedef adjacency_matrix_traits<Directed> Traits;
+
+ public:
+#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
+ // The bidirectionalS tag is not allowed with the adjacency_matrix
+ // graph type. Instead, use directedS, which also provides the
+ // functionality required for a Bidirectional Graph (in_edges,
+ // in_degree, etc.).
+ BOOST_STATIC_ASSERT(!(is_same<Directed, bidirectionalS>::value));
+#endif
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ typedef typename detail::retag_property_list<vertex_bundle_t, VertexProperty>::type
+ vertex_property_type;
+ typedef typename detail::retag_property_list<edge_bundle_t, EdgeProperty>::type
+ edge_property_type;
+
+ private:
+ typedef typename detail::retag_property_list<vertex_bundle_t, VertexProperty>::retagged
+ maybe_vertex_bundled;
+
+ typedef typename detail::retag_property_list<edge_bundle_t, EdgeProperty>::retagged
+ maybe_edge_bundled;
+
+ public:
+ // The types that are actually bundled
+ typedef typename mpl::if_c<(is_same<maybe_vertex_bundled, no_property>::value),
+ no_vertex_bundle,
+ maybe_vertex_bundled>::type vertex_bundled;
+ typedef typename mpl::if_c<(is_same<maybe_edge_bundled, no_property>::value),
+ no_edge_bundle,
+ maybe_edge_bundled>::type edge_bundled;
+#else
+ typedef EdgeProperty edge_property_type;
+ typedef VertexProperty vertex_property_type;
+ typedef no_vertex_bundle vertex_bundled;
+ typedef no_edge_bundle edge_bundled;
+#endif
+
+ public: // should be private
+ typedef typename mpl::if_<typename has_property<edge_property_type>::type,
+ std::pair<bool, edge_property_type>, char>::type StoredEdge;
+#if (defined(BOOST_MSVC) && BOOST_MSVC <= 1300) || defined(BOOST_NO_STD_ALLOCATOR)
+ typedef std::vector<StoredEdge> Matrix;
+#else
+ // This causes internal compiler error for MSVC
+ typedef typename Allocator::template rebind<StoredEdge>::other Alloc;
+ typedef std::vector<StoredEdge, Alloc> Matrix;
+#endif
+ typedef typename Matrix::iterator MatrixIter;
+ typedef typename Matrix::size_type size_type;
+ public:
+ // Graph concept required types
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+ typedef typename Traits::edge_descriptor edge_descriptor;
+ typedef typename Traits::directed_category directed_category;
+ typedef typename Traits::edge_parallel_category edge_parallel_category;
+ typedef adj_matrix_traversal_tag traversal_category;
+
+ static vertex_descriptor null_vertex()
+ {
+ return (std::numeric_limits<vertex_descriptor>::max)();
+ }
+
+ //private: if friends worked, these would be private
+
+ typedef detail::dir_adj_matrix_out_edge_iter<
+ vertex_descriptor, MatrixIter, size_type, edge_descriptor
+ > DirOutEdgeIter;
+
+ typedef detail::undir_adj_matrix_out_edge_iter<
+ vertex_descriptor, MatrixIter, size_type, edge_descriptor
+ > UnDirOutEdgeIter;
+
+ typedef typename mpl::if_<
+ typename Directed::is_directed_t, DirOutEdgeIter, UnDirOutEdgeIter
+ >::type unfiltered_out_edge_iter;
+
+ typedef detail::dir_adj_matrix_in_edge_iter<
+ vertex_descriptor, MatrixIter, size_type, edge_descriptor
+ > DirInEdgeIter;
+
+ typedef detail::undir_adj_matrix_in_edge_iter<
+ vertex_descriptor, MatrixIter, size_type, edge_descriptor
+ > UnDirInEdgeIter;
+
+ typedef typename mpl::if_<
+ typename Directed::is_directed_t, DirInEdgeIter, UnDirInEdgeIter
+ >::type unfiltered_in_edge_iter;
+
+ typedef detail::adj_matrix_edge_iter<
+ Directed, MatrixIter, size_type, edge_descriptor
+ > unfiltered_edge_iter;
+
+ public:
+
+ // IncidenceGraph concept required types
+ typedef filter_iterator<detail::does_edge_exist, unfiltered_out_edge_iter>
+ out_edge_iterator;
+
+ typedef size_type degree_size_type;
+
+ // BidirectionalGraph required types
+ typedef filter_iterator<detail::does_edge_exist, unfiltered_in_edge_iter>
+ in_edge_iterator;
+
+ // AdjacencyGraph required types
+ typedef typename adjacency_iterator_generator<self,
+ vertex_descriptor, out_edge_iterator>::type adjacency_iterator;
+
+ // VertexListGraph required types
+ typedef size_type vertices_size_type;
+ typedef integer_range<vertex_descriptor> VertexList;
+ typedef typename VertexList::iterator vertex_iterator;
+
+ // EdgeListGraph required types
+ typedef size_type edges_size_type;
+ typedef filter_iterator<
+ detail::does_edge_exist, unfiltered_edge_iter
+ > edge_iterator;
+
+ // PropertyGraph required types
+ typedef adjacency_matrix_class_tag graph_tag;
+
+ // Constructor required by MutableGraph
+ adjacency_matrix(vertices_size_type n_vertices)
+ : m_matrix(Directed::is_directed ?
+ (n_vertices * n_vertices)
+ : (n_vertices * (n_vertices + 1) / 2)),
+ m_vertex_set(0, n_vertices),
+ m_vertex_properties(n_vertices),
+ m_num_edges(0) { }
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ // Directly access a vertex or edge bundle
+ vertex_bundled& operator[](vertex_descriptor v)
+ { return get(vertex_bundle, *this)[v]; }
+
+ const vertex_bundled& operator[](vertex_descriptor v) const
+ { return get(vertex_bundle, *this)[v]; }
+
+ edge_bundled& operator[](edge_descriptor e)
+ { return get(edge_bundle, *this)[e]; }
+
+ const edge_bundled& operator[](edge_descriptor e) const
+ { return get(edge_bundle, *this)[e]; }
+#endif
+
+ //private: if friends worked, these would be private
+
+ typename Matrix::const_reference
+ get_edge(vertex_descriptor u, vertex_descriptor v) const {
+ if (Directed::is_directed)
+ return m_matrix[u * m_vertex_set.size() + v];
+ else {
+ if (v > u)
+ std::swap(u, v);
+ return m_matrix[u * (u + 1)/2 + v];
+ }
+ }
+ typename Matrix::reference
+ get_edge(vertex_descriptor u, vertex_descriptor v) {
+ if (Directed::is_directed)
+ return m_matrix[u * m_vertex_set.size() + v];
+ else {
+ if (v > u)
+ std::swap(u, v);
+ return m_matrix[u * (u + 1)/2 + v];
+ }
+ }
+
+ Matrix m_matrix;
+ VertexList m_vertex_set;
+ std::vector<vertex_property_type> m_vertex_properties;
+ size_type m_num_edges;
+ };
+
+ //=========================================================================
+ // Functions required by the AdjacencyMatrix concept
+
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor,
+ bool>
+ edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+ typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
+ const adjacency_matrix<D,VP,EP,GP,A>& g)
+ {
+ bool exists = detail::get_edge_exists(g.get_edge(u,v), 0);
+ typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor
+ e(exists, u, v, &detail::get_property(g.get_edge(u,v)));
+ return std::make_pair(e, exists);
+ }
+
+ //=========================================================================
+ // Functions required by the IncidenceGraph concept
+
+ // O(1)
+ template <typename VP, typename EP, typename GP, typename A>
+ std::pair<typename adjacency_matrix<directedS,VP,EP,GP,A>::out_edge_iterator,
+ typename adjacency_matrix<directedS,VP,EP,GP,A>::out_edge_iterator>
+ out_edges
+ (typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_descriptor u,
+ const adjacency_matrix<directedS,VP,EP,GP,A>& g_)
+ {
+ typedef adjacency_matrix<directedS,VP,EP,GP,A> Graph;
+ Graph& g = const_cast<Graph&>(g_);
+ typename Graph::vertices_size_type offset = u * g.m_vertex_set.size();
+ typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
+ typename Graph::MatrixIter l = f + g.m_vertex_set.size();
+ typename Graph::unfiltered_out_edge_iter
+ first(f, u, g.m_vertex_set.size())
+ , last(l, u, g.m_vertex_set.size());
+ detail::does_edge_exist pred;
+ typedef typename Graph::out_edge_iterator out_edge_iterator;
+ return std::make_pair(out_edge_iterator(pred, first, last),
+ out_edge_iterator(pred, last, last));
+ }
+
+ // O(1)
+ template <typename VP, typename EP, typename GP, typename A>
+ std::pair<
+ typename adjacency_matrix<undirectedS,VP,EP,GP,A>::out_edge_iterator,
+ typename adjacency_matrix<undirectedS,VP,EP,GP,A>::out_edge_iterator>
+ out_edges
+ (typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_descriptor u,
+ const adjacency_matrix<undirectedS,VP,EP,GP,A>& g_)
+ {
+ typedef adjacency_matrix<undirectedS,VP,EP,GP,A> Graph;
+ Graph& g = const_cast<Graph&>(g_);
+ typename Graph::vertices_size_type offset = u * (u + 1) / 2;
+ typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
+ typename Graph::MatrixIter l = g.m_matrix.end();
+
+ typename Graph::unfiltered_out_edge_iter
+ first(f, u, g.m_vertex_set.size())
+ , last(l, u, g.m_vertex_set.size());
+
+ detail::does_edge_exist pred;
+ typedef typename Graph::out_edge_iterator out_edge_iterator;
+ return std::make_pair(out_edge_iterator(pred, first, last),
+ out_edge_iterator(pred, last, last));
+ }
+
+ // O(N)
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type
+ out_degree(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+ const adjacency_matrix<D,VP,EP,GP,A>& g)
+ {
+ typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type n = 0;
+ typename adjacency_matrix<D,VP,EP,GP,A>::out_edge_iterator f, l;
+ for (tie(f, l) = out_edges(u, g); f != l; ++f)
+ ++n;
+ return n;
+ }
+
+ // O(1)
+ template <typename D, typename VP, typename EP, typename GP, typename A,
+ typename Dir, typename Vertex>
+ typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
+ source(const detail::matrix_edge_desc_impl<Dir,Vertex>& e,
+ const adjacency_matrix<D,VP,EP,GP,A>&)
+ {
+ return e.m_source;
+ }
+
+ // O(1)
+ template <typename D, typename VP, typename EP, typename GP, typename A,
+ typename Dir, typename Vertex>
+ typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
+ target(const detail::matrix_edge_desc_impl<Dir,Vertex>& e,
+ const adjacency_matrix<D,VP,EP,GP,A>&)
+ {
+ return e.m_target;
+ }
+
+ //=========================================================================
+ // Functions required by the BidirectionalGraph concept
+
+ // O(1)
+ template <typename VP, typename EP, typename GP, typename A>
+ std::pair<typename adjacency_matrix<directedS,VP,EP,GP,A>::in_edge_iterator,
+ typename adjacency_matrix<directedS,VP,EP,GP,A>::in_edge_iterator>
+ in_edges
+ (typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_descriptor u,
+ const adjacency_matrix<directedS,VP,EP,GP,A>& g_)
+ {
+ typedef adjacency_matrix<directedS,VP,EP,GP,A> Graph;
+ Graph& g = const_cast<Graph&>(g_);
+ typename Graph::MatrixIter f = g.m_matrix.begin() + u;
+ typename Graph::MatrixIter l = g.m_matrix.end();
+ typename Graph::unfiltered_in_edge_iter
+ first(f, l, u, g.m_vertex_set.size())
+ , last(l, l, u, g.m_vertex_set.size());
+ detail::does_edge_exist pred;
+ typedef typename Graph::in_edge_iterator in_edge_iterator;
+ return std::make_pair(in_edge_iterator(pred, first, last),
+ in_edge_iterator(pred, last, last));
+ }
+
+ // O(1)
+ template <typename VP, typename EP, typename GP, typename A>
+ std::pair<
+ typename adjacency_matrix<undirectedS,VP,EP,GP,A>::in_edge_iterator,
+ typename adjacency_matrix<undirectedS,VP,EP,GP,A>::in_edge_iterator>
+ in_edges
+ (typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_descriptor u,
+ const adjacency_matrix<undirectedS,VP,EP,GP,A>& g_)
+ {
+ typedef adjacency_matrix<undirectedS,VP,EP,GP,A> Graph;
+ Graph& g = const_cast<Graph&>(g_);
+ typename Graph::vertices_size_type offset = u * (u + 1) / 2;
+ typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
+ typename Graph::MatrixIter l = g.m_matrix.end();
+
+ typename Graph::unfiltered_in_edge_iter
+ first(f, u, g.m_vertex_set.size())
+ , last(l, u, g.m_vertex_set.size());
+
+ detail::does_edge_exist pred;
+ typedef typename Graph::in_edge_iterator in_edge_iterator;
+ return std::make_pair(in_edge_iterator(pred, first, last),
+ in_edge_iterator(pred, last, last));
+ }
+
+ // O(N)
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type
+ in_degree(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+ const adjacency_matrix<D,VP,EP,GP,A>& g)
+ {
+ typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type n = 0;
+ typename adjacency_matrix<D,VP,EP,GP,A>::in_edge_iterator f, l;
+ for (tie(f, l) = in_edges(u, g); f != l; ++f)
+ ++n;
+ return n;
+ }
+
+ //=========================================================================
+ // Functions required by the AdjacencyGraph concept
+
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::adjacency_iterator,
+ typename adjacency_matrix<D,VP,EP,GP,A>::adjacency_iterator>
+ adjacent_vertices
+ (typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+ const adjacency_matrix<D,VP,EP,GP,A>& g_)
+ {
+ typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
+ const Graph& cg = static_cast<const Graph&>(g_);
+ Graph& g = const_cast<Graph&>(cg);
+ typedef typename Graph::adjacency_iterator adjacency_iterator;
+ typename Graph::out_edge_iterator first, last;
+ boost::tie(first, last) = out_edges(u, g);
+ return std::make_pair(adjacency_iterator(first, &g),
+ adjacency_iterator(last, &g));
+ }
+
+ //=========================================================================
+ // Functions required by the VertexListGraph concept
+
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::vertex_iterator,
+ typename adjacency_matrix<D,VP,EP,GP,A>::vertex_iterator>
+ vertices(const adjacency_matrix<D,VP,EP,GP,A>& g_) {
+ typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
+ Graph& g = const_cast<Graph&>(g_);
+ return std::make_pair(g.m_vertex_set.begin(), g.m_vertex_set.end());
+ }
+
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ typename adjacency_matrix<D,VP,EP,GP,A>::vertices_size_type
+ num_vertices(const adjacency_matrix<D,VP,EP,GP,A>& g) {
+ return g.m_vertex_set.size();
+ }
+
+ //=========================================================================
+ // Functions required by the EdgeListGraph concept
+
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_iterator,
+ typename adjacency_matrix<D,VP,EP,GP,A>::edge_iterator>
+ edges(const adjacency_matrix<D,VP,EP,GP,A>& g_)
+ {
+ typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
+ Graph& g = const_cast<Graph&>(g_);
+
+ typename Graph::unfiltered_edge_iter
+ first(g.m_matrix.begin(), g.m_matrix.begin(),
+ g.m_vertex_set.size()),
+ last(g.m_matrix.end(), g.m_matrix.begin(),
+ g.m_vertex_set.size());
+ detail::does_edge_exist pred;
+ typedef typename Graph::edge_iterator edge_iterator;
+ return std::make_pair(edge_iterator(pred, first, last),
+ edge_iterator(pred, last, last));
+ }
+
+ // O(1)
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ typename adjacency_matrix<D,VP,EP,GP,A>::edges_size_type
+ num_edges(const adjacency_matrix<D,VP,EP,GP,A>& g)
+ {
+ return g.m_num_edges;
+ }
+
+ //=========================================================================
+ // Functions required by the MutableGraph concept
+
+ // O(1)
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor, bool>
+ add_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+ typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
+ const EP& ep,
+ adjacency_matrix<D,VP,EP,GP,A>& g)
+ {
+ typedef typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor
+ edge_descriptor;
+ if (detail::get_edge_exists(g.get_edge(u,v), 0) == false) {
+ ++(g.m_num_edges);
+ detail::set_property(g.get_edge(u,v), ep, 0);
+ detail::set_edge_exists(g.get_edge(u,v), true, 0);
+ return std::make_pair
+ (edge_descriptor(true, u, v, &detail::get_property(g.get_edge(u,v))),
+ true);
+ } else
+ return std::make_pair
+ (edge_descriptor(true, u, v, &detail::get_property(g.get_edge(u,v))),
+ false);
+ }
+ // O(1)
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor, bool>
+ add_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+ typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
+ adjacency_matrix<D,VP,EP,GP,A>& g)
+ {
+ EP ep;
+ return add_edge(u, v, ep, g);
+ }
+
+ // O(1)
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ void
+ remove_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+ typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
+ adjacency_matrix<D,VP,EP,GP,A>& g)
+ {
+ --(g.m_num_edges);
+ detail::set_edge_exists(g.get_edge(u,v), false, 0);
+ }
+
+ // O(1)
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ void
+ remove_edge(typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor e,
+ adjacency_matrix<D,VP,EP,GP,A>& g)
+ {
+ remove_edge(source(e, g), target(e, g), g);
+ }
+
+
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ inline typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
+ add_vertex(adjacency_matrix<D,VP,EP,GP,A>& g) {
+ // UNDER CONSTRUCTION
+ assert(false);
+ return *vertices(g).first;
+ }
+
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ inline typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
+ add_vertex(const VP& vp, adjacency_matrix<D,VP,EP,GP,A>& g) {
+ // UNDER CONSTRUCTION
+ assert(false);
+ return *vertices(g).first;
+ }
+
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ inline void
+ remove_vertex(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
+ adjacency_matrix<D,VP,EP,GP,A>& g)
+ {
+ // UNDER CONSTRUCTION
+ assert(false);
+ }
+
+ // O(V)
+ template <typename VP, typename EP, typename GP, typename A>
+ void
+ clear_vertex
+ (typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_descriptor u,
+ adjacency_matrix<directedS,VP,EP,GP,A>& g)
+ {
+ typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_iterator
+ vi, vi_end;
+ for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ remove_edge(u, *vi, g);
+ for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ remove_edge(*vi, u, g);
+ }
+
+ // O(V)
+ template <typename VP, typename EP, typename GP, typename A>
+ void
+ clear_vertex
+ (typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_descriptor u,
+ adjacency_matrix<undirectedS,VP,EP,GP,A>& g)
+ {
+ typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_iterator
+ vi, vi_end;
+ for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ remove_edge(u, *vi, g);
+ }
+
+ //=========================================================================
+ // Vertex Property Map
+
+ template <typename GraphPtr, typename Vertex, typename T, typename R,
+ typename Tag>
+ class adj_matrix_vertex_property_map
+ : public put_get_helper<R,
+ adj_matrix_vertex_property_map<GraphPtr, Vertex, T, R, Tag> >
+ {
+ public:
+ typedef T value_type;
+ typedef R reference;
+ typedef Vertex key_type;
+ typedef boost::lvalue_property_map_tag category;
+ adj_matrix_vertex_property_map() { }
+ adj_matrix_vertex_property_map(GraphPtr g) : m_g(g) { }
+ inline reference operator[](key_type v) const {
+ return get_property_value(m_g->m_vertex_properties[v], Tag());
+ }
+ GraphPtr m_g;
+ };
+
+ template <class Property, class Vertex>
+ struct adj_matrix_vertex_id_map
+ : public boost::put_get_helper<Vertex,
+ adj_matrix_vertex_id_map<Property, Vertex> >
+ {
+ typedef Vertex value_type;
+ typedef Vertex reference;
+ typedef Vertex key_type;
+ typedef boost::readable_property_map_tag category;
+ adj_matrix_vertex_id_map() { }
+ template <class Graph>
+ inline adj_matrix_vertex_id_map(const Graph&) { }
+ inline value_type operator[](key_type v) const { return v; }
+ };
+
+ namespace detail {
+
+ struct adj_matrix_any_vertex_pa {
+ template <class Tag, class Graph, class Property>
+ struct bind_ {
+ typedef typename property_value<Property,Tag>::type Value;
+ typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
+
+ typedef adj_matrix_vertex_property_map<Graph*, Vertex, Value, Value&,
+ Tag> type;
+ typedef adj_matrix_vertex_property_map<const Graph*, Vertex, Value,
+ const Value&, Tag> const_type;
+ };
+ };
+ struct adj_matrix_id_vertex_pa {
+ template <class Tag, class Graph, class Property>
+ struct bind_ {
+ typedef typename Graph::vertex_descriptor Vertex;
+ typedef adj_matrix_vertex_id_map<Property, Vertex> type;
+ typedef adj_matrix_vertex_id_map<Property, Vertex> const_type;
+ };
+ };
+
+ template <class Tag>
+ struct adj_matrix_choose_vertex_pa_helper {
+ typedef adj_matrix_any_vertex_pa type;
+ };
+ template <>
+ struct adj_matrix_choose_vertex_pa_helper<vertex_index_t> {
+ typedef adj_matrix_id_vertex_pa type;
+ };
+
+ template <class Tag, class Graph, class Property>
+ struct adj_matrix_choose_vertex_pa {
+ typedef typename adj_matrix_choose_vertex_pa_helper<Tag>::type Helper;
+ typedef typename Helper::template bind_<Tag,Graph,Property> Bind;
+ typedef typename Bind::type type;
+ typedef typename Bind::const_type const_type;
+ };
+
+ struct adj_matrix_vertex_property_selector {
+ template <class Graph, class Property, class Tag>
+ struct bind_ {
+ typedef adj_matrix_choose_vertex_pa<Tag,Graph,Property> Choice;
+ typedef typename Choice::type type;
+ typedef typename Choice::const_type const_type;
+ };
+ };
+
+ } // namespace detail
+
+ template <>
+ struct vertex_property_selector<adjacency_matrix_class_tag> {
+ typedef detail::adj_matrix_vertex_property_selector type;
+ };
+
+ //=========================================================================
+ // Edge Property Map
+
+
+ template <typename Directed, typename Property, typename Vertex,
+ typename T, typename R, typename Tag>
+ class adj_matrix_edge_property_map
+ : public put_get_helper<R,
+ adj_matrix_edge_property_map<Directed, Property, Vertex, T, R, Tag> >
+ {
+ public:
+ typedef T value_type;
+ typedef R reference;
+ typedef detail::matrix_edge_desc_impl<Directed, Vertex> key_type;
+ typedef boost::lvalue_property_map_tag category;
+ inline reference operator[](key_type e) const {
+ Property& p = *(Property*)e.get_property();
+ return get_property_value(p, Tag());
+ }
+ };
+ struct adj_matrix_edge_property_selector {
+ template <class Graph, class Property, class Tag>
+ struct bind_ {
+ typedef typename property_value<Property,Tag>::type T;
+ typedef typename Graph::vertex_descriptor Vertex;
+ typedef adj_matrix_edge_property_map<typename Graph::directed_category,
+ Property, Vertex, T, T&, Tag> type;
+ typedef adj_matrix_edge_property_map<typename Graph::directed_category,
+ Property, Vertex, T, const T&, Tag> const_type;
+ };
+ };
+ template <>
+ struct edge_property_selector<adjacency_matrix_class_tag> {
+ typedef adj_matrix_edge_property_selector type;
+ };
+
+ //=========================================================================
+ // Functions required by PropertyGraph
+
+ namespace detail {
+
+ template <typename Property, typename D, typename VP, typename EP,
+ typename GP, typename A>
+ typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>,
+ Property>::type
+ get_dispatch(adjacency_matrix<D,VP,EP,GP,A>& g, Property,
+ vertex_property_tag)
+ {
+ typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
+ typedef typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>,
+ Property>::type PA;
+ return PA(&g);
+ }
+ template <typename Property, typename D, typename VP, typename EP,
+ typename GP, typename A>
+ typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>,
+ Property>::type
+ get_dispatch(adjacency_matrix<D,VP,EP,GP,A>&, Property,
+ edge_property_tag)
+ {
+ typedef typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>,
+ Property>::type PA;
+ return PA();
+ }
+ template <typename Property, typename D, typename VP, typename EP,
+ typename GP, typename A>
+ typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>,
+ Property>::const_type
+ get_dispatch(const adjacency_matrix<D,VP,EP,GP,A>& g, Property,
+ vertex_property_tag)
+ {
+ typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
+ typedef typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>,
+ Property>::const_type PA;
+ return PA(&g);
+ }
+ template <typename Property, typename D, typename VP, typename EP,
+ typename GP, typename A>
+ typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>,
+ Property>::const_type
+ get_dispatch(const adjacency_matrix<D,VP,EP,GP,A>&, Property,
+ edge_property_tag)
+ {
+ typedef typename boost::property_map<adjacency_matrix<D,VP,EP,GP,A>,
+ Property>::const_type PA;
+ return PA();
+ }
+
+ } // namespace detail
+
+ template <typename Property, typename D, typename VP, typename EP,
+ typename GP, typename A>
+ inline
+ typename property_map<adjacency_matrix<D,VP,EP,GP,A>, Property>::type
+ get(Property p, adjacency_matrix<D,VP,EP,GP,A>& g)
+ {
+ typedef typename property_kind<Property>::type Kind;
+ return detail::get_dispatch(g, p, Kind());
+ }
+
+ template <typename Property, typename D, typename VP, typename EP,
+ typename GP, typename A>
+ inline
+ typename property_map<adjacency_matrix<D,VP,EP,GP,A>, Property>::const_type
+ get(Property p, const adjacency_matrix<D,VP,EP,GP,A>& g)
+ {
+ typedef typename property_kind<Property>::type Kind;
+ return detail::get_dispatch(g, p, Kind());
+ }
+
+ template <typename Property, typename D, typename VP, typename EP,
+ typename GP, typename A, typename Key>
+ inline
+ typename property_traits<
+ typename property_map<adjacency_matrix<D,VP,EP,GP,A>, Property>::const_type
+ >::value_type
+ get(Property p, const adjacency_matrix<D,VP,EP,GP,A>& g,
+ const Key& key)
+ {
+ return get(get(p, g), key);
+ }
+
+ template <typename Property, typename D, typename VP, typename EP,
+ typename GP, typename A, typename Key, typename Value>
+ inline void
+ put(Property p, adjacency_matrix<D,VP,EP,GP,A>& g,
+ const Key& key, const Value& value)
+ {
+ typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
+ typedef typename boost::property_map<Graph, Property>::type Map;
+ Map pmap = get(p, g);
+ put(pmap, key, value);
+ }
+
+ //=========================================================================
+ // Other Functions
+
+ template <typename D, typename VP, typename EP, typename GP, typename A>
+ typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
+ vertex(typename adjacency_matrix<D,VP,EP,GP,A>::vertices_size_type n,
+ const adjacency_matrix<D,VP,EP,GP,A>& g)
+ {
+ return n;
+ }
+
+ // Support for bundled properties
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ template <typename Directed, typename VertexProperty, typename EdgeProperty, typename GraphProperty,
+ typename Allocator, typename T, typename Bundle>
+ inline
+ typename property_map<adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>,
+ T Bundle::*>::type
+ get(T Bundle::* p, adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>& g)
+ {
+ typedef typename property_map<adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>,
+ T Bundle::*>::type
+ result_type;
+ return result_type(&g, p);
+ }
+
+ template <typename Directed, typename VertexProperty, typename EdgeProperty, typename GraphProperty,
+ typename Allocator, typename T, typename Bundle>
+ inline
+ typename property_map<adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>,
+ T Bundle::*>::const_type
+ get(T Bundle::* p, adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator> const & g)
+ {
+ typedef typename property_map<adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>,
+ T Bundle::*>::const_type
+ result_type;
+ return result_type(&g, p);
+ }
+
+ template <typename Directed, typename VertexProperty, typename EdgeProperty, typename GraphProperty,
+ typename Allocator, typename T, typename Bundle, typename Key>
+ inline T
+ get(T Bundle::* p, adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator> const & g,
+ const Key& key)
+ {
+ return get(get(p, g), key);
+ }
+
+ template <typename Directed, typename VertexProperty, typename EdgeProperty, typename GraphProperty,
+ typename Allocator, typename T, typename Bundle, typename Key>
+ inline void
+ put(T Bundle::* p, adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, Allocator>& g,
+ const Key& key, const T& value)
+ {
+ put(get(p, g), key, value);
+ }
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_ADJACENCY_MATRIX_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/astar_search.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/astar_search.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,407 @@
+
+
+//
+//=======================================================================
+// Copyright (c) 2004 Kristopher Beevers
+//
+// 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)
+//=======================================================================
+//
+
+#ifndef BOOST_GRAPH_ASTAR_SEARCH_HPP
+#define BOOST_GRAPH_ASTAR_SEARCH_HPP
+
+
+#include <functional>
+#include <boost/limits.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/pending/mutable_queue.hpp>
+#include <boost/graph/relax.hpp>
+#include <boost/pending/indirect_cmp.hpp>
+#include <boost/graph/exception.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+
+
+namespace boost {
+
+
+ template <class Heuristic, class Graph>
+ struct AStarHeuristicConcept {
+ void constraints()
+ {
+ function_requires< CopyConstructibleConcept<Heuristic> >();
+ h(u);
+ }
+ Heuristic h;
+ typename graph_traits<Graph>::vertex_descriptor u;
+ };
+
+
+ template <class Graph, class CostType>
+ class astar_heuristic : public std::unary_function<
+ typename graph_traits<Graph>::vertex_descriptor, CostType>
+ {
+ public:
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ astar_heuristic() {}
+ CostType operator()(Vertex u) { return static_cast<CostType>(0); }
+ };
+
+
+
+ template <class Visitor, class Graph>
+ struct AStarVisitorConcept {
+ void constraints()
+ {
+ function_requires< CopyConstructibleConcept<Visitor> >();
+ vis.initialize_vertex(u, g);
+ vis.discover_vertex(u, g);
+ vis.examine_vertex(u, g);
+ vis.examine_edge(e, g);
+ vis.edge_relaxed(e, g);
+ vis.edge_not_relaxed(e, g);
+ vis.black_target(e, g);
+ vis.finish_vertex(u, g);
+ }
+ Visitor vis;
+ Graph g;
+ typename graph_traits<Graph>::vertex_descriptor u;
+ typename graph_traits<Graph>::edge_descriptor e;
+ };
+
+
+ template <class Visitors = null_visitor>
+ class astar_visitor : public bfs_visitor<Visitors> {
+ public:
+ astar_visitor() {}
+ astar_visitor(Visitors vis)
+ : bfs_visitor<Visitors>(vis) {}
+
+ template <class Edge, class Graph>
+ void edge_relaxed(Edge e, Graph& g) {
+ invoke_visitors(this->m_vis, e, g, on_edge_relaxed());
+ }
+ template <class Edge, class Graph>
+ void edge_not_relaxed(Edge e, Graph& g) {
+ invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed());
+ }
+ private:
+ template <class Edge, class Graph>
+ void tree_edge(Edge e, Graph& g) {}
+ template <class Edge, class Graph>
+ void non_tree_edge(Edge e, Graph& g) {}
+ };
+ template <class Visitors>
+ astar_visitor<Visitors>
+ make_astar_visitor(Visitors vis) {
+ return astar_visitor<Visitors>(vis);
+ }
+ typedef astar_visitor<> default_astar_visitor;
+
+
+ namespace detail {
+
+ template <class AStarHeuristic, class UniformCostVisitor,
+ class UpdatableQueue, class PredecessorMap,
+ class CostMap, class DistanceMap, class WeightMap,
+ class ColorMap, class BinaryFunction,
+ class BinaryPredicate>
+ struct astar_bfs_visitor
+ {
+
+ typedef typename property_traits<CostMap>::value_type C;
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+ typedef typename property_traits<DistanceMap>::value_type distance_type;
+
+ astar_bfs_visitor(AStarHeuristic h, UniformCostVisitor vis,
+ UpdatableQueue& Q, PredecessorMap p,
+ CostMap c, DistanceMap d, WeightMap w,
+ ColorMap col, BinaryFunction combine,
+ BinaryPredicate compare, C zero)
+ : m_h(h), m_vis(vis), m_Q(Q), m_predecessor(p), m_cost(c),
+ m_distance(d), m_weight(w), m_color(col),
+ m_combine(combine), m_compare(compare), m_zero(zero) {}
+
+
+ template <class Vertex, class Graph>
+ void initialize_vertex(Vertex u, Graph& g) {
+ m_vis.initialize_vertex(u, g);
+ }
+ template <class Vertex, class Graph>
+ void discover_vertex(Vertex u, Graph& g) {
+ m_vis.discover_vertex(u, g);
+ }
+ template <class Vertex, class Graph>
+ void examine_vertex(Vertex u, Graph& g) {
+ m_vis.examine_vertex(u, g);
+ }
+ template <class Vertex, class Graph>
+ void finish_vertex(Vertex u, Graph& g) {
+ m_vis.finish_vertex(u, g);
+ }
+ template <class Edge, class Graph>
+ void examine_edge(Edge e, Graph& g) {
+ if (m_compare(get(m_weight, e), m_zero))
+ throw negative_edge();
+ m_vis.examine_edge(e, g);
+ }
+ template <class Edge, class Graph>
+ void non_tree_edge(Edge, Graph&) {}
+
+
+
+ template <class Edge, class Graph>
+ void tree_edge(Edge e, Graph& g) {
+ m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
+ m_combine, m_compare);
+
+ if(m_decreased) {
+ m_vis.edge_relaxed(e, g);
+ put(m_cost, target(e, g),
+ m_combine(get(m_distance, target(e, g)),
+ m_h(target(e, g))));
+ } else
+ m_vis.edge_not_relaxed(e, g);
+ }
+
+
+ template <class Edge, class Graph>
+ void gray_target(Edge e, Graph& g) {
+ distance_type old_distance = get(m_distance, target(e, g));
+
+ m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
+ m_combine, m_compare);
+
+ /* On x86 Linux with optimization, we sometimes get into a
+ horrible case where m_decreased is true but the distance hasn't
+ actually changed. This occurs when the comparison inside
+ relax() occurs with the 80-bit precision of the x87 floating
+ point unit, but the difference is lost when the resulting
+ values are written back to lower-precision memory (e.g., a
+ double). With the eager Dijkstra's implementation, this results
+ in looping. */
+ if(m_decreased && old_distance != get(m_distance, target(e, g))) {
+ put(m_cost, target(e, g),
+ m_combine(get(m_distance, target(e, g)),
+ m_h(target(e, g))));
+ m_Q.update(target(e, g));
+ m_vis.edge_relaxed(e, g);
+ } else
+ m_vis.edge_not_relaxed(e, g);
+ }
+
+
+ template <class Edge, class Graph>
+ void black_target(Edge e, Graph& g) {
+ distance_type old_distance = get(m_distance, target(e, g));
+
+ m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
+ m_combine, m_compare);
+
+ /* See comment in gray_target */
+ if(m_decreased && old_distance != get(m_distance, target(e, g))) {
+ m_vis.edge_relaxed(e, g);
+ put(m_cost, target(e, g),
+ m_combine(get(m_distance, target(e, g)),
+ m_h(target(e, g))));
+ m_Q.push(target(e, g));
+ put(m_color, target(e, g), Color::gray());
+ m_vis.black_target(e, g);
+ } else
+ m_vis.edge_not_relaxed(e, g);
+ }
+
+
+
+ AStarHeuristic m_h;
+ UniformCostVisitor m_vis;
+ UpdatableQueue& m_Q;
+ PredecessorMap m_predecessor;
+ CostMap m_cost;
+ DistanceMap m_distance;
+ WeightMap m_weight;
+ ColorMap m_color;
+ BinaryFunction m_combine;
+ BinaryPredicate m_compare;
+ bool m_decreased;
+ C m_zero;
+
+ };
+
+ } // namespace detail
+
+
+
+ template <typename VertexListGraph, typename AStarHeuristic,
+ typename AStarVisitor, typename PredecessorMap,
+ typename CostMap, typename DistanceMap,
+ typename WeightMap, typename ColorMap,
+ typename VertexIndexMap,
+ typename CompareFunction, typename CombineFunction,
+ typename CostInf, typename CostZero>
+ inline void
+ astar_search_no_init
+ (VertexListGraph &g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ AStarHeuristic h, AStarVisitor vis,
+ PredecessorMap predecessor, CostMap cost,
+ DistanceMap distance, WeightMap weight,
+ ColorMap color, VertexIndexMap index_map,
+ CompareFunction compare, CombineFunction combine,
+ CostInf inf, CostZero zero)
+ {
+ typedef indirect_cmp<CostMap, CompareFunction> IndirectCmp;
+ IndirectCmp icmp(cost, compare);
+
+ typedef typename graph_traits<VertexListGraph>::vertex_descriptor
+ Vertex;
+ typedef mutable_queue<Vertex, std::vector<Vertex>,
+ IndirectCmp, VertexIndexMap>
+ MutableQueue;
+ MutableQueue Q(num_vertices(g), icmp, index_map);
+
+ detail::astar_bfs_visitor<AStarHeuristic, AStarVisitor,
+ MutableQueue, PredecessorMap, CostMap, DistanceMap,
+ WeightMap, ColorMap, CombineFunction, CompareFunction>
+ bfs_vis(h, vis, Q, predecessor, cost, distance, weight,
+ color, combine, compare, zero);
+
+ breadth_first_visit(g, s, Q, bfs_vis, color);
+ }
+
+
+ // Non-named parameter interface
+ template <typename VertexListGraph, typename AStarHeuristic,
+ typename AStarVisitor, typename PredecessorMap,
+ typename CostMap, typename DistanceMap,
+ typename WeightMap, typename VertexIndexMap,
+ typename ColorMap,
+ typename CompareFunction, typename CombineFunction,
+ typename CostInf, typename CostZero>
+ inline void
+ astar_search
+ (VertexListGraph &g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ AStarHeuristic h, AStarVisitor vis,
+ PredecessorMap predecessor, CostMap cost,
+ DistanceMap distance, WeightMap weight,
+ VertexIndexMap index_map, ColorMap color,
+ CompareFunction compare, CombineFunction combine,
+ CostInf inf, CostZero zero)
+ {
+
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+ typename graph_traits<VertexListGraph>::vertex_iterator ui, ui_end;
+ for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
+ put(color, *ui, Color::white());
+ put(distance, *ui, inf);
+ put(cost, *ui, inf);
+ put(predecessor, *ui, *ui);
+ vis.initialize_vertex(*ui, g);
+ }
+ put(distance, s, zero);
+ put(cost, s, h(s));
+
+ astar_search_no_init
+ (g, s, h, vis, predecessor, cost, distance, weight,
+ color, index_map, compare, combine, inf, zero);
+
+ }
+
+
+
+ namespace detail {
+ template <class VertexListGraph, class AStarHeuristic,
+ class CostMap, class DistanceMap, class WeightMap,
+ class IndexMap, class ColorMap, class Params>
+ inline void
+ astar_dispatch2
+ (VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ AStarHeuristic h, CostMap cost, DistanceMap distance,
+ WeightMap weight, IndexMap index_map, ColorMap color,
+ const Params& params)
+ {
+ dummy_property_map p_map;
+ typedef typename property_traits<CostMap>::value_type C;
+ astar_search
+ (g, s, h,
+ choose_param(get_param(params, graph_visitor),
+ make_astar_visitor(null_visitor())),
+ choose_param(get_param(params, vertex_predecessor), p_map),
+ cost, distance, weight, index_map, color,
+ choose_param(get_param(params, distance_compare_t()),
+ std::less<C>()),
+ choose_param(get_param(params, distance_combine_t()),
+ closed_plus<C>()),
+ choose_param(get_param(params, distance_inf_t()),
+ std::numeric_limits<C>::max BOOST_PREVENT_MACRO_SUBSTITUTION ()),
+ choose_param(get_param(params, distance_zero_t()),
+ C()));
+ }
+
+ template <class VertexListGraph, class AStarHeuristic,
+ class CostMap, class DistanceMap, class WeightMap,
+ class IndexMap, class ColorMap, class Params>
+ inline void
+ astar_dispatch1
+ (VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ AStarHeuristic h, CostMap cost, DistanceMap distance,
+ WeightMap weight, IndexMap index_map, ColorMap color,
+ const Params& params)
+ {
+ typedef typename property_traits<WeightMap>::value_type D;
+ typename std::vector<D>::size_type
+ n = is_default_param(distance) ? num_vertices(g) : 1;
+ std::vector<D> distance_map(n);
+ n = is_default_param(cost) ? num_vertices(g) : 1;
+ std::vector<D> cost_map(n);
+ std::vector<default_color_type> color_map(num_vertices(g));
+ default_color_type c = white_color;
+
+ detail::astar_dispatch2
+ (g, s, h,
+ choose_param(cost, make_iterator_property_map
+ (cost_map.begin(), index_map,
+ cost_map[0])),
+ choose_param(distance, make_iterator_property_map
+ (distance_map.begin(), index_map,
+ distance_map[0])),
+ weight, index_map,
+ choose_param(color, make_iterator_property_map
+ (color_map.begin(), index_map, c)),
+ params);
+ }
+ } // namespace detail
+
+
+ // Named parameter interface
+ template <typename VertexListGraph,
+ typename AStarHeuristic,
+ typename P, typename T, typename R>
+ void
+ astar_search
+ (VertexListGraph &g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ AStarHeuristic h, const bgl_named_params<P, T, R>& params)
+ {
+
+ detail::astar_dispatch1
+ (g, s, h,
+ get_param(params, vertex_rank),
+ get_param(params, vertex_distance),
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
+ get_param(params, vertex_color),
+ params);
+
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_ASTAR_SEARCH_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/bandwidth.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/bandwidth.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,83 @@
+// Copyright (c) Jeremy Siek 2001, Marc Wintermantel 2002
+//
+// 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)
+
+#ifndef BOOST_GRAPH_BANDWIDTH_HPP
+#define BOOST_GRAPH_BANDWIDTH_HPP
+
+#include <algorithm> // for std::min and std::max
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/detail/numeric_traits.hpp>
+
+namespace boost {
+
+ template <typename Graph, typename VertexIndexMap>
+ typename graph_traits<Graph>::vertices_size_type
+ ith_bandwidth(typename graph_traits<Graph>::vertex_descriptor i,
+ const Graph& g,
+ VertexIndexMap index)
+ {
+ BOOST_USING_STD_MAX();
+ typedef typename graph_traits<Graph>::vertices_size_type size_type;
+ size_type b = 0;
+ typename graph_traits<Graph>::out_edge_iterator e, end;
+ for (tie(e, end) = out_edges(i, g); e != end; ++e) {
+ int f_i = get(index, i);
+ int f_j = get(index, target(*e, g));
+ using namespace std; // to call abs() unqualified
+ if(f_i > f_j)
+ b = max BOOST_PREVENT_MACRO_SUBSTITUTION (b, size_type(f_i - f_j));
+ }
+ return b;
+ }
+
+ template <typename Graph>
+ typename graph_traits<Graph>::vertices_size_type
+ ith_bandwidth(typename graph_traits<Graph>::vertex_descriptor i,
+ const Graph& g)
+ {
+ return ith_bandwidth(i, g, get(vertex_index, g));
+ }
+
+ template <typename Graph, typename VertexIndexMap>
+ typename graph_traits<Graph>::vertices_size_type
+ bandwidth(const Graph& g, VertexIndexMap index)
+ {
+ BOOST_USING_STD_MAX();
+ typename graph_traits<Graph>::vertices_size_type b = 0;
+ typename graph_traits<Graph>::vertex_iterator i, end;
+ for (tie(i, end) = vertices(g); i != end; ++i)
+ b = max BOOST_PREVENT_MACRO_SUBSTITUTION (b, ith_bandwidth(*i, g, index));
+ return b;
+ }
+
+ template <typename Graph>
+ typename graph_traits<Graph>::vertices_size_type
+ bandwidth(const Graph& g)
+ {
+ return bandwidth(g, get(vertex_index, g));
+ }
+
+ template <typename Graph, typename VertexIndexMap>
+ typename graph_traits<Graph>::vertices_size_type
+ edgesum(const Graph& g, VertexIndexMap index_map)
+ {
+ typedef typename graph_traits<Graph>::vertices_size_type size_type;
+ typedef typename detail::numeric_traits<size_type>::difference_type diff_t;
+ size_type sum = 0;
+ typename graph_traits<Graph>::edge_iterator i, end;
+ for (tie(i, end) = edges(g); i != end; ++i) {
+ diff_t f_u = get(index_map, source(*i, g));
+ diff_t f_v = get(index_map, target(*i, g));
+ using namespace std; // to call abs() unqualified
+ sum += abs(f_u - f_v);
+ }
+ return sum;
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_BANDWIDTH_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/bc_clustering.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/bc_clustering.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,164 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// 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)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_BETWEENNESS_CENTRALITY_CLUSTERING_HPP
+#define BOOST_GRAPH_BETWEENNESS_CENTRALITY_CLUSTERING_HPP
+
+#include <boost/graph/betweenness_centrality.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/pending/indirect_cmp.hpp>
+#include <algorithm>
+#include <vector>
+#include <boost/property_map.hpp>
+
+namespace boost {
+
+/** Threshold termination function for the betweenness centrality
+ * clustering algorithm.
+ */
+template<typename T>
+struct bc_clustering_threshold
+{
+ typedef T centrality_type;
+
+ /// Terminate clustering when maximum absolute edge centrality is
+ /// below the given threshold.
+ explicit bc_clustering_threshold(T threshold)
+ : threshold(threshold), dividend(1.0) {}
+
+ /**
+ * Terminate clustering when the maximum edge centrality is below
+ * the given threshold.
+ *
+ * @param threshold the threshold value
+ *
+ * @param g the graph on which the threshold will be calculated
+ *
+ * @param normalize when true, the threshold is compared against the
+ * normalized edge centrality based on the input graph; otherwise,
+ * the threshold is compared against the absolute edge centrality.
+ */
+ template<typename Graph>
+ bc_clustering_threshold(T threshold, const Graph& g, bool normalize = true)
+ : threshold(threshold), dividend(1.0)
+ {
+ if (normalize) {
+ typename graph_traits<Graph>::vertices_size_type n = num_vertices(g);
+ dividend = T((n - 1) * (n - 2)) / T(2);
+ }
+ }
+
+ /** Returns true when the given maximum edge centrality (potentially
+ * normalized) falls below the threshold.
+ */
+ template<typename Graph, typename Edge>
+ bool operator()(T max_centrality, Edge, const Graph&)
+ {
+ return (max_centrality / dividend) < threshold;
+ }
+
+ protected:
+ T threshold;
+ T dividend;
+};
+
+/** Graph clustering based on edge betweenness centrality.
+ *
+ * This algorithm implements graph clustering based on edge
+ * betweenness centrality. It is an iterative algorithm, where in each
+ * step it compute the edge betweenness centrality (via @ref
+ * brandes_betweenness_centrality) and removes the edge with the
+ * maximum betweenness centrality. The @p done function object
+ * determines when the algorithm terminates (the edge found when the
+ * algorithm terminates will not be removed).
+ *
+ * @param g The graph on which clustering will be performed. The type
+ * of this parameter (@c MutableGraph) must be a model of the
+ * VertexListGraph, IncidenceGraph, EdgeListGraph, and Mutable Graph
+ * concepts.
+ *
+ * @param done The function object that indicates termination of the
+ * algorithm. It must be a ternary function object thats accepts the
+ * maximum centrality, the descriptor of the edge that will be
+ * removed, and the graph @p g.
+ *
+ * @param edge_centrality (UTIL/OUT) The property map that will store
+ * the betweenness centrality for each edge. When the algorithm
+ * terminates, it will contain the edge centralities for the
+ * graph. The type of this property map must model the
+ * ReadWritePropertyMap concept. Defaults to an @c
+ * iterator_property_map whose value type is
+ * @c Done::centrality_type and using @c get(edge_index, g) for the
+ * index map.
+ *
+ * @param vertex_index (IN) The property map that maps vertices to
+ * indices in the range @c [0, num_vertices(g)). This type of this
+ * property map must model the ReadablePropertyMap concept and its
+ * value type must be an integral type. Defaults to
+ * @c get(vertex_index, g).
+ */
+template<typename MutableGraph, typename Done, typename EdgeCentralityMap,
+ typename VertexIndexMap>
+void
+betweenness_centrality_clustering(MutableGraph& g, Done done,
+ EdgeCentralityMap edge_centrality,
+ VertexIndexMap vertex_index)
+{
+ typedef typename property_traits<EdgeCentralityMap>::value_type
+ centrality_type;
+ typedef typename graph_traits<MutableGraph>::edge_iterator edge_iterator;
+ typedef typename graph_traits<MutableGraph>::edge_descriptor edge_descriptor;
+ typedef typename graph_traits<MutableGraph>::vertices_size_type
+ vertices_size_type;
+
+ if (edges(g).first == edges(g).second) return;
+
+ // Function object that compares the centrality of edges
+ indirect_cmp<EdgeCentralityMap, std::less<centrality_type> >
+ cmp(edge_centrality);
+
+ bool is_done;
+ do {
+ brandes_betweenness_centrality(g,
+ edge_centrality_map(edge_centrality)
+ .vertex_index_map(vertex_index));
+ edge_descriptor e = *max_element(edges(g).first, edges(g).second, cmp);
+ is_done = done(get(edge_centrality, e), e, g);
+ if (!is_done) remove_edge(e, g);
+ } while (!is_done && edges(g).first != edges(g).second);
+}
+
+/**
+ * \overload
+ */
+template<typename MutableGraph, typename Done, typename EdgeCentralityMap>
+void
+betweenness_centrality_clustering(MutableGraph& g, Done done,
+ EdgeCentralityMap edge_centrality)
+{
+ betweenness_centrality_clustering(g, done, edge_centrality,
+ get(vertex_index, g));
+}
+
+/**
+ * \overload
+ */
+template<typename MutableGraph, typename Done>
+void
+betweenness_centrality_clustering(MutableGraph& g, Done done)
+{
+ typedef typename Done::centrality_type centrality_type;
+ std::vector<centrality_type> edge_centrality(num_edges(g));
+ betweenness_centrality_clustering(g, done,
+ make_iterator_property_map(edge_centrality.begin(), get(edge_index, g)),
+ get(vertex_index, g));
+}
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_BETWEENNESS_CENTRALITY_CLUSTERING_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/bellman_ford_shortest_paths.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/bellman_ford_shortest_paths.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,241 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+
+/*
+ This file implements the function
+
+ template <class EdgeListGraph, class Size, class P, class T, class R>
+ bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N,
+ const bgl_named_params<P, T, R>& params)
+
+ */
+
+
+#ifndef BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP
+#define BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP
+
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/relax.hpp>
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/named_function_params.hpp>
+
+namespace boost {
+
+ template <class Visitor, class Graph>
+ struct BellmanFordVisitorConcept {
+ void constraints() {
+ function_requires< CopyConstructibleConcept<Visitor> >();
+ vis.examine_edge(e, g);
+ vis.edge_relaxed(e, g);
+ vis.edge_not_relaxed(e, g);
+ vis.edge_minimized(e, g);
+ vis.edge_not_minimized(e, g);
+ }
+ Visitor vis;
+ Graph g;
+ typename graph_traits<Graph>::edge_descriptor e;
+ };
+
+ template <class Visitors = null_visitor>
+ class bellman_visitor {
+ public:
+ bellman_visitor() { }
+ bellman_visitor(Visitors vis) : m_vis(vis) { }
+
+ template <class Edge, class Graph>
+ void examine_edge(Edge u, Graph& g) {
+ invoke_visitors(m_vis, u, g, on_examine_edge());
+ }
+ template <class Edge, class Graph>
+ void edge_relaxed(Edge u, Graph& g) {
+ invoke_visitors(m_vis, u, g, on_edge_relaxed());
+ }
+ template <class Edge, class Graph>
+ void edge_not_relaxed(Edge u, Graph& g) {
+ invoke_visitors(m_vis, u, g, on_edge_not_relaxed());
+ }
+ template <class Edge, class Graph>
+ void edge_minimized(Edge u, Graph& g) {
+ invoke_visitors(m_vis, u, g, on_edge_minimized());
+ }
+ template <class Edge, class Graph>
+ void edge_not_minimized(Edge u, Graph& g) {
+ invoke_visitors(m_vis, u, g, on_edge_not_minimized());
+ }
+ protected:
+ Visitors m_vis;
+ };
+ template <class Visitors>
+ bellman_visitor<Visitors>
+ make_bellman_visitor(Visitors vis) {
+ return bellman_visitor<Visitors>(vis);
+ }
+ typedef bellman_visitor<> default_bellman_visitor;
+
+ template <class EdgeListGraph, class Size, class WeightMap,
+ class PredecessorMap, class DistanceMap,
+ class BinaryFunction, class BinaryPredicate,
+ class BellmanFordVisitor>
+ bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N,
+ WeightMap weight,
+ PredecessorMap pred,
+ DistanceMap distance,
+ BinaryFunction combine,
+ BinaryPredicate compare,
+ BellmanFordVisitor v)
+ {
+ function_requires<EdgeListGraphConcept<EdgeListGraph> >();
+ typedef graph_traits<EdgeListGraph> GTraits;
+ typedef typename GTraits::edge_descriptor Edge;
+ typedef typename GTraits::vertex_descriptor Vertex;
+ function_requires<ReadWritePropertyMapConcept<DistanceMap, Vertex> >();
+ function_requires<ReadablePropertyMapConcept<WeightMap, Edge> >();
+ typedef typename property_traits<DistanceMap>::value_type D_value;
+ typedef typename property_traits<WeightMap>::value_type W_value;
+
+ typename GTraits::edge_iterator i, end;
+
+ for (Size k = 0; k < N; ++k) {
+ bool at_least_one_edge_relaxed = false;
+ for (tie(i, end) = edges(g); i != end; ++i) {
+ v.examine_edge(*i, g);
+ if (relax(*i, g, weight, pred, distance, combine, compare)) {
+ at_least_one_edge_relaxed = true;
+ v.edge_relaxed(*i, g);
+ } else
+ v.edge_not_relaxed(*i, g);
+ }
+ if (!at_least_one_edge_relaxed)
+ break;
+ }
+
+ for (tie(i, end) = edges(g); i != end; ++i)
+ if (compare(combine(get(distance, source(*i, g)), get(weight, *i)),
+ get(distance, target(*i,g))))
+ {
+ v.edge_not_minimized(*i, g);
+ return false;
+ } else
+ v.edge_minimized(*i, g);
+
+ return true;
+ }
+
+ namespace detail {
+
+ template<typename VertexAndEdgeListGraph, typename Size,
+ typename WeightMap, typename PredecessorMap, typename DistanceMap,
+ typename P, typename T, typename R>
+ bool
+ bellman_dispatch2
+ (VertexAndEdgeListGraph& g,
+ typename graph_traits<VertexAndEdgeListGraph>::vertex_descriptor s,
+ Size N, WeightMap weight, PredecessorMap pred, DistanceMap distance,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef typename property_traits<DistanceMap>::value_type D;
+ bellman_visitor<> null_vis;
+ typedef typename property_traits<WeightMap>::value_type weight_type;
+ typename graph_traits<VertexAndEdgeListGraph>::vertex_iterator v, v_end;
+ for (tie(v, v_end) = vertices(g); v != v_end; ++v) {
+ put(distance, *v, (std::numeric_limits<weight_type>::max)());
+ put(pred, *v, *v);
+ }
+ put(distance, s, weight_type(0));
+ return bellman_ford_shortest_paths
+ (g, N, weight, pred, distance,
+ choose_param(get_param(params, distance_combine_t()),
+ closed_plus<D>()),
+ choose_param(get_param(params, distance_compare_t()),
+ std::less<D>()),
+ choose_param(get_param(params, graph_visitor),
+ null_vis)
+ );
+ }
+
+ template<typename VertexAndEdgeListGraph, typename Size,
+ typename WeightMap, typename PredecessorMap, typename DistanceMap,
+ typename P, typename T, typename R>
+ bool
+ bellman_dispatch2
+ (VertexAndEdgeListGraph& g,
+ detail::error_property_not_found,
+ Size N, WeightMap weight, PredecessorMap pred, DistanceMap distance,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef typename property_traits<DistanceMap>::value_type D;
+ bellman_visitor<> null_vis;
+ return bellman_ford_shortest_paths
+ (g, N, weight, pred, distance,
+ choose_param(get_param(params, distance_combine_t()),
+ closed_plus<D>()),
+ choose_param(get_param(params, distance_compare_t()),
+ std::less<D>()),
+ choose_param(get_param(params, graph_visitor),
+ null_vis)
+ );
+ }
+
+ template <class EdgeListGraph, class Size, class WeightMap,
+ class DistanceMap, class P, class T, class R>
+ bool bellman_dispatch(EdgeListGraph& g, Size N,
+ WeightMap weight, DistanceMap distance,
+ const bgl_named_params<P, T, R>& params)
+ {
+ dummy_property_map dummy_pred;
+ return
+ detail::bellman_dispatch2
+ (g,
+ get_param(params, root_vertex_t()),
+ N, weight,
+ choose_param(get_param(params, vertex_predecessor), dummy_pred),
+ distance,
+ params);
+ }
+ } // namespace detail
+
+ template <class EdgeListGraph, class Size, class P, class T, class R>
+ bool bellman_ford_shortest_paths
+ (EdgeListGraph& g, Size N,
+ const bgl_named_params<P, T, R>& params)
+ {
+ return detail::bellman_dispatch
+ (g, N,
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ choose_pmap(get_param(params, vertex_distance), g, vertex_distance),
+ params);
+ }
+
+ template <class EdgeListGraph, class Size>
+ bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N)
+ {
+ bgl_named_params<int,int> params(0);
+ return bellman_ford_shortest_paths(g, N, params);
+ }
+
+ template <class VertexAndEdgeListGraph, class P, class T, class R>
+ bool bellman_ford_shortest_paths
+ (VertexAndEdgeListGraph& g,
+ const bgl_named_params<P, T, R>& params)
+ {
+ function_requires<VertexListGraphConcept<VertexAndEdgeListGraph> >();
+ return detail::bellman_dispatch
+ (g, num_vertices(g),
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ choose_pmap(get_param(params, vertex_distance), g, vertex_distance),
+ params);
+ }
+} // namespace boost
+
+#endif // BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/betweenness_centrality.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/betweenness_centrality.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,597 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// 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)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_BRANDES_BETWEENNESS_CENTRALITY_HPP
+#define BOOST_GRAPH_BRANDES_BETWEENNESS_CENTRALITY_HPP
+
+#include <stack>
+#include <vector>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/relax.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <algorithm>
+
+namespace boost {
+
+namespace detail { namespace graph {
+
+ /**
+ * Customized visitor passed to Dijkstra's algorithm by Brandes'
+ * betweenness centrality algorithm. This visitor is responsible for
+ * keeping track of the order in which vertices are discovered, the
+ * predecessors on the shortest path(s) to a vertex, and the number
+ * of shortest paths.
+ */
+ template<typename Graph, typename WeightMap, typename IncomingMap,
+ typename DistanceMap, typename PathCountMap>
+ struct brandes_dijkstra_visitor : public bfs_visitor<>
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
+
+ brandes_dijkstra_visitor(std::stack<vertex_descriptor>& ordered_vertices,
+ WeightMap weight,
+ IncomingMap incoming,
+ DistanceMap distance,
+ PathCountMap path_count)
+ : ordered_vertices(ordered_vertices), weight(weight),
+ incoming(incoming), distance(distance),
+ path_count(path_count)
+ { }
+
+ /**
+ * Whenever an edge e = (v, w) is relaxed, the incoming edge list
+ * for w is set to {(v, w)} and the shortest path count of w is set to
+ * the number of paths that reach {v}.
+ */
+ void edge_relaxed(edge_descriptor e, const Graph& g)
+ {
+ vertex_descriptor v = source(e, g), w = target(e, g);
+ incoming[w].clear();
+ incoming[w].push_back(e);
+ put(path_count, w, get(path_count, v));
+ }
+
+ /**
+ * If an edge e = (v, w) was not relaxed, it may still be the case
+ * that we've found more equally-short paths, so include {(v, w)} in the
+ * incoming edges of w and add all of the shortest paths to v to the
+ * shortest path count of w.
+ */
+ void edge_not_relaxed(edge_descriptor e, const Graph& g)
+ {
+ typedef typename property_traits<WeightMap>::value_type weight_type;
+ typedef typename property_traits<DistanceMap>::value_type distance_type;
+ vertex_descriptor v = source(e, g), w = target(e, g);
+ distance_type d_v = get(distance, v), d_w = get(distance, w);
+ weight_type w_e = get(weight, e);
+
+ closed_plus<distance_type> combine;
+ if (d_w == combine(d_v, w_e)) {
+ put(path_count, w, get(path_count, w) + get(path_count, v));
+ incoming[w].push_back(e);
+ }
+ }
+
+ /// Keep track of vertices as they are reached
+ void examine_vertex(vertex_descriptor w, const Graph&)
+ {
+ ordered_vertices.push(w);
+ }
+
+ private:
+ std::stack<vertex_descriptor>& ordered_vertices;
+ WeightMap weight;
+ IncomingMap incoming;
+ DistanceMap distance;
+ PathCountMap path_count;
+ };
+
+ /**
+ * Function object that calls Dijkstra's shortest paths algorithm
+ * using the Dijkstra visitor for the Brandes betweenness centrality
+ * algorithm.
+ */
+ template<typename WeightMap>
+ struct brandes_dijkstra_shortest_paths
+ {
+ brandes_dijkstra_shortest_paths(WeightMap weight_map)
+ : weight_map(weight_map) { }
+
+ template<typename Graph, typename IncomingMap, typename DistanceMap,
+ typename PathCountMap, typename VertexIndexMap>
+ void
+ operator()(Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor s,
+ std::stack<typename graph_traits<Graph>::vertex_descriptor>& ov,
+ IncomingMap incoming,
+ DistanceMap distance,
+ PathCountMap path_count,
+ VertexIndexMap vertex_index)
+ {
+ typedef brandes_dijkstra_visitor<Graph, WeightMap, IncomingMap,
+ DistanceMap, PathCountMap> visitor_type;
+ visitor_type visitor(ov, weight_map, incoming, distance, path_count);
+
+ dijkstra_shortest_paths(g, s,
+ boost::weight_map(weight_map)
+ .vertex_index_map(vertex_index)
+ .distance_map(distance)
+ .visitor(visitor));
+ }
+
+ private:
+ WeightMap weight_map;
+ };
+
+ /**
+ * Function object that invokes breadth-first search for the
+ * unweighted form of the Brandes betweenness centrality algorithm.
+ */
+ struct brandes_unweighted_shortest_paths
+ {
+ /**
+ * Customized visitor passed to breadth-first search, which
+ * records predecessor and the number of shortest paths to each
+ * vertex.
+ */
+ template<typename Graph, typename IncomingMap, typename DistanceMap,
+ typename PathCountMap>
+ struct visitor_type : public bfs_visitor<>
+ {
+ typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
+ typedef typename graph_traits<Graph>::vertex_descriptor
+ vertex_descriptor;
+
+ visitor_type(IncomingMap incoming, DistanceMap distance,
+ PathCountMap path_count,
+ std::stack<vertex_descriptor>& ordered_vertices)
+ : incoming(incoming), distance(distance),
+ path_count(path_count), ordered_vertices(ordered_vertices) { }
+
+ /// Keep track of vertices as they are reached
+ void examine_vertex(vertex_descriptor v, Graph&)
+ {
+ ordered_vertices.push(v);
+ }
+
+ /**
+ * Whenever an edge e = (v, w) is labelled a tree edge, the
+ * incoming edge list for w is set to {(v, w)} and the shortest
+ * path count of w is set to the number of paths that reach {v}.
+ */
+ void tree_edge(edge_descriptor e, Graph& g)
+ {
+ vertex_descriptor v = source(e, g);
+ vertex_descriptor w = target(e, g);
+ put(distance, w, get(distance, v) + 1);
+
+ put(path_count, w, get(path_count, v));
+ incoming[w].push_back(e);
+ }
+
+ /**
+ * If an edge e = (v, w) is not a tree edge, it may still be the
+ * case that we've found more equally-short paths, so include (v, w)
+ * in the incoming edge list of w and add all of the shortest
+ * paths to v to the shortest path count of w.
+ */
+ void non_tree_edge(edge_descriptor e, Graph& g)
+ {
+ vertex_descriptor v = source(e, g);
+ vertex_descriptor w = target(e, g);
+ if (get(distance, w) == get(distance, v) + 1) {
+ put(path_count, w, get(path_count, w) + get(path_count, v));
+ incoming[w].push_back(e);
+ }
+ }
+
+ private:
+ IncomingMap incoming;
+ DistanceMap distance;
+ PathCountMap path_count;
+ std::stack<vertex_descriptor>& ordered_vertices;
+ };
+
+ template<typename Graph, typename IncomingMap, typename DistanceMap,
+ typename PathCountMap, typename VertexIndexMap>
+ void
+ operator()(Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor s,
+ std::stack<typename graph_traits<Graph>::vertex_descriptor>& ov,
+ IncomingMap incoming,
+ DistanceMap distance,
+ PathCountMap path_count,
+ VertexIndexMap vertex_index)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor
+ vertex_descriptor;
+
+ visitor_type<Graph, IncomingMap, DistanceMap, PathCountMap>
+ visitor(incoming, distance, path_count, ov);
+
+ std::vector<default_color_type>
+ colors(num_vertices(g), color_traits<default_color_type>::white());
+ boost::queue<vertex_descriptor> Q;
+ breadth_first_visit(g, s, Q, visitor,
+ make_iterator_property_map(colors.begin(),
+ vertex_index));
+ }
+ };
+
+ // When the edge centrality map is a dummy property map, no
+ // initialization is needed.
+ template<typename Iter>
+ inline void
+ init_centrality_map(std::pair<Iter, Iter>, dummy_property_map) { }
+
+ // When we have a real edge centrality map, initialize all of the
+ // centralities to zero.
+ template<typename Iter, typename Centrality>
+ void
+ init_centrality_map(std::pair<Iter, Iter> keys, Centrality centrality_map)
+ {
+ typedef typename property_traits<Centrality>::value_type
+ centrality_type;
+ while (keys.first != keys.second) {
+ put(centrality_map, *keys.first, centrality_type(0));
+ ++keys.first;
+ }
+ }
+
+ // When the edge centrality map is a dummy property map, no update
+ // is performed.
+ template<typename Key, typename T>
+ inline void
+ update_centrality(dummy_property_map, const Key&, const T&) { }
+
+ // When we have a real edge centrality map, add the value to the map
+ template<typename CentralityMap, typename Key, typename T>
+ inline void
+ update_centrality(CentralityMap centrality_map, Key k, const T& x)
+ { put(centrality_map, k, get(centrality_map, k) + x); }
+
+ template<typename Iter>
+ inline void
+ divide_centrality_by_two(std::pair<Iter, Iter>, dummy_property_map) {}
+
+ template<typename Iter, typename CentralityMap>
+ inline void
+ divide_centrality_by_two(std::pair<Iter, Iter> keys,
+ CentralityMap centrality_map)
+ {
+ typename property_traits<CentralityMap>::value_type two(2);
+ while (keys.first != keys.second) {
+ put(centrality_map, *keys.first, get(centrality_map, *keys.first) / two);
+ ++keys.first;
+ }
+ }
+
+ template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
+ typename IncomingMap, typename DistanceMap,
+ typename DependencyMap, typename PathCountMap,
+ typename VertexIndexMap, typename ShortestPaths>
+ void
+ brandes_betweenness_centrality_impl(const Graph& g,
+ CentralityMap centrality, // C_B
+ EdgeCentralityMap edge_centrality_map,
+ IncomingMap incoming, // P
+ DistanceMap distance, // d
+ DependencyMap dependency, // delta
+ PathCountMap path_count, // sigma
+ VertexIndexMap vertex_index,
+ ShortestPaths shortest_paths)
+ {
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
+ typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+
+ // Initialize centrality
+ init_centrality_map(vertices(g), centrality);
+ init_centrality_map(edges(g), edge_centrality_map);
+
+ std::stack<vertex_descriptor> ordered_vertices;
+ vertex_iterator s, s_end;
+ for (tie(s, s_end) = vertices(g); s != s_end; ++s) {
+ // Initialize for this iteration
+ vertex_iterator w, w_end;
+ for (tie(w, w_end) = vertices(g); w != w_end; ++w) {
+ incoming[*w].clear();
+ put(path_count, *w, 0);
+ put(dependency, *w, 0);
+ }
+ put(path_count, *s, 1);
+
+ // Execute the shortest paths algorithm. This will be either
+ // Dijkstra's algorithm or a customized breadth-first search,
+ // depending on whether the graph is weighted or unweighted.
+ shortest_paths(g, *s, ordered_vertices, incoming, distance,
+ path_count, vertex_index);
+
+ while (!ordered_vertices.empty()) {
+ vertex_descriptor w = ordered_vertices.top();
+ ordered_vertices.pop();
+
+ typedef typename property_traits<IncomingMap>::value_type
+ incoming_type;
+ typedef typename incoming_type::iterator incoming_iterator;
+ typedef typename property_traits<DependencyMap>::value_type
+ dependency_type;
+
+ for (incoming_iterator vw = incoming[w].begin();
+ vw != incoming[w].end(); ++vw) {
+ vertex_descriptor v = source(*vw, g);
+ dependency_type factor = dependency_type(get(path_count, v))
+ / dependency_type(get(path_count, w));
+ factor *= (dependency_type(1) + get(dependency, w));
+ put(dependency, v, get(dependency, v) + factor);
+ update_centrality(edge_centrality_map, *vw, factor);
+ }
+
+ if (w != *s) {
+ update_centrality(centrality, w, get(dependency, w));
+ }
+ }
+ }
+
+ typedef typename graph_traits<Graph>::directed_category directed_category;
+ const bool is_undirected =
+ is_convertible<directed_category*, undirected_tag*>::value;
+ if (is_undirected) {
+ divide_centrality_by_two(vertices(g), centrality);
+ divide_centrality_by_two(edges(g), edge_centrality_map);
+ }
+ }
+
+} } // end namespace detail::graph
+
+template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
+ typename IncomingMap, typename DistanceMap,
+ typename DependencyMap, typename PathCountMap,
+ typename VertexIndexMap>
+void
+brandes_betweenness_centrality(const Graph& g,
+ CentralityMap centrality, // C_B
+ EdgeCentralityMap edge_centrality_map,
+ IncomingMap incoming, // P
+ DistanceMap distance, // d
+ DependencyMap dependency, // delta
+ PathCountMap path_count, // sigma
+ VertexIndexMap vertex_index)
+{
+ detail::graph::brandes_unweighted_shortest_paths shortest_paths;
+
+ detail::graph::brandes_betweenness_centrality_impl(g, centrality,
+ edge_centrality_map,
+ incoming, distance,
+ dependency, path_count,
+ vertex_index,
+ shortest_paths);
+}
+
+template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
+ typename IncomingMap, typename DistanceMap,
+ typename DependencyMap, typename PathCountMap,
+ typename VertexIndexMap, typename WeightMap>
+void
+brandes_betweenness_centrality(const Graph& g,
+ CentralityMap centrality, // C_B
+ EdgeCentralityMap edge_centrality_map,
+ IncomingMap incoming, // P
+ DistanceMap distance, // d
+ DependencyMap dependency, // delta
+ PathCountMap path_count, // sigma
+ VertexIndexMap vertex_index,
+ WeightMap weight_map)
+{
+ detail::graph::brandes_dijkstra_shortest_paths<WeightMap>
+ shortest_paths(weight_map);
+
+ detail::graph::brandes_betweenness_centrality_impl(g, centrality,
+ edge_centrality_map,
+ incoming, distance,
+ dependency, path_count,
+ vertex_index,
+ shortest_paths);
+}
+
+namespace detail { namespace graph {
+ template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
+ typename WeightMap, typename VertexIndexMap>
+ void
+ brandes_betweenness_centrality_dispatch2(const Graph& g,
+ CentralityMap centrality,
+ EdgeCentralityMap edge_centrality_map,
+ WeightMap weight_map,
+ VertexIndexMap vertex_index)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
+ typedef typename mpl::if_c<(is_same<CentralityMap,
+ dummy_property_map>::value),
+ EdgeCentralityMap,
+ CentralityMap>::type a_centrality_map;
+ typedef typename property_traits<a_centrality_map>::value_type
+ centrality_type;
+
+ typename graph_traits<Graph>::vertices_size_type V = num_vertices(g);
+
+ std::vector<std::vector<edge_descriptor> > incoming(V);
+ std::vector<centrality_type> distance(V);
+ std::vector<centrality_type> dependency(V);
+ std::vector<unsigned long long> path_count(V);
+
+ brandes_betweenness_centrality(
+ g, centrality, edge_centrality_map,
+ make_iterator_property_map(incoming.begin(), vertex_index),
+ make_iterator_property_map(distance.begin(), vertex_index),
+ make_iterator_property_map(dependency.begin(), vertex_index),
+ make_iterator_property_map(path_count.begin(), vertex_index),
+ vertex_index,
+ weight_map);
+ }
+
+
+ template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
+ typename VertexIndexMap>
+ void
+ brandes_betweenness_centrality_dispatch2(const Graph& g,
+ CentralityMap centrality,
+ EdgeCentralityMap edge_centrality_map,
+ VertexIndexMap vertex_index)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
+ typedef typename mpl::if_c<(is_same<CentralityMap,
+ dummy_property_map>::value),
+ EdgeCentralityMap,
+ CentralityMap>::type a_centrality_map;
+ typedef typename property_traits<a_centrality_map>::value_type
+ centrality_type;
+
+ typename graph_traits<Graph>::vertices_size_type V = num_vertices(g);
+
+ std::vector<std::vector<edge_descriptor> > incoming(V);
+ std::vector<centrality_type> distance(V);
+ std::vector<centrality_type> dependency(V);
+ std::vector<unsigned long long> path_count(V);
+
+ brandes_betweenness_centrality(
+ g, centrality, edge_centrality_map,
+ make_iterator_property_map(incoming.begin(), vertex_index),
+ make_iterator_property_map(distance.begin(), vertex_index),
+ make_iterator_property_map(dependency.begin(), vertex_index),
+ make_iterator_property_map(path_count.begin(), vertex_index),
+ vertex_index);
+ }
+
+ template<typename WeightMap>
+ struct brandes_betweenness_centrality_dispatch1
+ {
+ template<typename Graph, typename CentralityMap,
+ typename EdgeCentralityMap, typename VertexIndexMap>
+ static void
+ run(const Graph& g, CentralityMap centrality,
+ EdgeCentralityMap edge_centrality_map, VertexIndexMap vertex_index,
+ WeightMap weight_map)
+ {
+ brandes_betweenness_centrality_dispatch2(g, centrality, edge_centrality_map,
+ weight_map, vertex_index);
+ }
+ };
+
+ template<>
+ struct brandes_betweenness_centrality_dispatch1<error_property_not_found>
+ {
+ template<typename Graph, typename CentralityMap,
+ typename EdgeCentralityMap, typename VertexIndexMap>
+ static void
+ run(const Graph& g, CentralityMap centrality,
+ EdgeCentralityMap edge_centrality_map, VertexIndexMap vertex_index,
+ error_property_not_found)
+ {
+ brandes_betweenness_centrality_dispatch2(g, centrality, edge_centrality_map,
+ vertex_index);
+ }
+ };
+
+} } // end namespace detail::graph
+
+template<typename Graph, typename Param, typename Tag, typename Rest>
+void
+brandes_betweenness_centrality(const Graph& g,
+ const bgl_named_params<Param,Tag,Rest>& params)
+{
+ typedef bgl_named_params<Param,Tag,Rest> named_params;
+
+ typedef typename property_value<named_params, edge_weight_t>::type ew;
+ detail::graph::brandes_betweenness_centrality_dispatch1<ew>::run(
+ g,
+ choose_param(get_param(params, vertex_centrality),
+ dummy_property_map()),
+ choose_param(get_param(params, edge_centrality),
+ dummy_property_map()),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
+ get_param(params, edge_weight));
+}
+
+template<typename Graph, typename CentralityMap>
+void
+brandes_betweenness_centrality(const Graph& g, CentralityMap centrality)
+{
+ detail::graph::brandes_betweenness_centrality_dispatch2(
+ g, centrality, dummy_property_map(), get(vertex_index, g));
+}
+
+template<typename Graph, typename CentralityMap, typename EdgeCentralityMap>
+void
+brandes_betweenness_centrality(const Graph& g, CentralityMap centrality,
+ EdgeCentralityMap edge_centrality_map)
+{
+ detail::graph::brandes_betweenness_centrality_dispatch2(
+ g, centrality, edge_centrality_map, get(vertex_index, g));
+}
+
+/**
+ * Converts "absolute" betweenness centrality (as computed by the
+ * brandes_betweenness_centrality algorithm) in the centrality map
+ * into "relative" centrality. The result is placed back into the
+ * given centrality map.
+ */
+template<typename Graph, typename CentralityMap>
+void
+relative_betweenness_centrality(const Graph& g, CentralityMap centrality)
+{
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
+ typedef typename property_traits<CentralityMap>::value_type centrality_type;
+
+ typename graph_traits<Graph>::vertices_size_type n = num_vertices(g);
+ centrality_type factor = centrality_type(2)/centrality_type(n*n - 3*n + 2);
+ vertex_iterator v, v_end;
+ for (tie(v, v_end) = vertices(g); v != v_end; ++v) {
+ put(centrality, *v, factor * get(centrality, *v));
+ }
+}
+
+// Compute the central point dominance of a graph.
+template<typename Graph, typename CentralityMap>
+typename property_traits<CentralityMap>::value_type
+central_point_dominance(const Graph& g, CentralityMap centrality)
+{
+ using std::max;
+
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
+ typedef typename property_traits<CentralityMap>::value_type centrality_type;
+
+ typename graph_traits<Graph>::vertices_size_type n = num_vertices(g);
+
+ // Find max centrality
+ centrality_type max_centrality(0);
+ vertex_iterator v, v_end;
+ for (tie(v, v_end) = vertices(g); v != v_end; ++v) {
+ max_centrality = (max)(max_centrality, get(centrality, *v));
+ }
+
+ // Compute central point dominance
+ centrality_type sum(0);
+ for (tie(v, v_end) = vertices(g); v != v_end; ++v) {
+ sum += (max_centrality - get(centrality, *v));
+ }
+ return sum/(n-1);
+}
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_BRANDES_BETWEENNESS_CENTRALITY_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/biconnected_components.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/biconnected_components.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,415 @@
+// Copyright (c) Jeremy Siek 2001
+// Copyright (c) Douglas Gregor 2004
+//
+// 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)
+
+// NOTE: this final is generated by libs/graph/doc/biconnected_components.w
+
+#ifndef BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP
+#define BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP
+
+#include <stack>
+#include <vector>
+#include <algorithm> // for std::min and std::max
+#include <boost/config.hpp>
+#include <boost/limits.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/graph/graph_utility.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ template<typename ComponentMap, typename DiscoverTimeMap,
+ typename LowPointMap, typename PredecessorMap,
+ typename OutputIterator, typename Stack,
+ typename DFSVisitor>
+ struct biconnected_components_visitor : public dfs_visitor<>
+ {
+ biconnected_components_visitor
+ (ComponentMap comp, std::size_t& c, DiscoverTimeMap dtm,
+ std::size_t& dfs_time, LowPointMap lowpt, PredecessorMap pred,
+ OutputIterator out, Stack& S, DFSVisitor vis)
+ : comp(comp), c(c), dtm(dtm), dfs_time(dfs_time), lowpt(lowpt),
+ pred(pred), out(out), S(S), vis(vis) { }
+
+ template <typename Vertex, typename Graph>
+ void initialize_vertex(const Vertex& u, Graph& g)
+ {
+ vis.initialize_vertex(u, g);
+ }
+
+ template <typename Vertex, typename Graph>
+ void start_vertex(const Vertex& u, Graph& g)
+ {
+ put(pred, u, u);
+ vis.start_vertex(u, g);
+ }
+
+ template <typename Vertex, typename Graph>
+ void discover_vertex(const Vertex& u, Graph& g)
+ {
+ put(dtm, u, ++dfs_time);
+ put(lowpt, u, get(dtm, u));
+ vis.discover_vertex(u, g);
+ }
+
+ template <typename Edge, typename Graph>
+ void examine_edge(const Edge& e, Graph& g)
+ {
+ vis.examine_edge(e, g);
+ }
+
+ template <typename Edge, typename Graph>
+ void tree_edge(const Edge& e, Graph& g)
+ {
+ S.push(e);
+ put(pred, target(e, g), source(e, g));
+ vis.tree_edge(e, g);
+ }
+
+ template <typename Edge, typename Graph>
+ void back_edge(const Edge& e, Graph& g)
+ {
+ BOOST_USING_STD_MIN();
+
+ if ( target(e, g) != get(pred, source(e, g)) ) {
+ S.push(e);
+ put(lowpt, source(e, g),
+ min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, source(e, g)),
+ get(dtm, target(e, g))));
+ vis.back_edge(e, g);
+ }
+ }
+
+ template <typename Edge, typename Graph>
+ void forward_or_cross_edge(const Edge& e, Graph& g)
+ {
+ vis.forward_or_cross_edge(e, g);
+ }
+
+ template <typename Vertex, typename Graph>
+ void finish_vertex(const Vertex& u, Graph& g)
+ {
+ BOOST_USING_STD_MIN();
+ Vertex parent = get(pred, u);
+ const std::size_t dtm_of_dubious_parent = get(dtm, parent);
+ bool is_art_point = false;
+ if ( dtm_of_dubious_parent > get(dtm, u) ) {
+ parent = get(pred, parent);
+ is_art_point = true;
+ put(pred, get(pred, u), u);
+ put(pred, u, parent);
+ }
+
+ if ( parent == u ) { // at top
+ if ( get(dtm, u) + 1 == dtm_of_dubious_parent )
+ is_art_point = false;
+ } else {
+ put(lowpt, parent,
+ min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, parent),
+ get(lowpt, u)));
+
+ if (get(lowpt, u) >= get(dtm, parent)) {
+ if ( get(dtm, parent) > get(dtm, get(pred, parent)) ) {
+ put(pred, u, get(pred, parent));
+ put(pred, parent, u);
+ }
+
+ while ( get(dtm, source(S.top(), g)) >= get(dtm, u) ) {
+ put(comp, S.top(), c);
+ S.pop();
+ }
+ put(comp, S.top(), c);
+ S.pop();
+ ++c;
+ if ( S.empty() ) {
+ put(pred, u, parent);
+ put(pred, parent, u);
+ }
+ }
+ }
+ if ( is_art_point )
+ *out++ = u;
+ vis.finish_vertex(u, g);
+ }
+
+ ComponentMap comp;
+ std::size_t& c;
+ DiscoverTimeMap dtm;
+ std::size_t& dfs_time;
+ LowPointMap lowpt;
+ PredecessorMap pred;
+ OutputIterator out;
+ Stack& S;
+ DFSVisitor vis;
+ };
+
+ template<typename Graph, typename ComponentMap, typename OutputIterator,
+ typename VertexIndexMap, typename DiscoverTimeMap, typename LowPointMap,
+ typename PredecessorMap, typename DFSVisitor>
+ std::pair<std::size_t, OutputIterator>
+ biconnected_components_impl(const Graph & g, ComponentMap comp,
+ OutputIterator out, VertexIndexMap index_map, DiscoverTimeMap dtm,
+ LowPointMap lowpt, PredecessorMap pred, DFSVisitor dfs_vis)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ function_requires<VertexListGraphConcept<Graph> >();
+ function_requires<IncidenceGraphConcept<Graph> >();
+ function_requires<WritablePropertyMapConcept<ComponentMap, edge_t> >();
+ function_requires<ReadWritePropertyMapConcept<DiscoverTimeMap,
+ vertex_t> >();
+ function_requires<ReadWritePropertyMapConcept<LowPointMap, vertex_t > >();
+ function_requires<ReadWritePropertyMapConcept<PredecessorMap,
+ vertex_t> >();
+
+ std::size_t num_components = 0;
+ std::size_t dfs_time = 0;
+ std::stack<edge_t> S;
+
+ biconnected_components_visitor<ComponentMap, DiscoverTimeMap,
+ LowPointMap, PredecessorMap, OutputIterator, std::stack<edge_t>,
+ DFSVisitor>
+ vis(comp, num_components, dtm, dfs_time, lowpt, pred, out,
+ S, dfs_vis);
+
+ depth_first_search(g, visitor(vis).vertex_index_map(index_map));
+
+ return std::pair<std::size_t, OutputIterator>(num_components, vis.out);
+ }
+
+ template <typename PredecessorMap>
+ struct bicomp_dispatch3
+ {
+ template<typename Graph, typename ComponentMap, typename OutputIterator,
+ typename VertexIndexMap, typename DiscoverTimeMap,
+ typename LowPointMap, class P, class T, class R>
+ static std::pair<std::size_t, OutputIterator> apply (const Graph & g,
+ ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
+ DiscoverTimeMap dtm, LowPointMap lowpt,
+ const bgl_named_params<P, T, R>& params, PredecessorMap pred)
+ {
+ return biconnected_components_impl
+ (g, comp, out, index_map, dtm, lowpt, pred,
+ choose_param(get_param(params, graph_visitor),
+ make_dfs_visitor(null_visitor())));
+ }
+ };
+
+ template <>
+ struct bicomp_dispatch3<error_property_not_found>
+ {
+ template<typename Graph, typename ComponentMap, typename OutputIterator,
+ typename VertexIndexMap, typename DiscoverTimeMap,
+ typename LowPointMap, class P, class T, class R>
+ static std::pair<std::size_t, OutputIterator> apply (const Graph & g,
+ ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
+ DiscoverTimeMap dtm, LowPointMap lowpt,
+ const bgl_named_params<P, T, R>& params,
+ error_property_not_found)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ std::vector<vertex_t> pred(num_vertices(g));
+ vertex_t vert = graph_traits<Graph>::null_vertex();
+
+ return biconnected_components_impl
+ (g, comp, out, index_map, dtm, lowpt,
+ make_iterator_property_map(pred.begin(), index_map, vert),
+ choose_param(get_param(params, graph_visitor),
+ make_dfs_visitor(null_visitor())));
+ }
+ };
+
+ template <typename LowPointMap>
+ struct bicomp_dispatch2
+ {
+ template<typename Graph, typename ComponentMap, typename OutputIterator,
+ typename VertexIndexMap, typename DiscoverTimeMap,
+ typename P, typename T, typename R>
+ static std::pair<std::size_t, OutputIterator> apply (const Graph& g,
+ ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
+ DiscoverTimeMap dtm, const bgl_named_params<P, T, R>& params,
+ LowPointMap lowpt)
+ {
+ typedef typename property_value< bgl_named_params<P,T,R>,
+ vertex_predecessor_t>::type dispatch_type;
+
+ return bicomp_dispatch3<dispatch_type>::apply
+ (g, comp, out, index_map, dtm, lowpt, params,
+ get_param(params, vertex_predecessor));
+ }
+ };
+
+
+ template <>
+ struct bicomp_dispatch2<error_property_not_found>
+ {
+ template<typename Graph, typename ComponentMap, typename OutputIterator,
+ typename VertexIndexMap, typename DiscoverTimeMap,
+ typename P, typename T, typename R>
+ static std::pair<std::size_t, OutputIterator> apply (const Graph& g,
+ ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
+ DiscoverTimeMap dtm, const bgl_named_params<P, T, R>& params,
+ error_property_not_found)
+ {
+ typedef typename graph_traits<Graph>::vertices_size_type
+ vertices_size_type;
+ std::vector<vertices_size_type> lowpt(num_vertices(g));
+ vertices_size_type vst(0);
+
+ typedef typename property_value< bgl_named_params<P,T,R>,
+ vertex_predecessor_t>::type dispatch_type;
+
+ return bicomp_dispatch3<dispatch_type>::apply
+ (g, comp, out, index_map, dtm,
+ make_iterator_property_map(lowpt.begin(), index_map, vst),
+ params, get_param(params, vertex_predecessor));
+ }
+ };
+
+ template <typename DiscoverTimeMap>
+ struct bicomp_dispatch1
+ {
+ template<typename Graph, typename ComponentMap, typename OutputIterator,
+ typename VertexIndexMap, class P, class T, class R>
+ static std::pair<std::size_t, OutputIterator> apply(const Graph& g,
+ ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
+ const bgl_named_params<P, T, R>& params, DiscoverTimeMap dtm)
+ {
+ typedef typename property_value< bgl_named_params<P,T,R>,
+ vertex_lowpoint_t>::type dispatch_type;
+
+ return bicomp_dispatch2<dispatch_type>::apply
+ (g, comp, out, index_map, dtm, params,
+ get_param(params, vertex_lowpoint));
+ }
+ };
+
+ template <>
+ struct bicomp_dispatch1<error_property_not_found>
+ {
+ template<typename Graph, typename ComponentMap, typename OutputIterator,
+ typename VertexIndexMap, class P, class T, class R>
+ static std::pair<std::size_t, OutputIterator> apply(const Graph& g,
+ ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
+ const bgl_named_params<P, T, R>& params, error_property_not_found)
+ {
+ typedef typename graph_traits<Graph>::vertices_size_type
+ vertices_size_type;
+ std::vector<vertices_size_type> discover_time(num_vertices(g));
+ vertices_size_type vst(0);
+
+ typedef typename property_value< bgl_named_params<P,T,R>,
+ vertex_lowpoint_t>::type dispatch_type;
+
+ return bicomp_dispatch2<dispatch_type>::apply
+ (g, comp, out, index_map,
+ make_iterator_property_map(discover_time.begin(), index_map, vst),
+ params, get_param(params, vertex_lowpoint));
+ }
+ };
+
+ }
+
+ template<typename Graph, typename ComponentMap, typename OutputIterator,
+ typename DiscoverTimeMap, typename LowPointMap>
+ std::pair<std::size_t, OutputIterator>
+ biconnected_components(const Graph& g, ComponentMap comp,
+ OutputIterator out, DiscoverTimeMap dtm, LowPointMap lowpt)
+ {
+ typedef detail::error_property_not_found dispatch_type;
+
+ return detail::bicomp_dispatch3<dispatch_type>::apply
+ (g, comp, out,
+ get(vertex_index, g),
+ dtm, lowpt,
+ bgl_named_params<int, buffer_param_t>(0),
+ detail::error_property_not_found());
+ }
+
+ template <typename Graph, typename ComponentMap, typename OutputIterator,
+ typename P, typename T, typename R>
+ std::pair<std::size_t, OutputIterator>
+ biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef typename property_value< bgl_named_params<P,T,R>,
+ vertex_discover_time_t>::type dispatch_type;
+
+ return detail::bicomp_dispatch1<dispatch_type>::apply(g, comp, out,
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
+ params, get_param(params, vertex_discover_time));
+ }
+
+ template < typename Graph, typename ComponentMap, typename OutputIterator>
+ std::pair<std::size_t, OutputIterator>
+ biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out)
+ {
+ return biconnected_components(g, comp, out,
+ bgl_named_params<int, buffer_param_t>(0));
+ }
+
+ namespace graph_detail {
+ struct dummy_output_iterator
+ {
+ typedef std::output_iterator_tag iterator_category;
+ typedef void value_type;
+ typedef void pointer;
+ typedef void difference_type;
+
+ struct reference {
+ template<typename T>
+ reference& operator=(const T&) { return *this; }
+ };
+
+ reference operator*() const { return reference(); }
+ dummy_output_iterator& operator++() { return *this; }
+ dummy_output_iterator operator++(int) { return *this; }
+ };
+ } // end namespace graph_detail
+
+ template <typename Graph, typename ComponentMap,
+ typename P, typename T, typename R>
+ std::size_t
+ biconnected_components(const Graph& g, ComponentMap comp,
+ const bgl_named_params<P, T, R>& params)
+ {
+ return biconnected_components(g, comp,
+ graph_detail::dummy_output_iterator(), params).first;
+ }
+
+ template <typename Graph, typename ComponentMap>
+ std::size_t
+ biconnected_components(const Graph& g, ComponentMap comp)
+ {
+ return biconnected_components(g, comp,
+ graph_detail::dummy_output_iterator()).first;
+ }
+
+ template<typename Graph, typename OutputIterator,
+ typename P, typename T, typename R>
+ OutputIterator
+ articulation_points(const Graph& g, OutputIterator out,
+ const bgl_named_params<P, T, R>& params)
+ {
+ return biconnected_components(g, dummy_property_map(), out,
+ params).second;
+ }
+
+ template<typename Graph, typename OutputIterator>
+ OutputIterator
+ articulation_points(const Graph& g, OutputIterator out)
+ {
+ return biconnected_components(g, dummy_property_map(), out,
+ bgl_named_params<int, buffer_param_t>(0)).second;
+ }
+
+} // namespace boost
+
+#endif /* BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP */
Added: branches/CMake/release/libs/graph/include/boost/graph/boyer_myrvold_planar_test.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/boyer_myrvold_planar_test.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,322 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// 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)
+//=======================================================================
+
+#ifndef __BOYER_MYRVOLD_PLANAR_TEST_HPP__
+#define __BOYER_MYRVOLD_PLANAR_TEST_HPP__
+
+#include <boost/graph/planar_detail/boyer_myrvold_impl.hpp>
+#include <boost/parameter.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/mpl/bool.hpp>
+
+
+namespace boost
+{
+
+ struct no_kuratowski_subgraph_isolation {};
+ struct no_planar_embedding {};
+
+ namespace boyer_myrvold_params
+ {
+
+ BOOST_PARAMETER_KEYWORD(tag, graph)
+ BOOST_PARAMETER_KEYWORD(tag, embedding)
+ BOOST_PARAMETER_KEYWORD(tag, kuratowski_subgraph)
+ BOOST_PARAMETER_KEYWORD(tag, vertex_index_map)
+ BOOST_PARAMETER_KEYWORD(tag, edge_index_map)
+
+ typedef parameter::parameters< parameter::required<tag::graph>,
+ tag::embedding,
+ tag::kuratowski_subgraph,
+ tag::vertex_index_map,
+ tag::edge_index_map
+ > boyer_myrvold_params_t;
+
+ namespace core
+ {
+
+ template <typename ArgumentPack>
+ bool dispatched_boyer_myrvold(ArgumentPack const& args,
+ mpl::true_,
+ mpl::true_
+ )
+ {
+ //Dispatch for no planar embedding, no kuratowski subgraph isolation
+
+ typedef typename remove_const
+ <
+ typename remove_reference
+ < typename parameter::binding
+ < ArgumentPack, tag::graph>::type
+ >::type
+ >::type graph_t;
+
+ typedef typename parameter::binding
+ < ArgumentPack,
+ tag::vertex_index_map,
+ typename property_map
+ < typename remove_reference<graph_t>::type,
+ vertex_index_t>::const_type
+ >::type vertex_index_map_t;
+
+ boyer_myrvold_impl
+ <graph_t,
+ vertex_index_map_t,
+ graph::detail::no_old_handles,
+ graph::detail::no_embedding
+ >
+ planarity_tester(args[graph],
+ args[vertex_index_map |
+ get(vertex_index, args[graph])
+ ]
+ );
+
+ return planarity_tester.is_planar() ? true : false;
+ }
+
+
+
+ template <typename ArgumentPack>
+ bool dispatched_boyer_myrvold(ArgumentPack const& args,
+ mpl::true_,
+ mpl::false_
+ )
+ {
+ //Dispatch for no planar embedding, kuratowski subgraph isolation
+ typedef typename remove_const
+ <
+ typename remove_reference
+ < typename parameter::binding
+ < ArgumentPack, tag::graph>::type
+ >::type
+ >::type graph_t;
+
+ typedef typename parameter::binding
+ < ArgumentPack,
+ tag::vertex_index_map,
+ typename property_map<graph_t, vertex_index_t>::type
+ >::type vertex_index_map_t;
+
+ boyer_myrvold_impl
+ <graph_t,
+ vertex_index_map_t,
+ graph::detail::store_old_handles,
+ graph::detail::no_embedding
+ >
+ planarity_tester(args[graph],
+ args[vertex_index_map |
+ get(vertex_index, args[graph])
+ ]
+ );
+
+ if (planarity_tester.is_planar())
+ return true;
+ else
+ {
+ planarity_tester.extract_kuratowski_subgraph
+ (args[kuratowski_subgraph],
+ args[edge_index_map|get(edge_index, args[graph])]
+ );
+ return false;
+ }
+ }
+
+
+
+
+ template <typename ArgumentPack>
+ bool dispatched_boyer_myrvold(ArgumentPack const& args,
+ mpl::false_,
+ mpl::true_
+ )
+ {
+ //Dispatch for planar embedding, no kuratowski subgraph isolation
+ typedef typename remove_const
+ <
+ typename remove_reference
+ < typename parameter::binding
+ < ArgumentPack, tag::graph>::type
+ >::type
+ >::type graph_t;
+
+ typedef typename parameter::binding
+ < ArgumentPack,
+ tag::vertex_index_map,
+ typename property_map<graph_t, vertex_index_t>::type
+ >::type vertex_index_map_t;
+
+ boyer_myrvold_impl
+ <graph_t,
+ vertex_index_map_t,
+ graph::detail::no_old_handles,
+#ifdef BOOST_GRAPH_PREFER_STD_LIB
+ graph::detail::std_list
+#else
+ graph::detail::recursive_lazy_list
+#endif
+ >
+ planarity_tester(args[graph],
+ args[vertex_index_map |
+ get(vertex_index, args[graph])
+ ]
+ );
+
+ if (planarity_tester.is_planar())
+ {
+ planarity_tester.make_edge_permutation(args[embedding]);
+ return true;
+ }
+ else
+ return false;
+ }
+
+
+
+ template <typename ArgumentPack>
+ bool dispatched_boyer_myrvold(ArgumentPack const& args,
+ mpl::false_,
+ mpl::false_
+ )
+ {
+ //Dispatch for planar embedding, kuratowski subgraph isolation
+ typedef typename remove_const
+ <
+ typename remove_reference
+ < typename parameter::binding
+ < ArgumentPack, tag::graph>::type
+ >::type
+ >::type graph_t;
+
+ typedef typename parameter::binding
+ < ArgumentPack,
+ tag::vertex_index_map,
+ typename property_map<graph_t, vertex_index_t>::type
+ >::type vertex_index_map_t;
+
+ boyer_myrvold_impl
+ <graph_t,
+ vertex_index_map_t,
+ graph::detail::store_old_handles,
+#ifdef BOOST_BGL_PREFER_STD_LIB
+ graph::detail::std_list
+#else
+ graph::detail::recursive_lazy_list
+#endif
+ >
+ planarity_tester(args[graph],
+ args[vertex_index_map |
+ get(vertex_index, args[graph])
+ ]
+ );
+
+ if (planarity_tester.is_planar())
+ {
+ planarity_tester.make_edge_permutation(args[embedding]);
+ return true;
+ }
+ else
+ {
+ planarity_tester.extract_kuratowski_subgraph
+ (args[kuratowski_subgraph],
+ args[edge_index_map | get(edge_index, args[graph])]
+ );
+ return false;
+ }
+ }
+
+
+
+
+ template <typename ArgumentPack>
+ bool boyer_myrvold_planarity_test(ArgumentPack const& args)
+ {
+
+ typedef typename parameter::binding
+ < ArgumentPack,
+ tag::kuratowski_subgraph,
+ const no_kuratowski_subgraph_isolation&
+ >::type
+ kuratowski_arg_t;
+
+ typedef typename parameter::binding
+ < ArgumentPack,
+ tag::embedding,
+ const no_planar_embedding&
+ >::type
+ embedding_arg_t;
+
+ return dispatched_boyer_myrvold
+ (args,
+ boost::is_same
+ <embedding_arg_t, const no_planar_embedding&>(),
+ boost::is_same
+ <kuratowski_arg_t, const no_kuratowski_subgraph_isolation&>()
+ );
+ }
+
+
+
+ } //namespace core
+
+ } //namespace boyer_myrvold_params
+
+
+ template <typename A0>
+ bool boyer_myrvold_planarity_test(A0 const& arg0)
+ {
+ return boyer_myrvold_params::core::boyer_myrvold_planarity_test
+ (boyer_myrvold_params::boyer_myrvold_params_t()(arg0));
+ }
+
+ template <typename A0, typename A1>
+ // bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1)
+ bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1)
+ {
+ return boyer_myrvold_params::core::boyer_myrvold_planarity_test
+ (boyer_myrvold_params::boyer_myrvold_params_t()(arg0,arg1));
+ }
+
+ template <typename A0, typename A1, typename A2>
+ bool boyer_myrvold_planarity_test(A0 const& arg0,
+ A1 const& arg1,
+ A2 const& arg2
+ )
+ {
+ return boyer_myrvold_params::core::boyer_myrvold_planarity_test
+ (boyer_myrvold_params::boyer_myrvold_params_t()(arg0,arg1,arg2));
+ }
+
+ template <typename A0, typename A1, typename A2, typename A3>
+ bool boyer_myrvold_planarity_test(A0 const& arg0,
+ A1 const& arg1,
+ A2 const& arg2,
+ A3 const& arg3
+ )
+ {
+ return boyer_myrvold_params::core::boyer_myrvold_planarity_test
+ (boyer_myrvold_params::boyer_myrvold_params_t()(arg0,arg1,arg2,arg3));
+ }
+
+ template <typename A0, typename A1, typename A2, typename A3, typename A4>
+ bool boyer_myrvold_planarity_test(A0 const& arg0,
+ A1 const& arg1,
+ A2 const& arg2,
+ A3 const& arg3,
+ A4 const& arg4
+ )
+ {
+ return boyer_myrvold_params::core::boyer_myrvold_planarity_test
+ (boyer_myrvold_params::boyer_myrvold_params_t()
+ (arg0,arg1,arg2,arg3,arg4)
+ );
+ }
+
+
+}
+
+#endif //__BOYER_MYRVOLD_PLANAR_TEST_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/breadth_first_search.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/breadth_first_search.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,293 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP
+#define BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP
+
+/*
+ Breadth First Search Algorithm (Cormen, Leiserson, and Rivest p. 470)
+*/
+#include <boost/config.hpp>
+#include <vector>
+#include <boost/pending/queue.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/named_function_params.hpp>
+
+namespace boost {
+
+ template <class Visitor, class Graph>
+ struct BFSVisitorConcept {
+ void constraints() {
+ function_requires< CopyConstructibleConcept<Visitor> >();
+ vis.initialize_vertex(u, g);
+ vis.discover_vertex(u, g);
+ vis.examine_vertex(u, g);
+ vis.examine_edge(e, g);
+ vis.tree_edge(e, g);
+ vis.non_tree_edge(e, g);
+ vis.gray_target(e, g);
+ vis.black_target(e, g);
+ vis.finish_vertex(u, g);
+ }
+ Visitor vis;
+ Graph g;
+ typename graph_traits<Graph>::vertex_descriptor u;
+ typename graph_traits<Graph>::edge_descriptor e;
+ };
+
+
+ template <class IncidenceGraph, class Buffer, class BFSVisitor,
+ class ColorMap>
+ void breadth_first_visit
+ (const IncidenceGraph& g,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor s,
+ Buffer& Q, BFSVisitor vis, ColorMap color)
+ {
+ function_requires< IncidenceGraphConcept<IncidenceGraph> >();
+ typedef graph_traits<IncidenceGraph> GTraits;
+ typedef typename GTraits::vertex_descriptor Vertex;
+ typedef typename GTraits::edge_descriptor Edge;
+ function_requires< BFSVisitorConcept<BFSVisitor, IncidenceGraph> >();
+ function_requires< ReadWritePropertyMapConcept<ColorMap, Vertex> >();
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+ typename GTraits::out_edge_iterator ei, ei_end;
+
+ put(color, s, Color::gray()); vis.discover_vertex(s, g);
+ Q.push(s);
+ while (! Q.empty()) {
+ Vertex u = Q.top(); Q.pop(); vis.examine_vertex(u, g);
+ for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
+ Vertex v = target(*ei, g); vis.examine_edge(*ei, g);
+ ColorValue v_color = get(color, v);
+ if (v_color == Color::white()) { vis.tree_edge(*ei, g);
+ put(color, v, Color::gray()); vis.discover_vertex(v, g);
+ Q.push(v);
+ } else { vis.non_tree_edge(*ei, g);
+ if (v_color == Color::gray()) vis.gray_target(*ei, g);
+ else vis.black_target(*ei, g);
+ }
+ } // end for
+ put(color, u, Color::black()); vis.finish_vertex(u, g);
+ } // end while
+ } // breadth_first_visit
+
+
+ template <class VertexListGraph, class Buffer, class BFSVisitor,
+ class ColorMap>
+ void breadth_first_search
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ Buffer& Q, BFSVisitor vis, ColorMap color)
+ {
+ // Initialization
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+ typename boost::graph_traits<VertexListGraph>::vertex_iterator i, i_end;
+ for (tie(i, i_end) = vertices(g); i != i_end; ++i) {
+ vis.initialize_vertex(*i, g);
+ put(color, *i, Color::white());
+ }
+ breadth_first_visit(g, s, Q, vis, color);
+ }
+
+
+ template <class Visitors = null_visitor>
+ class bfs_visitor {
+ public:
+ bfs_visitor() { }
+ bfs_visitor(Visitors vis) : m_vis(vis) { }
+
+ template <class Vertex, class Graph>
+ void initialize_vertex(Vertex u, Graph& g) {
+ invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex());
+ }
+ template <class Vertex, class Graph>
+ void discover_vertex(Vertex u, Graph& g) {
+ invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex());
+ }
+ template <class Vertex, class Graph>
+ void examine_vertex(Vertex u, Graph& g) {
+ invoke_visitors(m_vis, u, g, ::boost::on_examine_vertex());
+ }
+ template <class Edge, class Graph>
+ void examine_edge(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, ::boost::on_examine_edge());
+ }
+ template <class Edge, class Graph>
+ void tree_edge(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, ::boost::on_tree_edge());
+ }
+ template <class Edge, class Graph>
+ void non_tree_edge(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, ::boost::on_non_tree_edge());
+ }
+ template <class Edge, class Graph>
+ void gray_target(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, ::boost::on_gray_target());
+ }
+ template <class Edge, class Graph>
+ void black_target(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, ::boost::on_black_target());
+ }
+ template <class Vertex, class Graph>
+ void finish_vertex(Vertex u, Graph& g) {
+ invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex());
+ }
+
+ BOOST_GRAPH_EVENT_STUB(on_initialize_vertex,bfs)
+ BOOST_GRAPH_EVENT_STUB(on_discover_vertex,bfs)
+ BOOST_GRAPH_EVENT_STUB(on_examine_vertex,bfs)
+ BOOST_GRAPH_EVENT_STUB(on_examine_edge,bfs)
+ BOOST_GRAPH_EVENT_STUB(on_tree_edge,bfs)
+ BOOST_GRAPH_EVENT_STUB(on_non_tree_edge,bfs)
+ BOOST_GRAPH_EVENT_STUB(on_gray_target,bfs)
+ BOOST_GRAPH_EVENT_STUB(on_black_target,bfs)
+ BOOST_GRAPH_EVENT_STUB(on_finish_vertex,bfs)
+
+ protected:
+ Visitors m_vis;
+ };
+ template <class Visitors>
+ bfs_visitor<Visitors>
+ make_bfs_visitor(Visitors vis) {
+ return bfs_visitor<Visitors>(vis);
+ }
+ typedef bfs_visitor<> default_bfs_visitor;
+
+
+ namespace detail {
+
+ template <class VertexListGraph, class ColorMap, class BFSVisitor,
+ class P, class T, class R>
+ void bfs_helper
+ (VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ ColorMap color,
+ BFSVisitor vis,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef graph_traits<VertexListGraph> Traits;
+ // Buffer default
+ typedef typename Traits::vertex_descriptor Vertex;
+ typedef boost::queue<Vertex> queue_t;
+ queue_t Q;
+ detail::wrap_ref<queue_t> Qref(Q);
+ breadth_first_search
+ (g, s,
+ choose_param(get_param(params, buffer_param_t()), Qref).ref,
+ vis, color);
+ }
+
+ //-------------------------------------------------------------------------
+ // Choose between default color and color parameters. Using
+ // function dispatching so that we don't require vertex index if
+ // the color default is not being used.
+
+ template <class ColorMap>
+ struct bfs_dispatch {
+ template <class VertexListGraph, class P, class T, class R>
+ static void apply
+ (VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ const bgl_named_params<P, T, R>& params,
+ ColorMap color)
+ {
+ bfs_helper
+ (g, s, color,
+ choose_param(get_param(params, graph_visitor),
+ make_bfs_visitor(null_visitor())),
+ params);
+ }
+ };
+
+ template <>
+ struct bfs_dispatch<detail::error_property_not_found> {
+ template <class VertexListGraph, class P, class T, class R>
+ static void apply
+ (VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ const bgl_named_params<P, T, R>& params,
+ detail::error_property_not_found)
+ {
+ std::vector<default_color_type> color_vec(num_vertices(g));
+ default_color_type c = white_color;
+ null_visitor null_vis;
+
+ bfs_helper
+ (g, s,
+ make_iterator_property_map
+ (color_vec.begin(),
+ choose_const_pmap(get_param(params, vertex_index),
+ g, vertex_index), c),
+ choose_param(get_param(params, graph_visitor),
+ make_bfs_visitor(null_vis)),
+ params);
+ }
+ };
+
+ } // namespace detail
+
+
+ // Named Parameter Variant
+ template <class VertexListGraph, class P, class T, class R>
+ void breadth_first_search
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ const bgl_named_params<P, T, R>& params)
+ {
+ // The graph is passed by *const* reference so that graph adaptors
+ // (temporaries) can be passed into this function. However, the
+ // graph is not really const since we may write to property maps
+ // of the graph.
+ VertexListGraph& ng = const_cast<VertexListGraph&>(g);
+ typedef typename property_value< bgl_named_params<P,T,R>,
+ vertex_color_t>::type C;
+ detail::bfs_dispatch<C>::apply(ng, s, params,
+ get_param(params, vertex_color));
+ }
+
+
+ // This version does not initialize colors, user has to.
+
+ template <class IncidenceGraph, class P, class T, class R>
+ void breadth_first_visit
+ (const IncidenceGraph& g,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor s,
+ const bgl_named_params<P, T, R>& params)
+ {
+ // The graph is passed by *const* reference so that graph adaptors
+ // (temporaries) can be passed into this function. However, the
+ // graph is not really const since we may write to property maps
+ // of the graph.
+ IncidenceGraph& ng = const_cast<IncidenceGraph&>(g);
+
+ typedef graph_traits<IncidenceGraph> Traits;
+ // Buffer default
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+ typedef boost::queue<vertex_descriptor> queue_t;
+ queue_t Q;
+ detail::wrap_ref<queue_t> Qref(Q);
+
+ breadth_first_visit
+ (ng, s,
+ choose_param(get_param(params, buffer_param_t()), Qref).ref,
+ choose_param(get_param(params, graph_visitor),
+ make_bfs_visitor(null_visitor())),
+ choose_pmap(get_param(params, vertex_color), ng, vertex_color)
+ );
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP
+
Added: branches/CMake/release/libs/graph/include/boost/graph/chrobak_payne_drawing.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/chrobak_payne_drawing.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,270 @@
+//=======================================================================
+// Copyright (c) Aaron Windsor 2007
+//
+// 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)
+//=======================================================================
+
+#ifndef __CHROBAK_PAYNE_DRAWING_HPP__
+#define __CHROBAK_PAYNE_DRAWING_HPP__
+
+#include <vector>
+#include <list>
+#include <boost/config.hpp>
+#include <boost/utility.hpp> //for next and prior
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map.hpp>
+
+
+namespace boost
+{
+
+ namespace graph { namespace detail
+ {
+
+ template<typename Graph,
+ typename VertexToVertexMap,
+ typename VertexTo1DCoordMap>
+ void accumulate_offsets(typename graph_traits<Graph>::vertex_descriptor v,
+ std::size_t offset,
+ const Graph& g,
+ VertexTo1DCoordMap x,
+ VertexTo1DCoordMap delta_x,
+ VertexToVertexMap left,
+ VertexToVertexMap right)
+ {
+ if (v != graph_traits<Graph>::null_vertex())
+ {
+ x[v] += delta_x[v] + offset;
+ accumulate_offsets(left[v], x[v], g, x, delta_x, left, right);
+ accumulate_offsets(right[v], x[v], g, x, delta_x, left, right);
+ }
+ }
+
+ } /*namespace detail*/ } /*namespace graph*/
+
+
+
+
+
+ template<typename Graph,
+ typename PlanarEmbedding,
+ typename ForwardIterator,
+ typename GridPositionMap,
+ typename VertexIndexMap>
+ void chrobak_payne_straight_line_drawing(const Graph& g,
+ PlanarEmbedding embedding,
+ ForwardIterator ordering_begin,
+ ForwardIterator ordering_end,
+ GridPositionMap drawing,
+ VertexIndexMap vm
+ )
+ {
+
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
+ typedef typename PlanarEmbedding::value_type::const_iterator
+ edge_permutation_iterator_t;
+ typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
+ typedef std::vector<vertex_t> vertex_vector_t;
+ typedef std::vector<v_size_t> vsize_vector_t;
+ typedef std::vector<bool> bool_vector_t;
+ typedef boost::iterator_property_map
+ <typename vertex_vector_t::iterator, VertexIndexMap>
+ vertex_to_vertex_map_t;
+ typedef boost::iterator_property_map
+ <typename vsize_vector_t::iterator, VertexIndexMap>
+ vertex_to_vsize_map_t;
+ typedef boost::iterator_property_map
+ <typename bool_vector_t::iterator, VertexIndexMap>
+ vertex_to_bool_map_t;
+
+ vertex_vector_t left_vector(num_vertices(g),
+ graph_traits<Graph>::null_vertex()
+ );
+ vertex_vector_t right_vector(num_vertices(g),
+ graph_traits<Graph>::null_vertex()
+ );
+ vsize_vector_t seen_as_right_vector(num_vertices(g), 0);
+ vsize_vector_t seen_vector(num_vertices(g), 0);
+ vsize_vector_t delta_x_vector(num_vertices(g),0);
+ vsize_vector_t y_vector(num_vertices(g));
+ vsize_vector_t x_vector(num_vertices(g),0);
+ bool_vector_t installed_vector(num_vertices(g),false);
+
+ vertex_to_vertex_map_t left(left_vector.begin(), vm);
+ vertex_to_vertex_map_t right(right_vector.begin(), vm);
+ vertex_to_vsize_map_t seen_as_right(seen_as_right_vector.begin(), vm);
+ vertex_to_vsize_map_t seen(seen_vector.begin(), vm);
+ vertex_to_vsize_map_t delta_x(delta_x_vector.begin(), vm);
+ vertex_to_vsize_map_t y(y_vector.begin(), vm);
+ vertex_to_vsize_map_t x(x_vector.begin(), vm);
+ vertex_to_bool_map_t installed(installed_vector.begin(), vm);
+
+ v_size_t timestamp = 1;
+ vertex_vector_t installed_neighbors;
+
+ ForwardIterator itr = ordering_begin;
+ vertex_t v1 = *itr; ++itr;
+ vertex_t v2 = *itr; ++itr;
+ vertex_t v3 = *itr; ++itr;
+
+ delta_x[v2] = 1;
+ delta_x[v3] = 1;
+
+ y[v1] = 0;
+ y[v2] = 0;
+ y[v3] = 1;
+
+ right[v1] = v3;
+ right[v3] = v2;
+
+ installed[v1] = installed[v2] = installed[v3] = true;
+
+ for(ForwardIterator itr_end = ordering_end; itr != itr_end; ++itr)
+ {
+ vertex_t v = *itr;
+
+ // First, find the leftmost and rightmost neighbor of v on the outer
+ // cycle of the embedding.
+ // Note: since we're moving clockwise through the edges adjacent to v,
+ // we're actually moving from right to left among v's neighbors on the
+ // outer face (since v will be installed above them all) looking for
+ // the leftmost and rightmost installed neigbhors
+
+ vertex_t leftmost = graph_traits<Graph>::null_vertex();
+ vertex_t rightmost = graph_traits<Graph>::null_vertex();
+
+ installed_neighbors.clear();
+
+ vertex_t prev_vertex = graph_traits<Graph>::null_vertex();
+ edge_permutation_iterator_t pi, pi_end;
+ pi_end = embedding[v].end();
+ for(pi = embedding[v].begin(); pi != pi_end; ++pi)
+ {
+ vertex_t curr_vertex = source(*pi,g) == v ?
+ target(*pi,g) : source(*pi,g);
+
+ // Skip any self-loops or parallel edges
+ if (curr_vertex == v || curr_vertex == prev_vertex)
+ continue;
+
+ if (installed[curr_vertex])
+ {
+ seen[curr_vertex] = timestamp;
+
+ if (right[curr_vertex] != graph_traits<Graph>::null_vertex())
+ {
+ seen_as_right[right[curr_vertex]] = timestamp;
+ }
+ installed_neighbors.push_back(curr_vertex);
+ }
+
+ prev_vertex = curr_vertex;
+ }
+
+ typename vertex_vector_t::iterator vi, vi_end;
+ vi_end = installed_neighbors.end();
+ for(vi = installed_neighbors.begin(); vi != vi_end; ++vi)
+ {
+ if (right[*vi] == graph_traits<Graph>::null_vertex() ||
+ seen[right[*vi]] != timestamp
+ )
+ rightmost = *vi;
+ if (seen_as_right[*vi] != timestamp)
+ leftmost = *vi;
+ }
+
+ ++timestamp;
+
+ //stretch gaps
+ ++delta_x[right[leftmost]];
+ ++delta_x[rightmost];
+
+ //adjust offsets
+ std::size_t delta_p_q = 0;
+ vertex_t stopping_vertex = right[rightmost];
+ for(vertex_t temp = right[leftmost]; temp != stopping_vertex;
+ temp = right[temp]
+ )
+ {
+ delta_p_q += delta_x[temp];
+ }
+
+ delta_x[v] = (y[rightmost] - y[leftmost] + delta_p_q)/2;
+ y[v] = (y[rightmost] + y[leftmost] + delta_p_q)/2;
+ delta_x[rightmost] = delta_p_q - delta_x[v];
+
+ bool leftmost_and_rightmost_adjacent = right[leftmost] == rightmost;
+ if (!leftmost_and_rightmost_adjacent)
+ delta_x[right[leftmost]] -= delta_x[v];
+
+ //install v
+ if (!leftmost_and_rightmost_adjacent)
+ {
+ left[v] = right[leftmost];
+ vertex_t next_to_rightmost;
+ for(vertex_t temp = leftmost; temp != rightmost;
+ temp = right[temp]
+ )
+ {
+ next_to_rightmost = temp;
+ }
+
+ right[next_to_rightmost] = graph_traits<Graph>::null_vertex();
+ }
+ else
+ {
+ left[v] = graph_traits<Graph>::null_vertex();
+ }
+
+ right[leftmost] = v;
+ right[v] = rightmost;
+ installed[v] = true;
+
+ }
+
+ graph::detail::accumulate_offsets
+ (*ordering_begin,0,g,x,delta_x,left,right);
+
+ vertex_iterator_t vi, vi_end;
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_t v(*vi);
+ drawing[v].x = x[v];
+ drawing[v].y = y[v];
+ }
+
+ }
+
+
+
+
+ template<typename Graph,
+ typename PlanarEmbedding,
+ typename ForwardIterator,
+ typename GridPositionMap>
+ inline void chrobak_payne_straight_line_drawing(const Graph& g,
+ PlanarEmbedding embedding,
+ ForwardIterator ord_begin,
+ ForwardIterator ord_end,
+ GridPositionMap drawing
+ )
+ {
+ chrobak_payne_straight_line_drawing(g,
+ embedding,
+ ord_begin,
+ ord_end,
+ drawing,
+ get(vertex_index,g)
+ );
+ }
+
+
+
+
+} // namespace boost
+
+#endif //__CHROBAK_PAYNE_DRAWING_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/circle_layout.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/circle_layout.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,55 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// 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)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_CIRCLE_LAYOUT_HPP
+#define BOOST_GRAPH_CIRCLE_LAYOUT_HPP
+#include <cmath>
+#include <utility>
+#include <boost/graph/graph_traits.hpp>
+
+namespace boost {
+ /**
+ * \brief Layout the graph with the vertices at the points of a regular
+ * n-polygon.
+ *
+ * The distance from the center of the polygon to each point is
+ * determined by the @p radius parameter. The @p position parameter
+ * must be an Lvalue Property Map whose value type is a class type
+ * containing @c x and @c y members that will be set to the @c x and
+ * @c y coordinates.
+ */
+ template<typename VertexListGraph, typename PositionMap, typename Radius>
+ void
+ circle_graph_layout(const VertexListGraph& g, PositionMap position,
+ Radius radius)
+ {
+ const double pi = 3.14159;
+
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sin;
+ using std::cos;
+#endif // BOOST_NO_STDC_NAMESPACE
+
+ typedef typename graph_traits<VertexListGraph>::vertices_size_type
+ vertices_size_type;
+
+ vertices_size_type n = num_vertices(g);
+
+ typedef typename graph_traits<VertexListGraph>::vertex_iterator
+ vertex_iterator;
+
+ vertices_size_type i = 0;
+ for(std::pair<vertex_iterator, vertex_iterator> v = vertices(g);
+ v.first != v.second; ++v.first, ++i) {
+ position[*v.first].x = radius * cos(i * 2 * pi / n);
+ position[*v.first].y = radius * sin(i * 2 * pi / n);
+ }
+ }
+} // end namespace boost
+
+#endif // BOOST_GRAPH_CIRCLE_LAYOUT_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/compressed_sparse_row_graph.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/compressed_sparse_row_graph.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,801 @@
+// Copyright 2005-2006 The Trustees of Indiana University.
+
+// 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)
+
+// Authors: Jeremiah Willcock
+// Douglas Gregor
+// Andrew Lumsdaine
+
+// Compressed sparse row graph type
+
+#ifndef BOOST_GRAPH_COMPRESSED_SPARSE_ROW_GRAPH_HPP
+#define BOOST_GRAPH_COMPRESSED_SPARSE_ROW_GRAPH_HPP
+
+#include <vector>
+#include <utility>
+#include <algorithm>
+#include <climits>
+#include <iterator>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/detail/indexed_properties.hpp>
+#include <boost/iterator/counting_iterator.hpp>
+#include <boost/integer.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/graph/graph_selectors.hpp>
+#include <boost/static_assert.hpp>
+
+#ifdef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+# error The Compressed Sparse Row graph only supports bundled properties.
+# error You will need a compiler that conforms better to the C++ standard.
+#endif
+
+namespace boost {
+
+// A tag type indicating that the graph in question is a compressed
+// sparse row graph. This is an internal detail of the BGL.
+struct csr_graph_tag;
+
+/****************************************************************************
+ * Local helper macros to reduce typing and clutter later on. *
+ ****************************************************************************/
+#define BOOST_CSR_GRAPH_TEMPLATE_PARMS \
+ typename Directed, typename VertexProperty, typename EdgeProperty, \
+ typename GraphProperty, typename Vertex, typename EdgeIndex
+#define BOOST_CSR_GRAPH_TYPE \
+ compressed_sparse_row_graph<Directed, VertexProperty, EdgeProperty, \
+ GraphProperty, Vertex, EdgeIndex>
+
+// Forward declaration of CSR edge descriptor type, needed to pass to
+// indexed_edge_properties.
+template<typename Vertex, typename EdgeIndex>
+class csr_edge_descriptor;
+
+/** Compressed sparse row graph.
+ *
+ * Vertex and EdgeIndex should be unsigned integral types and should
+ * specialize numeric_limits.
+ */
+template<typename Directed = directedS,
+ typename VertexProperty = void,
+ typename EdgeProperty = void,
+ typename GraphProperty = no_property,
+ typename Vertex = std::size_t,
+ typename EdgeIndex = Vertex>
+class compressed_sparse_row_graph
+ : public detail::indexed_vertex_properties<BOOST_CSR_GRAPH_TYPE, VertexProperty,
+ Vertex>,
+ public detail::indexed_edge_properties<BOOST_CSR_GRAPH_TYPE, EdgeProperty,
+ csr_edge_descriptor<Vertex,
+ EdgeIndex> >
+
+{
+ typedef detail::indexed_vertex_properties<compressed_sparse_row_graph,
+ VertexProperty, Vertex>
+ inherited_vertex_properties;
+
+ typedef detail::indexed_edge_properties<BOOST_CSR_GRAPH_TYPE, EdgeProperty,
+ csr_edge_descriptor<Vertex, EdgeIndex> >
+ inherited_edge_properties;
+
+ public:
+ // For Property Graph
+ typedef GraphProperty graph_property_type;
+
+ protected:
+ template<typename InputIterator>
+ void
+ maybe_reserve_edge_list_storage(InputIterator, InputIterator,
+ std::input_iterator_tag)
+ {
+ // Do nothing: we have no idea how much storage to reserve.
+ }
+
+ template<typename InputIterator>
+ void
+ maybe_reserve_edge_list_storage(InputIterator first, InputIterator last,
+ std::forward_iterator_tag)
+ {
+ using std::distance;
+ typename std::iterator_traits<InputIterator>::difference_type n =
+ distance(first, last);
+ m_column.reserve(n);
+ inherited_edge_properties::reserve(n);
+ }
+
+ public:
+ /* At this time, the compressed sparse row graph can only be used to
+ * create a directed graph. In the future, bidirectional and
+ * undirected CSR graphs will also be supported.
+ */
+ BOOST_STATIC_ASSERT((is_same<Directed, directedS>::value));
+
+ // Concept requirements:
+ // For Graph
+ typedef Vertex vertex_descriptor;
+ typedef csr_edge_descriptor<Vertex, EdgeIndex> edge_descriptor;
+ typedef directed_tag directed_category;
+ typedef allow_parallel_edge_tag edge_parallel_category;
+
+ class traversal_category: public incidence_graph_tag,
+ public adjacency_graph_tag,
+ public vertex_list_graph_tag,
+ public edge_list_graph_tag {};
+
+ static vertex_descriptor null_vertex() { return vertex_descriptor(-1); }
+
+ // For VertexListGraph
+ typedef counting_iterator<Vertex> vertex_iterator;
+ typedef Vertex vertices_size_type;
+
+ // For EdgeListGraph
+ typedef EdgeIndex edges_size_type;
+
+ // For IncidenceGraph
+ class out_edge_iterator;
+ typedef EdgeIndex degree_size_type;
+
+ // For AdjacencyGraph
+ typedef typename std::vector<Vertex>::const_iterator adjacency_iterator;
+
+ // For EdgeListGraph
+ class edge_iterator;
+
+ // For BidirectionalGraph (not implemented)
+ typedef void in_edge_iterator;
+
+ // For internal use
+ typedef csr_graph_tag graph_tag;
+
+ // Constructors
+
+ // Default constructor: an empty graph.
+ compressed_sparse_row_graph()
+ : m_rowstart(1, EdgeIndex(0)), m_column(0), m_property(),
+ m_last_source(0) {}
+
+ // From number of vertices and sorted list of edges
+ template<typename InputIterator>
+ compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
+ vertices_size_type numverts,
+ edges_size_type numedges = 0,
+ const GraphProperty& prop = GraphProperty())
+ : inherited_vertex_properties(numverts), m_rowstart(numverts + 1),
+ m_column(0), m_property(prop), m_last_source(numverts)
+ {
+ // Reserving storage in advance can save us lots of time and
+ // memory, but it can only be done if we have forward iterators or
+ // the user has supplied the number of edges.
+ if (numedges == 0) {
+ typedef typename std::iterator_traits<InputIterator>::iterator_category
+ category;
+ maybe_reserve_edge_list_storage(edge_begin, edge_end, category());
+ } else {
+ m_column.reserve(numedges);
+ }
+
+ EdgeIndex current_edge = 0;
+ Vertex current_vertex_plus_one = 1;
+ m_rowstart[0] = 0;
+ for (InputIterator ei = edge_begin; ei != edge_end; ++ei) {
+ Vertex src = ei->first;
+ Vertex tgt = ei->second;
+ for (; current_vertex_plus_one != src + 1; ++current_vertex_plus_one)
+ m_rowstart[current_vertex_plus_one] = current_edge;
+ m_column.push_back(tgt);
+ ++current_edge;
+ }
+
+ // The remaining vertices have no edges
+ for (; current_vertex_plus_one != numverts + 1; ++current_vertex_plus_one)
+ m_rowstart[current_vertex_plus_one] = current_edge;
+
+ // Default-construct properties for edges
+ inherited_edge_properties::resize(m_column.size());
+ }
+
+ // From number of vertices and sorted list of edges
+ template<typename InputIterator, typename EdgePropertyIterator>
+ compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
+ EdgePropertyIterator ep_iter,
+ vertices_size_type numverts,
+ edges_size_type numedges = 0,
+ const GraphProperty& prop = GraphProperty())
+ : inherited_vertex_properties(numverts), m_rowstart(numverts + 1),
+ m_column(0), m_property(prop), m_last_source(numverts)
+ {
+ // Reserving storage in advance can save us lots of time and
+ // memory, but it can only be done if we have forward iterators or
+ // the user has supplied the number of edges.
+ if (numedges == 0) {
+ typedef typename std::iterator_traits<InputIterator>::iterator_category
+ category;
+ maybe_reserve_edge_list_storage(edge_begin, edge_end, category());
+ } else {
+ m_column.reserve(numedges);
+ }
+
+ EdgeIndex current_edge = 0;
+ Vertex current_vertex_plus_one = 1;
+ m_rowstart[0] = 0;
+ for (InputIterator ei = edge_begin; ei != edge_end; ++ei, ++ep_iter) {
+ Vertex src = ei->first;
+ Vertex tgt = ei->second;
+ for (; current_vertex_plus_one != src + 1; ++current_vertex_plus_one)
+ m_rowstart[current_vertex_plus_one] = current_edge;
+ m_column.push_back(tgt);
+ inherited_edge_properties::push_back(*ep_iter);
+ ++current_edge;
+ }
+
+ // The remaining vertices have no edges
+ for (; current_vertex_plus_one != numverts + 1; ++current_vertex_plus_one)
+ m_rowstart[current_vertex_plus_one] = current_edge;
+ }
+
+ // Requires IncidenceGraph, a vertex index map, and a vertex(n, g) function
+ template<typename Graph, typename VertexIndexMap>
+ compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi,
+ vertices_size_type numverts,
+ edges_size_type numedges)
+ : m_property(), m_last_source(0)
+ {
+ assign(g, vi, numverts, numedges);
+ }
+
+ // Requires VertexListGraph and EdgeListGraph
+ template<typename Graph, typename VertexIndexMap>
+ compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi)
+ : m_property(), m_last_source(0)
+ {
+ assign(g, vi, num_vertices(g), num_edges(g));
+ }
+
+ // Requires vertex index map plus requirements of previous constructor
+ template<typename Graph>
+ explicit compressed_sparse_row_graph(const Graph& g)
+ : m_property(), m_last_source(0)
+ {
+ assign(g, get(vertex_index, g), num_vertices(g), num_edges(g));
+ }
+
+ // From any graph (slow and uses a lot of memory)
+ // Requires IncidenceGraph, a vertex index map, and a vertex(n, g) function
+ // Internal helper function
+ template<typename Graph, typename VertexIndexMap>
+ void
+ assign(const Graph& g, const VertexIndexMap& vi,
+ vertices_size_type numverts, edges_size_type numedges)
+ {
+ inherited_vertex_properties::resize(numverts);
+ m_rowstart.resize(numverts + 1);
+ m_column.resize(numedges);
+ EdgeIndex current_edge = 0;
+ typedef typename boost::graph_traits<Graph>::vertex_descriptor g_vertex;
+ typedef typename boost::graph_traits<Graph>::edge_descriptor g_edge;
+ typedef typename boost::graph_traits<Graph>::out_edge_iterator
+ g_out_edge_iter;
+
+ for (Vertex i = 0; i != numverts; ++i) {
+ m_rowstart[i] = current_edge;
+ g_vertex v = vertex(i, g);
+ EdgeIndex num_edges_before_this_vertex = current_edge;
+ g_out_edge_iter ei, ei_end;
+ for (tie(ei, ei_end) = out_edges(v, g); ei != ei_end; ++ei) {
+ m_column[current_edge++] = get(vi, target(*ei, g));
+ }
+ std::sort(m_column.begin() + num_edges_before_this_vertex,
+ m_column.begin() + current_edge);
+ }
+ m_rowstart[numverts] = current_edge;
+ m_last_source = numverts;
+ }
+
+ // Requires the above, plus VertexListGraph and EdgeListGraph
+ template<typename Graph, typename VertexIndexMap>
+ void assign(const Graph& g, const VertexIndexMap& vi)
+ {
+ assign(g, vi, num_vertices(g), num_edges(g));
+ }
+
+ // Requires the above, plus a vertex_index map.
+ template<typename Graph>
+ void assign(const Graph& g)
+ {
+ assign(g, get(vertex_index, g), num_vertices(g), num_edges(g));
+ }
+
+ using inherited_vertex_properties::operator[];
+ using inherited_edge_properties::operator[];
+
+ // private: non-portable, requires friend templates
+ inherited_vertex_properties& vertex_properties() {return *this;}
+ const inherited_vertex_properties& vertex_properties() const {return *this;}
+ inherited_edge_properties& edge_properties() { return *this; }
+ const inherited_edge_properties& edge_properties() const { return *this; }
+
+ std::vector<EdgeIndex> m_rowstart;
+ std::vector<Vertex> m_column;
+ GraphProperty m_property;
+ Vertex m_last_source; // Last source of added edge, plus one
+};
+
+template<typename Vertex, typename EdgeIndex>
+class csr_edge_descriptor
+{
+ public:
+ Vertex src;
+ EdgeIndex idx;
+
+ csr_edge_descriptor(Vertex src, EdgeIndex idx): src(src), idx(idx) {}
+ csr_edge_descriptor(): src(0), idx(0) {}
+
+ bool operator==(const csr_edge_descriptor& e) const {return idx == e.idx;}
+ bool operator!=(const csr_edge_descriptor& e) const {return idx != e.idx;}
+ bool operator<(const csr_edge_descriptor& e) const {return idx < e.idx;}
+ bool operator>(const csr_edge_descriptor& e) const {return idx > e.idx;}
+ bool operator<=(const csr_edge_descriptor& e) const {return idx <= e.idx;}
+ bool operator>=(const csr_edge_descriptor& e) const {return idx >= e.idx;}
+};
+
+// Construction functions
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline Vertex
+add_vertex(BOOST_CSR_GRAPH_TYPE& g) {
+ Vertex old_num_verts_plus_one = g.m_rowstart.size();
+ g.m_rowstart.push_back(EdgeIndex(0));
+ g.vertex_properties().resize(num_vertices(g));
+ return old_num_verts_plus_one - 1;
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline Vertex
+add_vertices(typename BOOST_CSR_GRAPH_TYPE::vertices_size_type count, BOOST_CSR_GRAPH_TYPE& g) {
+ Vertex old_num_verts_plus_one = g.m_rowstart.size();
+ g.m_rowstart.resize(old_num_verts_plus_one + count, EdgeIndex(0));
+ g.vertex_properties().resize(num_vertices(g));
+ return old_num_verts_plus_one - 1;
+}
+
+// This function requires that (src, tgt) be lexicographically at least as
+// large as the largest edge in the graph so far
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline typename BOOST_CSR_GRAPH_TYPE::edge_descriptor
+add_edge(Vertex src, Vertex tgt, BOOST_CSR_GRAPH_TYPE& g) {
+ assert ((g.m_last_source == 0 || src >= g.m_last_source - 1) &&
+ src < num_vertices(g));
+ EdgeIndex num_edges_orig = g.m_column.size();
+ for (; g.m_last_source <= src; ++g.m_last_source)
+ g.m_rowstart[g.m_last_source] = num_edges_orig;
+ g.m_rowstart[src + 1] = num_edges_orig + 1;
+ g.m_column.push_back(tgt);
+ typedef typename BOOST_CSR_GRAPH_TYPE::edge_push_back_type push_back_type;
+ g.edge_properties().push_back(push_back_type());
+ return typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(src, num_edges_orig);
+}
+
+// This function requires that (src, tgt) be lexicographically at least as
+// large as the largest edge in the graph so far
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline typename BOOST_CSR_GRAPH_TYPE::edge_descriptor
+add_edge(Vertex src, Vertex tgt,
+ typename BOOST_CSR_GRAPH_TYPE::edge_bundled const& p,
+ BOOST_CSR_GRAPH_TYPE& g) {
+ assert ((g.m_last_source == 0 || src >= g.m_last_source - 1) &&
+ src < num_vertices(g));
+ EdgeIndex num_edges_orig = g.m_column.size();
+ for (; g.m_last_source <= src; ++g.m_last_source)
+ g.m_rowstart[g.m_last_source] = num_edges_orig;
+ g.m_rowstart[src + 1] = num_edges_orig + 1;
+ g.m_column.push_back(tgt);
+ g.edge_properties().push_back(p);
+ return typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(src, num_edges_orig);
+}
+
+
+// From VertexListGraph
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline Vertex
+num_vertices(const BOOST_CSR_GRAPH_TYPE& g) {
+ return g.m_rowstart.size() - 1;
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+std::pair<counting_iterator<Vertex>, counting_iterator<Vertex> >
+inline vertices(const BOOST_CSR_GRAPH_TYPE& g) {
+ return std::make_pair(counting_iterator<Vertex>(0),
+ counting_iterator<Vertex>(num_vertices(g)));
+}
+
+// From IncidenceGraph
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+class BOOST_CSR_GRAPH_TYPE::out_edge_iterator
+ : public iterator_facade<typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator,
+ typename BOOST_CSR_GRAPH_TYPE::edge_descriptor,
+ std::random_access_iterator_tag,
+ const typename BOOST_CSR_GRAPH_TYPE::edge_descriptor&,
+ typename int_t<CHAR_BIT * sizeof(EdgeIndex)>::fast>
+{
+ public:
+ typedef typename int_t<CHAR_BIT * sizeof(EdgeIndex)>::fast difference_type;
+
+ out_edge_iterator() {}
+ // Implicit copy constructor OK
+ explicit out_edge_iterator(edge_descriptor edge) : m_edge(edge) { }
+
+ private:
+ // iterator_facade requirements
+ const edge_descriptor& dereference() const { return m_edge; }
+
+ bool equal(const out_edge_iterator& other) const
+ { return m_edge == other.m_edge; }
+
+ void increment() { ++m_edge.idx; }
+ void decrement() { ++m_edge.idx; }
+ void advance(difference_type n) { m_edge.idx += n; }
+
+ difference_type distance_to(const out_edge_iterator& other) const
+ { return other.m_edge.idx - m_edge.idx; }
+
+ edge_descriptor m_edge;
+
+ friend class iterator_core_access;
+};
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline Vertex
+source(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e,
+ const BOOST_CSR_GRAPH_TYPE&)
+{
+ return e.src;
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline Vertex
+target(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e,
+ const BOOST_CSR_GRAPH_TYPE& g)
+{
+ return g.m_column[e.idx];
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline std::pair<typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator,
+ typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator>
+out_edges(Vertex v, const BOOST_CSR_GRAPH_TYPE& g)
+{
+ typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor ed;
+ typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator it;
+ EdgeIndex v_row_start = g.m_rowstart[v];
+ EdgeIndex next_row_start = g.m_rowstart[v + 1];
+ return std::make_pair(it(ed(v, v_row_start)),
+ it(ed(v, (std::max)(v_row_start, next_row_start))));
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline EdgeIndex
+out_degree(Vertex v, const BOOST_CSR_GRAPH_TYPE& g)
+{
+ EdgeIndex v_row_start = g.m_rowstart[v];
+ EdgeIndex next_row_start = g.m_rowstart[v + 1];
+ return (std::max)(v_row_start, next_row_start) - v_row_start;
+}
+
+// From AdjacencyGraph
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline std::pair<typename BOOST_CSR_GRAPH_TYPE::adjacency_iterator,
+ typename BOOST_CSR_GRAPH_TYPE::adjacency_iterator>
+adjacent_vertices(Vertex v, const BOOST_CSR_GRAPH_TYPE& g)
+{
+ EdgeIndex v_row_start = g.m_rowstart[v];
+ EdgeIndex next_row_start = g.m_rowstart[v + 1];
+ return std::make_pair(g.m_column.begin() + v_row_start,
+ g.m_column.begin() +
+ (std::max)(v_row_start, next_row_start));
+}
+
+// Extra, common functions
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline typename graph_traits<BOOST_CSR_GRAPH_TYPE>::vertex_descriptor
+vertex(typename graph_traits<BOOST_CSR_GRAPH_TYPE>::vertex_descriptor i,
+ const BOOST_CSR_GRAPH_TYPE&)
+{
+ return i;
+}
+
+// Unlike for an adjacency_matrix, edge_range and edge take lg(out_degree(i))
+// time
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline std::pair<typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator,
+ typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator>
+edge_range(Vertex i, Vertex j, const BOOST_CSR_GRAPH_TYPE& g)
+{
+ typedef typename std::vector<Vertex>::const_iterator adj_iter;
+ typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter;
+ typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor edge_desc;
+ std::pair<adj_iter, adj_iter> raw_adjacencies = adjacent_vertices(i, g);
+ std::pair<adj_iter, adj_iter> adjacencies =
+ std::equal_range(raw_adjacencies.first, raw_adjacencies.second, j);
+ EdgeIndex idx_begin = adjacencies.first - g.m_column.begin();
+ EdgeIndex idx_end = adjacencies.second - g.m_column.begin();
+ return std::make_pair(out_edge_iter(edge_desc(i, idx_begin)),
+ out_edge_iter(edge_desc(i, idx_end)));
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline std::pair<typename BOOST_CSR_GRAPH_TYPE::edge_descriptor, bool>
+edge(Vertex i, Vertex j, const BOOST_CSR_GRAPH_TYPE& g)
+{
+ typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter;
+ std::pair<out_edge_iter, out_edge_iter> range = edge_range(i, j, g);
+ if (range.first == range.second)
+ return std::make_pair(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(),
+ false);
+ else
+ return std::make_pair(*range.first, true);
+}
+
+// Find an edge given its index in the graph
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline typename BOOST_CSR_GRAPH_TYPE::edge_descriptor
+edge_from_index(EdgeIndex idx, const BOOST_CSR_GRAPH_TYPE& g)
+{
+ typedef typename std::vector<EdgeIndex>::const_iterator row_start_iter;
+ assert (idx < num_edges(g));
+ row_start_iter src_plus_1 =
+ std::upper_bound(g.m_rowstart.begin(),
+ g.m_rowstart.begin() + g.m_last_source + 1,
+ idx);
+ // Get last source whose rowstart is at most idx
+ // upper_bound returns this position plus 1
+ Vertex src = (src_plus_1 - g.m_rowstart.begin()) - 1;
+ return typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(src, idx);
+}
+
+// From EdgeListGraph
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+class BOOST_CSR_GRAPH_TYPE::edge_iterator
+{
+ public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef edge_descriptor value_type;
+
+ typedef const edge_descriptor* pointer;
+
+ typedef edge_descriptor reference;
+ typedef typename int_t<CHAR_BIT * sizeof(EdgeIndex)>::fast difference_type;
+
+ edge_iterator() : rowstart_array(0), current_edge(), end_of_this_vertex(0) {}
+
+ edge_iterator(const compressed_sparse_row_graph& graph,
+ edge_descriptor current_edge,
+ EdgeIndex end_of_this_vertex)
+ : rowstart_array(&graph.m_rowstart[0]), current_edge(current_edge),
+ end_of_this_vertex(end_of_this_vertex) {}
+
+ // From InputIterator
+ reference operator*() const { return current_edge; }
+ pointer operator->() const { return ¤t_edge; }
+
+ bool operator==(const edge_iterator& o) const {
+ return current_edge == o.current_edge;
+ }
+ bool operator!=(const edge_iterator& o) const {
+ return current_edge != o.current_edge;
+ }
+
+ edge_iterator& operator++() {
+ ++current_edge.idx;
+ while (current_edge.idx == end_of_this_vertex) {
+ ++current_edge.src;
+ end_of_this_vertex = rowstart_array[current_edge.src + 1];
+ }
+ return *this;
+ }
+
+ edge_iterator operator++(int) {
+ edge_iterator temp = *this;
+ ++*this;
+ return temp;
+ }
+
+ private:
+ const EdgeIndex* rowstart_array;
+ edge_descriptor current_edge;
+ EdgeIndex end_of_this_vertex;
+};
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline EdgeIndex
+num_edges(const BOOST_CSR_GRAPH_TYPE& g)
+{
+ return g.m_column.size();
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+std::pair<typename BOOST_CSR_GRAPH_TYPE::edge_iterator,
+ typename BOOST_CSR_GRAPH_TYPE::edge_iterator>
+edges(const BOOST_CSR_GRAPH_TYPE& g)
+{
+ typedef typename BOOST_CSR_GRAPH_TYPE::edge_iterator ei;
+ typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor edgedesc;
+ if (g.m_rowstart.size() == 1 || g.m_column.empty()) {
+ return std::make_pair(ei(), ei());
+ } else {
+ // Find the first vertex that has outgoing edges
+ Vertex src = 0;
+ while (g.m_rowstart[src + 1] == 0) ++src;
+ return std::make_pair(ei(g, edgedesc(src, 0), g.m_rowstart[src + 1]),
+ ei(g, edgedesc(num_vertices(g), g.m_column.size()), 0));
+ }
+}
+
+// For Property Graph
+
+// Graph properties
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS, class Tag, class Value>
+inline void
+set_property(BOOST_CSR_GRAPH_TYPE& g, Tag, const Value& value)
+{
+ get_property_value(g.m_property, Tag()) = value;
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS, class Tag>
+inline
+typename graph_property<BOOST_CSR_GRAPH_TYPE, Tag>::type&
+get_property(BOOST_CSR_GRAPH_TYPE& g, Tag)
+{
+ return get_property_value(g.m_property, Tag());
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS, class Tag>
+inline
+const
+typename graph_property<BOOST_CSR_GRAPH_TYPE, Tag>::type&
+get_property(const BOOST_CSR_GRAPH_TYPE& g, Tag)
+{
+ return get_property_value(g.m_property, Tag());
+}
+
+// Add edge_index property map
+template<typename Index, typename Descriptor>
+struct csr_edge_index_map
+{
+ typedef Index value_type;
+ typedef Index reference;
+ typedef Descriptor key_type;
+ typedef readable_property_map_tag category;
+};
+
+template<typename Index, typename Descriptor>
+inline Index
+get(const csr_edge_index_map<Index, Descriptor>&,
+ const typename csr_edge_index_map<Index, Descriptor>::key_type& key)
+{
+ return key.idx;
+}
+
+// Doing the right thing here (by unifying with vertex_index_t and
+// edge_index_t) breaks GCC.
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
+struct property_map<BOOST_CSR_GRAPH_TYPE, Tag>
+{
+private:
+ typedef identity_property_map vertex_index_type;
+ typedef typename graph_traits<BOOST_CSR_GRAPH_TYPE>::edge_descriptor
+ edge_descriptor;
+ typedef csr_edge_index_map<EdgeIndex, edge_descriptor> edge_index_type;
+
+ typedef typename mpl::if_<is_same<Tag, edge_index_t>,
+ edge_index_type,
+ detail::error_property_not_found>::type
+ edge_or_none;
+
+public:
+ typedef typename mpl::if_<is_same<Tag, vertex_index_t>,
+ vertex_index_type,
+ edge_or_none>::type type;
+
+ typedef type const_type;
+};
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline identity_property_map
+get(vertex_index_t, const BOOST_CSR_GRAPH_TYPE&)
+{
+ return identity_property_map();
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline Vertex
+get(vertex_index_t,
+ const BOOST_CSR_GRAPH_TYPE&, Vertex v)
+{
+ return v;
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline typename property_map<BOOST_CSR_GRAPH_TYPE, edge_index_t>::const_type
+get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&)
+{
+ typedef typename property_map<BOOST_CSR_GRAPH_TYPE, edge_index_t>::const_type
+ result_type;
+ return result_type();
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
+inline EdgeIndex
+get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&,
+ typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e)
+{
+ return e.idx;
+}
+
+// Support for bundled properties
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename T, typename Bundle>
+struct property_map<BOOST_CSR_GRAPH_TYPE, T Bundle::*>
+{
+private:
+ typedef graph_traits<BOOST_CSR_GRAPH_TYPE> traits;
+ typedef VertexProperty vertex_bundled;
+ typedef EdgeProperty edge_bundled;
+ typedef typename mpl::if_c<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value),
+ typename traits::vertex_descriptor,
+ typename traits::edge_descriptor>::type
+ descriptor;
+
+public:
+ typedef bundle_property_map<BOOST_CSR_GRAPH_TYPE, descriptor, Bundle, T>
+ type;
+ typedef bundle_property_map<const BOOST_CSR_GRAPH_TYPE, descriptor, Bundle,
+ const T> const_type;
+};
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename T, typename Bundle>
+inline
+typename property_map<BOOST_CSR_GRAPH_TYPE, T Bundle::*>::type
+get(T Bundle::* p, BOOST_CSR_GRAPH_TYPE& g)
+{
+ typedef typename property_map<BOOST_CSR_GRAPH_TYPE,
+ T Bundle::*>::type
+ result_type;
+ return result_type(&g, p);
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename T, typename Bundle>
+inline
+typename property_map<BOOST_CSR_GRAPH_TYPE, T Bundle::*>::const_type
+get(T Bundle::* p, BOOST_CSR_GRAPH_TYPE const & g)
+{
+ typedef typename property_map<BOOST_CSR_GRAPH_TYPE,
+ T Bundle::*>::const_type
+ result_type;
+ return result_type(&g, p);
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename T, typename Bundle,
+ typename Key>
+inline T
+get(T Bundle::* p, BOOST_CSR_GRAPH_TYPE const & g,
+ const Key& key)
+{
+ return get(get(p, g), key);
+}
+
+template<BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename T, typename Bundle,
+ typename Key>
+inline void
+put(T Bundle::* p, BOOST_CSR_GRAPH_TYPE& g,
+ const Key& key, const T& value)
+{
+ put(get(p, g), key, value);
+}
+
+#undef BOOST_CSR_GRAPH_TYPE
+#undef BOOST_CSR_GRAPH_TEMPLATE_PARMS
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_COMPRESSED_SPARSE_ROW_GRAPH_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/connected_components.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/connected_components.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,101 @@
+//
+//=======================================================================
+// Copyright 1997-2001 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_CONNECTED_COMPONENTS_HPP
+#define BOOST_GRAPH_CONNECTED_COMPONENTS_HPP
+
+#include <boost/config.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/graph_concepts.hpp>
+
+#include <boost/static_assert.hpp>
+
+namespace boost {
+
+ namespace detail {
+
+ // This visitor is used both in the connected_components algorithm
+ // and in the kosaraju strong components algorithm during the
+ // second DFS traversal.
+ template <class ComponentsMap>
+ class components_recorder : public dfs_visitor<>
+ {
+ typedef typename property_traits<ComponentsMap>::value_type comp_type;
+ public:
+ components_recorder(ComponentsMap c,
+ comp_type& c_count)
+ : m_component(c), m_count(c_count) {}
+
+ template <class Vertex, class Graph>
+ void start_vertex(Vertex, Graph&) {
+ if (m_count == (std::numeric_limits<comp_type>::max)())
+ m_count = 0; // start counting components at zero
+ else
+ ++m_count;
+ }
+ template <class Vertex, class Graph>
+ void discover_vertex(Vertex u, Graph&) {
+ put(m_component, u, m_count);
+ }
+ protected:
+ ComponentsMap m_component;
+ comp_type& m_count;
+ };
+
+ } // namespace detail
+
+ // This function computes the connected components of an undirected
+ // graph using a single application of depth first search.
+
+ template <class Graph, class ComponentMap, class P, class T, class R>
+ inline typename property_traits<ComponentMap>::value_type
+ connected_components(const Graph& g, ComponentMap c,
+ const bgl_named_params<P, T, R>& params)
+ {
+ if (num_vertices(g) == 0) return 0;
+
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ function_requires< WritablePropertyMapConcept<ComponentMap, Vertex> >();
+ typedef typename boost::graph_traits<Graph>::directed_category directed;
+ BOOST_STATIC_ASSERT((boost::is_same<directed, undirected_tag>::value));
+
+ typedef typename property_traits<ComponentMap>::value_type comp_type;
+ // c_count initialized to "nil" (with nil represented by (max)())
+ comp_type c_count((std::numeric_limits<comp_type>::max)());
+ detail::components_recorder<ComponentMap> vis(c, c_count);
+ depth_first_search(g, params.visitor(vis));
+ return c_count + 1;
+ }
+
+ template <class Graph, class ComponentMap>
+ inline typename property_traits<ComponentMap>::value_type
+ connected_components(const Graph& g, ComponentMap c)
+ {
+ if (num_vertices(g) == 0) return 0;
+
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ function_requires< WritablePropertyMapConcept<ComponentMap, Vertex> >();
+ typedef typename boost::graph_traits<Graph>::directed_category directed;
+ BOOST_STATIC_ASSERT((boost::is_same<directed, undirected_tag>::value));
+
+ typedef typename property_traits<ComponentMap>::value_type comp_type;
+ // c_count initialized to "nil" (with nil represented by (max)())
+ comp_type c_count((std::numeric_limits<comp_type>::max)());
+ detail::components_recorder<ComponentMap> vis(c, c_count);
+ depth_first_search(g, visitor(vis));
+ return c_count + 1;
+ }
+
+
+} // namespace boost
+
+
+#endif // BOOST_GRAPH_CONNECTED_COMPONENTS_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/copy.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/copy.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,450 @@
+//
+//=======================================================================
+// Copyright 1997-2001 University of Notre Dame.
+// Authors: Jeremy G. Siek, Lie-Quan Lee, Andrew Lumsdaine
+//
+// 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)
+//=======================================================================
+//
+
+/*
+ This file implements the following functions:
+
+
+ template <typename VertexListGraph, typename MutableGraph>
+ void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out)
+
+ template <typename VertexListGraph, typename MutableGraph,
+ class P, class T, class R>
+ void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out,
+ const bgl_named_params<P, T, R>& params)
+
+
+ template <typename IncidenceGraph, typename MutableGraph>
+ typename graph_traits<MutableGraph>::vertex_descriptor
+ copy_component(IncidenceGraph& g_in,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor src,
+ MutableGraph& g_out)
+
+ template <typename IncidenceGraph, typename MutableGraph,
+ typename P, typename T, typename R>
+ typename graph_traits<MutableGraph>::vertex_descriptor
+ copy_component(IncidenceGraph& g_in,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor src,
+ MutableGraph& g_out,
+ const bgl_named_params<P, T, R>& params)
+ */
+
+
+#ifndef BOOST_GRAPH_COPY_HPP
+#define BOOST_GRAPH_COPY_HPP
+
+#include <boost/config.hpp>
+#include <vector>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/type_traits/conversion_traits.hpp>
+
+namespace boost {
+
+ namespace detail {
+
+ // Default edge and vertex property copiers
+
+ template <typename Graph1, typename Graph2>
+ struct edge_copier {
+ edge_copier(const Graph1& g1, Graph2& g2)
+ : edge_all_map1(get(edge_all, g1)),
+ edge_all_map2(get(edge_all, g2)) { }
+
+ template <typename Edge1, typename Edge2>
+ void operator()(const Edge1& e1, Edge2& e2) const {
+ put(edge_all_map2, e2, get(edge_all_map1, e1));
+ }
+ typename property_map<Graph1, edge_all_t>::const_type edge_all_map1;
+ mutable typename property_map<Graph2, edge_all_t>::type edge_all_map2;
+ };
+ template <typename Graph1, typename Graph2>
+ inline edge_copier<Graph1,Graph2>
+ make_edge_copier(const Graph1& g1, Graph2& g2)
+ {
+ return edge_copier<Graph1,Graph2>(g1, g2);
+ }
+
+ template <typename Graph1, typename Graph2>
+ struct vertex_copier {
+ vertex_copier(const Graph1& g1, Graph2& g2)
+ : vertex_all_map1(get(vertex_all, g1)),
+ vertex_all_map2(get(vertex_all, g2)) { }
+
+ template <typename Vertex1, typename Vertex2>
+ void operator()(const Vertex1& v1, Vertex2& v2) const {
+ put(vertex_all_map2, v2, get(vertex_all_map1, v1));
+ }
+ typename property_map<Graph1, vertex_all_t>::const_type vertex_all_map1;
+ mutable typename property_map<Graph2, vertex_all_t>::type
+ vertex_all_map2;
+ };
+ template <typename Graph1, typename Graph2>
+ inline vertex_copier<Graph1,Graph2>
+ make_vertex_copier(const Graph1& g1, Graph2& g2)
+ {
+ return vertex_copier<Graph1,Graph2>(g1, g2);
+ }
+
+ // Copy all the vertices and edges of graph g_in into graph g_out.
+ // The copy_vertex and copy_edge function objects control how vertex
+ // and edge properties are copied.
+
+ template <int Version>
+ struct copy_graph_impl { };
+
+ template <> struct copy_graph_impl<0>
+ {
+ template <typename Graph, typename MutableGraph,
+ typename CopyVertex, typename CopyEdge, typename IndexMap,
+ typename Orig2CopyVertexIndexMap>
+ static void apply(const Graph& g_in, MutableGraph& g_out,
+ CopyVertex copy_vertex, CopyEdge copy_edge,
+ Orig2CopyVertexIndexMap orig2copy, IndexMap)
+ {
+ typename graph_traits<Graph>::vertex_iterator vi, vi_end;
+ for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
+ typename graph_traits<MutableGraph>::vertex_descriptor
+ new_v = add_vertex(g_out);
+ put(orig2copy, *vi, new_v);
+ copy_vertex(*vi, new_v);
+ }
+ typename graph_traits<Graph>::edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = edges(g_in); ei != ei_end; ++ei) {
+ typename graph_traits<MutableGraph>::edge_descriptor new_e;
+ bool inserted;
+ tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei, g_in)),
+ get(orig2copy, target(*ei, g_in)),
+ g_out);
+ copy_edge(*ei, new_e);
+ }
+ }
+ };
+
+ // for directed graphs
+ template <> struct copy_graph_impl<1>
+ {
+ template <typename Graph, typename MutableGraph,
+ typename CopyVertex, typename CopyEdge, typename IndexMap,
+ typename Orig2CopyVertexIndexMap>
+ static void apply(const Graph& g_in, MutableGraph& g_out,
+ CopyVertex copy_vertex, CopyEdge copy_edge,
+ Orig2CopyVertexIndexMap orig2copy, IndexMap)
+ {
+ typename graph_traits<Graph>::vertex_iterator vi, vi_end;
+ for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
+ typename graph_traits<MutableGraph>::vertex_descriptor
+ new_v = add_vertex(g_out);
+ put(orig2copy, *vi, new_v);
+ copy_vertex(*vi, new_v);
+ }
+ for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
+ typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = out_edges(*vi, g_in); ei != ei_end; ++ei) {
+ typename graph_traits<MutableGraph>::edge_descriptor new_e;
+ bool inserted;
+ tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei, g_in)),
+ get(orig2copy, target(*ei, g_in)),
+ g_out);
+ copy_edge(*ei, new_e);
+ }
+ }
+ }
+ };
+
+ // for undirected graphs
+ template <> struct copy_graph_impl<2>
+ {
+ template <typename Graph, typename MutableGraph,
+ typename CopyVertex, typename CopyEdge, typename IndexMap,
+ typename Orig2CopyVertexIndexMap>
+ static void apply(const Graph& g_in, MutableGraph& g_out,
+ CopyVertex copy_vertex, CopyEdge copy_edge,
+ Orig2CopyVertexIndexMap orig2copy,
+ IndexMap index_map)
+ {
+ typedef color_traits<default_color_type> Color;
+ std::vector<default_color_type>
+ color(num_vertices(g_in), Color::white());
+ typename graph_traits<Graph>::vertex_iterator vi, vi_end;
+ for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
+ typename graph_traits<MutableGraph>::vertex_descriptor
+ new_v = add_vertex(g_out);
+ put(orig2copy, *vi, new_v);
+ copy_vertex(*vi, new_v);
+ }
+ for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
+ typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = out_edges(*vi, g_in); ei != ei_end; ++ei) {
+ typename graph_traits<MutableGraph>::edge_descriptor new_e;
+ bool inserted;
+ if (color[get(index_map, target(*ei, g_in))] == Color::white()) {
+ tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei,g_in)),
+ get(orig2copy, target(*ei,g_in)),
+ g_out);
+ copy_edge(*ei, new_e);
+ }
+ }
+ color[get(index_map, *vi)] = Color::black();
+ }
+ }
+ };
+
+ template <class Graph>
+ struct choose_graph_copy {
+ typedef typename Graph::traversal_category Trv;
+ typedef typename Graph::directed_category Dr;
+ enum { algo =
+ (is_convertible<Trv, vertex_list_graph_tag>::value
+ && is_convertible<Trv, edge_list_graph_tag>::value)
+ ? 0 : is_convertible<Dr, directed_tag>::value ? 1 : 2 };
+ typedef copy_graph_impl<algo> type;
+ };
+
+ //-------------------------------------------------------------------------
+ struct choose_copier_parameter {
+ template <class P, class G1, class G2>
+ struct bind_ {
+ typedef const P& result_type;
+ static result_type apply(const P& p, const G1&, G2&)
+ { return p; }
+ };
+ };
+ struct choose_default_edge_copier {
+ template <class P, class G1, class G2>
+ struct bind_ {
+ typedef edge_copier<G1, G2> result_type;
+ static result_type apply(const P&, const G1& g1, G2& g2) {
+ return result_type(g1, g2);
+ }
+ };
+ };
+ template <class Param>
+ struct choose_edge_copy {
+ typedef choose_copier_parameter type;
+ };
+ template <>
+ struct choose_edge_copy<detail::error_property_not_found> {
+ typedef choose_default_edge_copier type;
+ };
+ template <class Param, class G1, class G2>
+ struct choose_edge_copier_helper {
+ typedef typename choose_edge_copy<Param>::type Selector;
+ typedef typename Selector:: template bind_<Param, G1, G2> Bind;
+ typedef Bind type;
+ typedef typename Bind::result_type result_type;
+ };
+ template <typename Param, typename G1, typename G2>
+ typename detail::choose_edge_copier_helper<Param,G1,G2>::result_type
+ choose_edge_copier(const Param& params, const G1& g_in, G2& g_out)
+ {
+ typedef typename
+ detail::choose_edge_copier_helper<Param,G1,G2>::type Choice;
+ return Choice::apply(params, g_in, g_out);
+ }
+
+
+ struct choose_default_vertex_copier {
+ template <class P, class G1, class G2>
+ struct bind_ {
+ typedef vertex_copier<G1, G2> result_type;
+ static result_type apply(const P&, const G1& g1, G2& g2) {
+ return result_type(g1, g2);
+ }
+ };
+ };
+ template <class Param>
+ struct choose_vertex_copy {
+ typedef choose_copier_parameter type;
+ };
+ template <>
+ struct choose_vertex_copy<detail::error_property_not_found> {
+ typedef choose_default_vertex_copier type;
+ };
+ template <class Param, class G1, class G2>
+ struct choose_vertex_copier_helper {
+ typedef typename choose_vertex_copy<Param>::type Selector;
+ typedef typename Selector:: template bind_<Param, G1, G2> Bind;
+ typedef Bind type;
+ typedef typename Bind::result_type result_type;
+ };
+ template <typename Param, typename G1, typename G2>
+ typename detail::choose_vertex_copier_helper<Param,G1,G2>::result_type
+ choose_vertex_copier(const Param& params, const G1& g_in, G2& g_out)
+ {
+ typedef typename
+ detail::choose_vertex_copier_helper<Param,G1,G2>::type Choice;
+ return Choice::apply(params, g_in, g_out);
+ }
+
+ } // namespace detail
+
+
+ template <typename VertexListGraph, typename MutableGraph>
+ void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out)
+ {
+ if (num_vertices(g_in) == 0)
+ return;
+ typedef typename graph_traits<MutableGraph>::vertex_descriptor vertex_t;
+ std::vector<vertex_t> orig2copy(num_vertices(g_in));
+ typedef typename detail::choose_graph_copy<VertexListGraph>::type
+ copy_impl;
+ copy_impl::apply
+ (g_in, g_out,
+ detail::make_vertex_copier(g_in, g_out),
+ detail::make_edge_copier(g_in, g_out),
+ make_iterator_property_map(orig2copy.begin(),
+ get(vertex_index, g_in), orig2copy[0]),
+ get(vertex_index, g_in)
+ );
+ }
+
+ template <typename VertexListGraph, typename MutableGraph,
+ class P, class T, class R>
+ void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typename std::vector<T>::size_type n;
+ n = is_default_param(get_param(params, orig_to_copy_t()))
+ ? num_vertices(g_in) : 1;
+ if (n == 0)
+ return;
+ std::vector<BOOST_DEDUCED_TYPENAME graph_traits<MutableGraph>::vertex_descriptor>
+ orig2copy(n);
+
+ typedef typename detail::choose_graph_copy<VertexListGraph>::type
+ copy_impl;
+ copy_impl::apply
+ (g_in, g_out,
+ detail::choose_vertex_copier(get_param(params, vertex_copy_t()),
+ g_in, g_out),
+ detail::choose_edge_copier(get_param(params, edge_copy_t()),
+ g_in, g_out),
+ choose_param(get_param(params, orig_to_copy_t()),
+ make_iterator_property_map
+ (orig2copy.begin(),
+ choose_const_pmap(get_param(params, vertex_index),
+ g_in, vertex_index), orig2copy[0])),
+ choose_const_pmap(get_param(params, vertex_index), g_in, vertex_index)
+ );
+ }
+
+ namespace detail {
+
+ template <class NewGraph, class Copy2OrigIndexMap,
+ class CopyVertex, class CopyEdge>
+ struct graph_copy_visitor : public bfs_visitor<>
+ {
+ graph_copy_visitor(NewGraph& graph, Copy2OrigIndexMap c,
+ CopyVertex cv, CopyEdge ce)
+ : g_out(graph), orig2copy(c), copy_vertex(cv), copy_edge(ce) { }
+
+ template <class Vertex, class Graph>
+ void examine_vertex(Vertex u, const Graph& g_in) const {
+ typename graph_traits<NewGraph>::vertex_descriptor
+ new_u = add_vertex(g_out);
+ put(orig2copy, u, new_u);
+ copy_vertex(u, new_u);
+ }
+
+ template <class Edge, class Graph>
+ void examine_edge(Edge e, const Graph& g_in) const {
+ typename graph_traits<NewGraph>::edge_descriptor new_e;
+ bool inserted;
+ tie(new_e, inserted) = add_edge(get(orig2copy, source(e, g_in)),
+ get(orig2copy, target(e, g_in)),
+ g_out);
+ copy_edge(e, new_e);
+ }
+ private:
+ NewGraph& g_out;
+ Copy2OrigIndexMap orig2copy;
+ CopyVertex copy_vertex;
+ CopyEdge copy_edge;
+ };
+
+ template <typename Graph, typename MutableGraph,
+ typename CopyVertex, typename CopyEdge,
+ typename Orig2CopyVertexIndexMap, typename Params>
+ typename graph_traits<MutableGraph>::vertex_descriptor
+ copy_component_impl
+ (const Graph& g_in,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ MutableGraph& g_out,
+ CopyVertex copy_vertex, CopyEdge copy_edge,
+ Orig2CopyVertexIndexMap orig2copy,
+ const Params& params)
+ {
+ graph_copy_visitor<MutableGraph, Orig2CopyVertexIndexMap,
+ CopyVertex, CopyEdge> vis(g_out, orig2copy, copy_vertex, copy_edge);
+ breadth_first_search(g_in, src, params.visitor(vis));
+ return get(orig2copy, src);
+ }
+
+ } // namespace detail
+
+
+ // Copy all the vertices and edges of graph g_in that are reachable
+ // from the source vertex into graph g_out. Return the vertex
+ // in g_out that matches the source vertex of g_in.
+ template <typename IncidenceGraph, typename MutableGraph,
+ typename P, typename T, typename R>
+ typename graph_traits<MutableGraph>::vertex_descriptor
+ copy_component(IncidenceGraph& g_in,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor src,
+ MutableGraph& g_out,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typename std::vector<T>::size_type n;
+ n = is_default_param(get_param(params, orig_to_copy_t()))
+ ? num_vertices(g_in) : 1;
+ std::vector<typename graph_traits<IncidenceGraph>::vertex_descriptor>
+ orig2copy(n);
+
+ return detail::copy_component_impl
+ (g_in, src, g_out,
+ detail::choose_vertex_copier(get_param(params, vertex_copy_t()),
+ g_in, g_out),
+ detail::choose_edge_copier(get_param(params, edge_copy_t()),
+ g_in, g_out),
+ choose_param(get_param(params, orig_to_copy_t()),
+ make_iterator_property_map
+ (orig2copy.begin(),
+ choose_pmap(get_param(params, vertex_index),
+ g_in, vertex_index), orig2copy[0])),
+ params
+ );
+ }
+
+ template <typename IncidenceGraph, typename MutableGraph>
+ typename graph_traits<MutableGraph>::vertex_descriptor
+ copy_component(IncidenceGraph& g_in,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor src,
+ MutableGraph& g_out)
+ {
+ std::vector<typename graph_traits<IncidenceGraph>::vertex_descriptor>
+ orig2copy(num_vertices(g_in));
+
+ return detail::copy_component_impl
+ (g_in, src, g_out,
+ make_vertex_copier(g_in, g_out),
+ make_edge_copier(g_in, g_out),
+ make_iterator_property_map(orig2copy.begin(),
+ get(vertex_index, g_in), orig2copy[0]),
+ bgl_named_params<char,char>('x') // dummy param object
+ );
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_COPY_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/create_condensation_graph.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/create_condensation_graph.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,83 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_CREATE_CONDENSATION_GRAPH_HPP
+#define BOOST_CREATE_CONDENSATION_GRAPH_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map.hpp>
+
+namespace boost {
+
+ template <typename Graph, typename ComponentLists,
+ typename ComponentNumberMap,
+ typename CondensationGraph, typename EdgeMultiplicityMap>
+ void create_condensation_graph(const Graph& g,
+ const ComponentLists& components,
+ ComponentNumberMap component_number,
+ CondensationGraph& cg,
+ EdgeMultiplicityMap edge_mult_map)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex;
+ typedef typename graph_traits<Graph>::vertices_size_type size_type;
+ typedef typename graph_traits<CondensationGraph>::vertex_descriptor
+ cg_vertex;
+ std::vector<cg_vertex> to_cg_vertex(components.size());
+ for (size_type s = 0; s < components.size(); ++s)
+ to_cg_vertex[s] = add_vertex(cg);
+
+ for (size_type si = 0; si < components.size(); ++si) {
+ cg_vertex s = to_cg_vertex[si];
+ std::vector<cg_vertex> adj;
+ for (size_type i = 0; i < components[si].size(); ++i) {
+ vertex u = components[s][i];
+ typename graph_traits<Graph>::adjacency_iterator v, v_end;
+ for (tie(v, v_end) = adjacent_vertices(u, g); v != v_end; ++v) {
+ cg_vertex t = to_cg_vertex[component_number[*v]];
+ if (s != t) // Avoid loops in the condensation graph
+ adj.push_back(t);
+ }
+ }
+ std::sort(adj.begin(), adj.end());
+ if (! adj.empty()) {
+ size_type i = 0;
+ cg_vertex t = adj[i];
+ typename graph_traits<CondensationGraph>::edge_descriptor e;
+ bool inserted;
+ tie(e, inserted) = add_edge(s, t, cg);
+ put(edge_mult_map, e, 1);
+ ++i;
+ while (i < adj.size()) {
+ if (adj[i] == t)
+ put(edge_mult_map, e, get(edge_mult_map, e) + 1);
+ else {
+ t = adj[i];
+ tie(e, inserted) = add_edge(s, t, cg);
+ put(edge_mult_map, e, 1);
+ }
+ ++i;
+ }
+ }
+ }
+ }
+
+ template <typename Graph, typename ComponentLists,
+ typename ComponentNumberMap, typename CondensationGraph>
+ void create_condensation_graph(const Graph& g,
+ const ComponentLists& components,
+ ComponentNumberMap component_number,
+ CondensationGraph& cg)
+ {
+ create_condensation_graph(g, components, component_number, cg,
+ dummy_property_map());
+ }
+
+} // namespace boost
+
+#endif // BOOST_CREATE_CONDENSATION_GRAPH_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/cuthill_mckee_ordering.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/cuthill_mckee_ordering.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,190 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2004, 2005 Trustees of Indiana University
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek,
+// Doug Gregor, D. Kevin McGrath
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_GRAPH_CUTHILL_MCKEE_HPP
+#define BOOST_GRAPH_CUTHILL_MCKEE_HPP
+
+#include <boost/config.hpp>
+#include <boost/graph/detail/sparse_ordering.hpp>
+#include <algorithm>
+
+
+/*
+ (Reverse) Cuthill-McKee Algorithm for matrix reordering
+*/
+
+namespace boost {
+
+ namespace detail {
+
+
+
+ template < typename OutputIterator, typename Buffer, typename DegreeMap >
+ class bfs_rcm_visitor:public default_bfs_visitor
+ {
+ public:
+ bfs_rcm_visitor(OutputIterator *iter, Buffer *b, DegreeMap deg):
+ permutation(iter), Qptr(b), degree(deg) { }
+ template <class Vertex, class Graph>
+ void examine_vertex(Vertex u, Graph&) {
+ *(*permutation)++ = u;
+ index_begin = Qptr->size();
+ }
+ template <class Vertex, class Graph>
+ void finish_vertex(Vertex, Graph&) {
+ using std::sort;
+
+ typedef typename property_traits<DegreeMap>::value_type ds_type;
+
+ typedef indirect_cmp<DegreeMap, std::less<ds_type> > Compare;
+ Compare comp(degree);
+
+ sort(Qptr->begin()+index_begin, Qptr->end(), comp);
+ }
+ protected:
+ OutputIterator *permutation;
+ int index_begin;
+ Buffer *Qptr;
+ DegreeMap degree;
+ };
+
+ } // namespace detail
+
+
+ // Reverse Cuthill-McKee algorithm with a given starting Vertex.
+ //
+ // If user provides a reverse iterator, this will be a reverse-cuthill-mckee
+ // algorithm, otherwise it will be a standard CM algorithm
+
+ template <class Graph, class OutputIterator,
+ class ColorMap, class DegreeMap>
+ OutputIterator
+ cuthill_mckee_ordering(const Graph& g,
+ std::deque< typename
+ graph_traits<Graph>::vertex_descriptor > vertex_queue,
+ OutputIterator permutation,
+ ColorMap color, DegreeMap degree)
+ {
+
+ //create queue, visitor...don't forget namespaces!
+ typedef typename property_traits<DegreeMap>::value_type ds_type;
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename boost::sparse::sparse_ordering_queue<Vertex> queue;
+ typedef typename detail::bfs_rcm_visitor<OutputIterator, queue, DegreeMap> Visitor;
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+
+
+ queue Q;
+
+ //create a bfs_rcm_visitor as defined above
+ Visitor vis(&permutation, &Q, degree);
+
+ typename graph_traits<Graph>::vertex_iterator ui, ui_end;
+
+ // Copy degree to pseudo_degree
+ // initialize the color map
+ for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui){
+ put(color, *ui, Color::white());
+ }
+
+
+ while( !vertex_queue.empty() ) {
+ Vertex s = vertex_queue.front();
+ vertex_queue.pop_front();
+
+ //call BFS with visitor
+ breadth_first_visit(g, s, Q, vis, color);
+ }
+ return permutation;
+ }
+
+
+ // This is the case where only a single starting vertex is supplied.
+ template <class Graph, class OutputIterator,
+ class ColorMap, class DegreeMap>
+ OutputIterator
+ cuthill_mckee_ordering(const Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor s,
+ OutputIterator permutation,
+ ColorMap color, DegreeMap degree)
+ {
+
+ std::deque< typename graph_traits<Graph>::vertex_descriptor > vertex_queue;
+ vertex_queue.push_front( s );
+
+ return cuthill_mckee_ordering(g, vertex_queue, permutation, color, degree);
+
+ }
+
+
+ // This is the version of CM which selects its own starting vertex
+ template < class Graph, class OutputIterator,
+ class ColorMap, class DegreeMap>
+ OutputIterator
+ cuthill_mckee_ordering(const Graph& G, OutputIterator permutation,
+ ColorMap color, DegreeMap degree)
+ {
+ if (vertices(G).first == vertices(G).second)
+ return permutation;
+
+ typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename boost::graph_traits<Graph>::vertex_iterator VerIter;
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+
+ std::deque<Vertex> vertex_queue;
+
+ // Mark everything white
+ BGL_FORALL_VERTICES_T(v, G, Graph) put(color, v, Color::white());
+
+ // Find one vertex from each connected component
+ BGL_FORALL_VERTICES_T(v, G, Graph) {
+ if (get(color, v) == Color::white()) {
+ depth_first_visit(G, v, dfs_visitor<>(), color);
+ vertex_queue.push_back(v);
+ }
+ }
+
+ // Find starting nodes for all vertices
+ // TBD: How to do this with a directed graph?
+ for (typename std::deque<Vertex>::iterator i = vertex_queue.begin();
+ i != vertex_queue.end(); ++i)
+ *i = find_starting_node(G, *i, color, degree);
+
+ return cuthill_mckee_ordering(G, vertex_queue, permutation,
+ color, degree);
+ }
+
+ template<typename Graph, typename OutputIterator, typename VertexIndexMap>
+ OutputIterator
+ cuthill_mckee_ordering(const Graph& G, OutputIterator permutation,
+ VertexIndexMap index_map)
+ {
+ if (vertices(G).first == vertices(G).second)
+ return permutation;
+
+ typedef out_degree_property_map<Graph> DegreeMap;
+ std::vector<default_color_type> colors(num_vertices(G));
+ return cuthill_mckee_ordering(G, permutation,
+ make_iterator_property_map(&colors[0],
+ index_map,
+ colors[0]),
+ make_out_degree_map(G));
+ }
+
+ template<typename Graph, typename OutputIterator>
+ inline OutputIterator
+ cuthill_mckee_ordering(const Graph& G, OutputIterator permutation)
+ { return cuthill_mckee_ordering(G, permutation, get(vertex_index, G)); }
+} // namespace boost
+
+
+#endif // BOOST_GRAPH_CUTHILL_MCKEE_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/dag_shortest_paths.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/dag_shortest_paths.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,157 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_DAG_SHORTEST_PATHS_HPP
+#define BOOST_GRAPH_DAG_SHORTEST_PATHS_HPP
+
+#include <boost/graph/topological_sort.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+
+// single-source shortest paths for a Directed Acyclic Graph (DAG)
+
+namespace boost {
+
+ // Initalize distances and call depth first search
+ template <class VertexListGraph, class DijkstraVisitor,
+ class DistanceMap, class WeightMap, class ColorMap,
+ class PredecessorMap,
+ class Compare, class Combine,
+ class DistInf, class DistZero>
+ inline void
+ dag_shortest_paths
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ DistanceMap distance, WeightMap weight, ColorMap color,
+ PredecessorMap pred,
+ DijkstraVisitor vis, Compare compare, Combine combine,
+ DistInf inf, DistZero zero)
+ {
+ typedef typename graph_traits<VertexListGraph>::vertex_descriptor Vertex;
+ std::vector<Vertex> rev_topo_order;
+ rev_topo_order.reserve(num_vertices(g));
+
+ // Call 'depth_first_visit', not 'topological_sort', because we don't
+ // want to traverse the entire graph, only vertices reachable from 's',
+ // and 'topological_sort' will traverse everything. The logic below
+ // is the same as for 'topological_sort', only we call 'depth_first_visit'
+ // and 'topological_sort' calls 'depth_first_search'.
+ topo_sort_visitor<std::back_insert_iterator<std::vector<Vertex> > >
+ topo_visitor(std::back_inserter(rev_topo_order));
+ depth_first_visit(g, s, topo_visitor, color);
+
+ typename graph_traits<VertexListGraph>::vertex_iterator ui, ui_end;
+ for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
+ put(distance, *ui, inf);
+ put(pred, *ui, *ui);
+ }
+
+ put(distance, s, zero);
+ vis.discover_vertex(s, g);
+ typename std::vector<Vertex>::reverse_iterator i;
+ for (i = rev_topo_order.rbegin(); i != rev_topo_order.rend(); ++i) {
+ Vertex u = *i;
+ vis.examine_vertex(u, g);
+ typename graph_traits<VertexListGraph>::out_edge_iterator e, e_end;
+ for (tie(e, e_end) = out_edges(u, g); e != e_end; ++e) {
+ vis.discover_vertex(target(*e, g), g);
+ bool decreased = relax(*e, g, weight, pred, distance,
+ combine, compare);
+ if (decreased)
+ vis.edge_relaxed(*e, g);
+ else
+ vis.edge_not_relaxed(*e, g);
+ }
+ vis.finish_vertex(u, g);
+ }
+ }
+
+ namespace detail {
+
+ // Defaults are the same as Dijkstra's algorithm
+
+ // Handle Distance Compare, Combine, Inf and Zero defaults
+ template <class VertexListGraph, class DijkstraVisitor,
+ class DistanceMap, class WeightMap, class ColorMap,
+ class IndexMap, class Params>
+ inline void
+ dag_sp_dispatch2
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ DistanceMap distance, WeightMap weight, ColorMap color, IndexMap id,
+ DijkstraVisitor vis, const Params& params)
+ {
+ typedef typename property_traits<DistanceMap>::value_type D;
+ dummy_property_map p_map;
+ dag_shortest_paths
+ (g, s, distance, weight, color,
+ choose_param(get_param(params, vertex_predecessor), p_map),
+ vis,
+ choose_param(get_param(params, distance_compare_t()), std::less<D>()),
+ choose_param(get_param(params, distance_combine_t()), closed_plus<D>()),
+ choose_param(get_param(params, distance_inf_t()),
+ (std::numeric_limits<D>::max)()),
+ choose_param(get_param(params, distance_zero_t()),
+ D()));
+ }
+
+ // Handle DistanceMap and ColorMap defaults
+ template <class VertexListGraph, class DijkstraVisitor,
+ class DistanceMap, class WeightMap, class ColorMap,
+ class IndexMap, class Params>
+ inline void
+ dag_sp_dispatch1
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ DistanceMap distance, WeightMap weight, ColorMap color, IndexMap id,
+ DijkstraVisitor vis, const Params& params)
+ {
+ typedef typename property_traits<WeightMap>::value_type T;
+ typename std::vector<T>::size_type n;
+ n = is_default_param(distance) ? num_vertices(g) : 1;
+ std::vector<T> distance_map(n);
+ n = is_default_param(color) ? num_vertices(g) : 1;
+ std::vector<default_color_type> color_map(n);
+
+ dag_sp_dispatch2
+ (g, s,
+ choose_param(distance,
+ make_iterator_property_map(distance_map.begin(), id,
+ distance_map[0])),
+ weight,
+ choose_param(color,
+ make_iterator_property_map(color_map.begin(), id,
+ color_map[0])),
+ id, vis, params);
+ }
+
+ } // namespace detail
+
+ template <class VertexListGraph, class Param, class Tag, class Rest>
+ inline void
+ dag_shortest_paths
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ const bgl_named_params<Param,Tag,Rest>& params)
+ {
+ // assert that the graph is directed...
+ null_visitor null_vis;
+ detail::dag_sp_dispatch1
+ (g, s,
+ get_param(params, vertex_distance),
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ get_param(params, vertex_color),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
+ choose_param(get_param(params, graph_visitor),
+ make_dijkstra_visitor(null_vis)),
+ params);
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_DAG_SHORTEST_PATHS_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/depth_first_search.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/depth_first_search.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,365 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2003 Bruce Barr
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+// Nonrecursive implementation of depth_first_visit_impl submitted by
+// Bruce Barr, schmoost <at> yahoo.com, May/June 2003.
+#ifndef BOOST_GRAPH_RECURSIVE_DFS_HPP
+#define BOOST_GRAPH_RECURSIVE_DFS_HPP
+
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/named_function_params.hpp>
+
+#include <boost/ref.hpp>
+#include <boost/implicit_cast.hpp>
+
+#include <vector>
+#include <utility>
+
+namespace boost {
+
+ template <class Visitor, class Graph>
+ class DFSVisitorConcept {
+ public:
+ void constraints() {
+ function_requires< CopyConstructibleConcept<Visitor> >();
+ vis.initialize_vertex(u, g);
+ vis.start_vertex(u, g);
+ vis.discover_vertex(u, g);
+ vis.examine_edge(e, g);
+ vis.tree_edge(e, g);
+ vis.back_edge(e, g);
+ vis.forward_or_cross_edge(e, g);
+ vis.finish_vertex(u, g);
+ }
+ private:
+ Visitor vis;
+ Graph g;
+ typename graph_traits<Graph>::vertex_descriptor u;
+ typename graph_traits<Graph>::edge_descriptor e;
+ };
+
+ namespace detail {
+
+ struct nontruth2 {
+ template<class T, class T2>
+ bool operator()(const T&, const T2&) const { return false; }
+ };
+
+
+// Define BOOST_RECURSIVE_DFS to use older, recursive version.
+// It is retained for a while in order to perform performance
+// comparison.
+#ifndef BOOST_RECURSIVE_DFS
+
+ // If the vertex u and the iterators ei and ei_end are thought of as the
+ // context of the algorithm, each push and pop from the stack could
+ // be thought of as a context shift.
+ // Each pass through "while (ei != ei_end)" may refer to the out-edges of
+ // an entirely different vertex, because the context of the algorithm
+ // shifts every time a white adjacent vertex is discovered.
+ // The corresponding context shift back from the adjacent vertex occurs
+ // after all of its out-edges have been examined.
+ //
+ // See http://lists.boost.org/MailArchives/boost/msg48752.php for FAQ.
+
+ template <class IncidenceGraph, class DFSVisitor, class ColorMap,
+ class TerminatorFunc>
+ void depth_first_visit_impl
+ (const IncidenceGraph& g,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor u,
+ DFSVisitor& vis,
+ ColorMap color, TerminatorFunc func = TerminatorFunc())
+ {
+ function_requires<IncidenceGraphConcept<IncidenceGraph> >();
+ function_requires<DFSVisitorConcept<DFSVisitor, IncidenceGraph> >();
+ typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
+ function_requires< ReadWritePropertyMapConcept<ColorMap, Vertex> >();
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ function_requires< ColorValueConcept<ColorValue> >();
+ typedef color_traits<ColorValue> Color;
+ typedef typename graph_traits<IncidenceGraph>::out_edge_iterator Iter;
+ typedef std::pair<Vertex, std::pair<Iter, Iter> > VertexInfo;
+
+ Iter ei, ei_end;
+ std::vector<VertexInfo> stack;
+
+ // Possible optimization for vector
+ //stack.reserve(num_vertices(g));
+
+ typedef typename unwrap_reference<TerminatorFunc>::type TF;
+
+ put(color, u, Color::gray());
+ vis.discover_vertex(u, g);
+ tie(ei, ei_end) = out_edges(u, g);
+ // Variable is needed to workaround a borland bug.
+ TF& fn = static_cast<TF&>(func);
+ if (fn(u, g)) {
+ // If this vertex terminates the search, we push empty range
+ stack.push_back(std::make_pair(u, std::make_pair(ei_end, ei_end)));
+ } else {
+ stack.push_back(std::make_pair(u, std::make_pair(ei, ei_end)));
+ }
+ while (!stack.empty()) {
+ VertexInfo& back = stack.back();
+ u = back.first;
+ tie(ei, ei_end) = back.second;
+ stack.pop_back();
+ while (ei != ei_end) {
+ Vertex v = target(*ei, g);
+ vis.examine_edge(*ei, g);
+ ColorValue v_color = get(color, v);
+ if (v_color == Color::white()) {
+ vis.tree_edge(*ei, g);
+ stack.push_back(std::make_pair(u, std::make_pair(++ei, ei_end)));
+ u = v;
+ put(color, u, Color::gray());
+ vis.discover_vertex(u, g);
+ tie(ei, ei_end) = out_edges(u, g);
+ if (fn(u, g)) {
+ ei = ei_end;
+ }
+ } else if (v_color == Color::gray()) {
+ vis.back_edge(*ei, g);
+ ++ei;
+ } else {
+ vis.forward_or_cross_edge(*ei, g);
+ ++ei;
+ }
+ }
+ put(color, u, Color::black());
+ vis.finish_vertex(u, g);
+ }
+ }
+
+#else // BOOST_RECURSIVE_DFS is defined
+
+ template <class IncidenceGraph, class DFSVisitor, class ColorMap,
+ class TerminatorFunc>
+ void depth_first_visit_impl
+ (const IncidenceGraph& g,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor u,
+ DFSVisitor& vis, // pass-by-reference here, important!
+ ColorMap color, TerminatorFunc func)
+ {
+ function_requires<IncidenceGraphConcept<IncidenceGraph> >();
+ function_requires<DFSVisitorConcept<DFSVisitor, IncidenceGraph> >();
+ typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
+ function_requires< ReadWritePropertyMapConcept<ColorMap, Vertex> >();
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ function_requires< ColorValueConcept<ColorValue> >();
+ typedef color_traits<ColorValue> Color;
+ typename graph_traits<IncidenceGraph>::out_edge_iterator ei, ei_end;
+
+ put(color, u, Color::gray()); vis.discover_vertex(u, g);
+
+ typedef typename unwrap_reference<TerminatorFunc>::type TF;
+ // Variable is needed to workaround a borland bug.
+ TF& fn = static_cast<TF&>(func);
+ if (!fn(u, g))
+ for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
+ Vertex v = target(*ei, g); vis.examine_edge(*ei, g);
+ ColorValue v_color = get(color, v);
+ if (v_color == Color::white()) { vis.tree_edge(*ei, g);
+ depth_first_visit_impl(g, v, vis, color, func);
+ } else if (v_color == Color::gray()) vis.back_edge(*ei, g);
+ else vis.forward_or_cross_edge(*ei, g);
+ }
+ put(color, u, Color::black()); vis.finish_vertex(u, g);
+ }
+
+#endif
+
+ } // namespace detail
+
+ template <class VertexListGraph, class DFSVisitor, class ColorMap>
+ void
+ depth_first_search(const VertexListGraph& g, DFSVisitor vis, ColorMap color,
+ typename graph_traits<VertexListGraph>::vertex_descriptor start_vertex)
+ {
+ typedef typename graph_traits<VertexListGraph>::vertex_descriptor Vertex;
+ function_requires<DFSVisitorConcept<DFSVisitor, VertexListGraph> >();
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+
+ typename graph_traits<VertexListGraph>::vertex_iterator ui, ui_end;
+ for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
+ put(color, *ui, Color::white()); vis.initialize_vertex(*ui, g);
+ }
+
+ if (start_vertex != implicit_cast<Vertex>(*vertices(g).first)){ vis.start_vertex(start_vertex, g);
+ detail::depth_first_visit_impl(g, start_vertex, vis, color,
+ detail::nontruth2());
+ }
+
+ for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
+ ColorValue u_color = get(color, *ui);
+ if (u_color == Color::white()) { vis.start_vertex(*ui, g);
+ detail::depth_first_visit_impl(g, *ui, vis, color, detail::nontruth2());
+ }
+ }
+ }
+
+ template <class VertexListGraph, class DFSVisitor, class ColorMap>
+ void
+ depth_first_search(const VertexListGraph& g, DFSVisitor vis, ColorMap color)
+ {
+ if (vertices(g).first == vertices(g).second)
+ return;
+
+ depth_first_search(g, vis, color, *vertices(g).first);
+ }
+
+ namespace detail {
+ template <class ColorMap>
+ struct dfs_dispatch {
+
+ template <class VertexListGraph, class Vertex, class DFSVisitor,
+ class P, class T, class R>
+ static void
+ apply(const VertexListGraph& g, DFSVisitor vis, Vertex start_vertex,
+ const bgl_named_params<P, T, R>&,
+ ColorMap color)
+ {
+ depth_first_search(g, vis, color, start_vertex);
+ }
+ };
+
+ template <>
+ struct dfs_dispatch<detail::error_property_not_found> {
+ template <class VertexListGraph, class Vertex, class DFSVisitor,
+ class P, class T, class R>
+ static void
+ apply(const VertexListGraph& g, DFSVisitor vis, Vertex start_vertex,
+ const bgl_named_params<P, T, R>& params,
+ detail::error_property_not_found)
+ {
+ std::vector<default_color_type> color_vec(num_vertices(g));
+ default_color_type c = white_color; // avoid warning about un-init
+ depth_first_search
+ (g, vis, make_iterator_property_map
+ (color_vec.begin(),
+ choose_const_pmap(get_param(params, vertex_index),
+ g, vertex_index), c),
+ start_vertex);
+ }
+ };
+ } // namespace detail
+
+
+ template <class Visitors = null_visitor>
+ class dfs_visitor {
+ public:
+ dfs_visitor() { }
+ dfs_visitor(Visitors vis) : m_vis(vis) { }
+
+ template <class Vertex, class Graph>
+ void initialize_vertex(Vertex u, const Graph& g) {
+ invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex());
+ }
+ template <class Vertex, class Graph>
+ void start_vertex(Vertex u, const Graph& g) {
+ invoke_visitors(m_vis, u, g, ::boost::on_start_vertex());
+ }
+ template <class Vertex, class Graph>
+ void discover_vertex(Vertex u, const Graph& g) {
+ invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex());
+ }
+ template <class Edge, class Graph>
+ void examine_edge(Edge u, const Graph& g) {
+ invoke_visitors(m_vis, u, g, ::boost::on_examine_edge());
+ }
+ template <class Edge, class Graph>
+ void tree_edge(Edge u, const Graph& g) {
+ invoke_visitors(m_vis, u, g, ::boost::on_tree_edge());
+ }
+ template <class Edge, class Graph>
+ void back_edge(Edge u, const Graph& g) {
+ invoke_visitors(m_vis, u, g, ::boost::on_back_edge());
+ }
+ template <class Edge, class Graph>
+ void forward_or_cross_edge(Edge u, const Graph& g) {
+ invoke_visitors(m_vis, u, g, ::boost::on_forward_or_cross_edge());
+ }
+ template <class Vertex, class Graph>
+ void finish_vertex(Vertex u, const Graph& g) {
+ invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex());
+ }
+
+ BOOST_GRAPH_EVENT_STUB(on_initialize_vertex,dfs)
+ BOOST_GRAPH_EVENT_STUB(on_start_vertex,dfs)
+ BOOST_GRAPH_EVENT_STUB(on_discover_vertex,dfs)
+ BOOST_GRAPH_EVENT_STUB(on_examine_edge,dfs)
+ BOOST_GRAPH_EVENT_STUB(on_tree_edge,dfs)
+ BOOST_GRAPH_EVENT_STUB(on_back_edge,dfs)
+ BOOST_GRAPH_EVENT_STUB(on_forward_or_cross_edge,dfs)
+ BOOST_GRAPH_EVENT_STUB(on_finish_vertex,dfs)
+
+ protected:
+ Visitors m_vis;
+ };
+ template <class Visitors>
+ dfs_visitor<Visitors>
+ make_dfs_visitor(Visitors vis) {
+ return dfs_visitor<Visitors>(vis);
+ }
+ typedef dfs_visitor<> default_dfs_visitor;
+
+
+ // Named Parameter Variant
+ template <class VertexListGraph, class P, class T, class R>
+ void
+ depth_first_search(const VertexListGraph& g,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef typename property_value< bgl_named_params<P, T, R>,
+ vertex_color_t>::type C;
+ if (vertices(g).first == vertices(g).second)
+ return;
+ detail::dfs_dispatch<C>::apply
+ (g,
+ choose_param(get_param(params, graph_visitor),
+ make_dfs_visitor(null_visitor())),
+ choose_param(get_param(params, root_vertex_t()),
+ *vertices(g).first),
+ params,
+ get_param(params, vertex_color)
+ );
+ }
+
+ template <class IncidenceGraph, class DFSVisitor, class ColorMap>
+ void depth_first_visit
+ (const IncidenceGraph& g,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor u,
+ DFSVisitor vis, ColorMap color)
+ {
+ vis.start_vertex(u, g);
+ detail::depth_first_visit_impl(g, u, vis, color, detail::nontruth2());
+ }
+
+ template <class IncidenceGraph, class DFSVisitor, class ColorMap,
+ class TerminatorFunc>
+ void depth_first_visit
+ (const IncidenceGraph& g,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor u,
+ DFSVisitor vis, ColorMap color, TerminatorFunc func = TerminatorFunc())
+ {
+ vis.start_vertex(u, g);
+ detail::depth_first_visit_impl(g, u, vis, color, func);
+ }
+
+
+} // namespace boost
+
+
+#endif
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/adj_list_edge_iterator.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/adj_list_edge_iterator.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,117 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP
+#define BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP
+
+#include <iterator>
+#include <utility>
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
+# define BOOST_GRAPH_NO_OPTIONAL
+#endif
+
+#ifdef BOOST_GRAPH_NO_OPTIONAL
+# define BOOST_GRAPH_MEMBER .
+#else
+# define BOOST_GRAPH_MEMBER ->
+# include <boost/optional.hpp>
+#endif // ndef BOOST_GRAPH_NO_OPTIONAL
+
+namespace boost {
+
+ namespace detail {
+
+ template <class VertexIterator, class OutEdgeIterator, class Graph>
+ class adj_list_edge_iterator {
+ typedef adj_list_edge_iterator self;
+ public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef typename OutEdgeIterator::value_type value_type;
+ typedef typename OutEdgeIterator::reference reference;
+ typedef typename OutEdgeIterator::pointer pointer;
+ typedef typename OutEdgeIterator::difference_type difference_type;
+ typedef difference_type distance_type;
+
+ inline adj_list_edge_iterator() {}
+
+ inline adj_list_edge_iterator(const self& x)
+ : vBegin(x.vBegin), vCurr(x.vCurr), vEnd(x.vEnd),
+ edges(x.edges), m_g(x.m_g) { }
+
+ template <class G>
+ inline adj_list_edge_iterator(VertexIterator b,
+ VertexIterator c,
+ VertexIterator e,
+ const G& g)
+ : vBegin(b), vCurr(c), vEnd(e), m_g(&g) {
+ if ( vCurr != vEnd ) {
+ while ( vCurr != vEnd && out_degree(*vCurr, *m_g) == 0 )
+ ++vCurr;
+ if ( vCurr != vEnd )
+ edges = out_edges(*vCurr, *m_g);
+ }
+ }
+
+ /*Note:
+ In the directed graph cases, it is fine.
+ For undirected graphs, one edge go through twice.
+ */
+ inline self& operator++() {
+ ++edges BOOST_GRAPH_MEMBER first;
+ if (edges BOOST_GRAPH_MEMBER first == edges BOOST_GRAPH_MEMBER second)
+ {
+ ++vCurr;
+ while ( vCurr != vEnd && out_degree(*vCurr, *m_g) == 0 )
+ ++vCurr;
+ if ( vCurr != vEnd )
+ edges = out_edges(*vCurr, *m_g);
+ }
+ return *this;
+ }
+ inline self operator++(int) {
+ self tmp = *this;
+ ++(*this);
+ return tmp;
+ }
+ inline value_type operator*() const
+ { return *edges BOOST_GRAPH_MEMBER first; }
+ inline bool operator==(const self& x) const {
+ return vCurr == x.vCurr
+ && (vCurr == vEnd
+ || edges BOOST_GRAPH_MEMBER first == x.edges BOOST_GRAPH_MEMBER first);
+ }
+ inline bool operator!=(const self& x) const {
+ return vCurr != x.vCurr
+ || (vCurr != vEnd
+ && edges BOOST_GRAPH_MEMBER first != x.edges BOOST_GRAPH_MEMBER first);
+ }
+ protected:
+ VertexIterator vBegin;
+ VertexIterator vCurr;
+ VertexIterator vEnd;
+
+#ifdef BOOST_GRAPH_NO_OPTIONAL
+ std::pair<OutEdgeIterator, OutEdgeIterator> edges;
+#else
+ boost::optional<std::pair<OutEdgeIterator, OutEdgeIterator> >
+ edges;
+#endif // ndef BOOST_GRAPH_NO_OPTIONAL
+ const Graph* m_g;
+ };
+
+ } // namespace detail
+
+}
+
+#undef BOOST_GRAPH_MEMBER
+
+#endif // BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/adjacency_list.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/adjacency_list.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,2844 @@
+// -*- c++ -*-
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_DETAIL_ADJACENCY_LIST_HPP
+#define BOOST_GRAPH_DETAIL_ADJACENCY_LIST_HPP
+
+#include <map> // for vertex_map in copy_impl
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/operators.hpp>
+#include <boost/property_map.hpp>
+#include <boost/pending/integer_range.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <memory>
+#include <algorithm>
+#include <boost/limits.hpp>
+
+#include <boost/iterator/iterator_adaptor.hpp>
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/pending/container_traits.hpp>
+#include <boost/graph/detail/adj_list_edge_iterator.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/pending/property.hpp>
+#include <boost/graph/adjacency_iterator.hpp>
+#include <boost/static_assert.hpp>
+
+// Symbol truncation problems with MSVC, trying to shorten names.
+#define stored_edge se_
+#define stored_edge_property sep_
+#define stored_edge_iter sei_
+
+/*
+ Outline for this file:
+
+ out_edge_iterator and in_edge_iterator implementation
+ edge_iterator for undirected graph
+ stored edge types (these object live in the out-edge/in-edge lists)
+ directed edges helper class
+ directed graph helper class
+ undirected graph helper class
+ bidirectional graph helper class
+ bidirectional graph helper class (without edge properties)
+ bidirectional graph helper class (with edge properties)
+ adjacency_list helper class
+ adj_list_impl class
+ vec_adj_list_impl class
+ adj_list_gen class
+ vertex property map
+ edge property map
+
+
+ Note: it would be nice to merge some of the undirected and
+ bidirectional code... it is awful similar.
+ */
+
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+// Stay out of the way of the concept checking class
+# define Graph Graph_
+#endif
+
+namespace boost {
+
+ namespace detail {
+
+ template <typename DirectedS>
+ struct directed_category_traits {
+ typedef directed_tag directed_category;
+ };
+
+ template <>
+ struct directed_category_traits<directedS> {
+ typedef directed_tag directed_category;
+ };
+ template <>
+ struct directed_category_traits<undirectedS> {
+ typedef undirected_tag directed_category;
+ };
+ template <>
+ struct directed_category_traits<bidirectionalS> {
+ typedef bidirectional_tag directed_category;
+ };
+
+ template <class Vertex>
+ struct target_is {
+ target_is(const Vertex& v) : m_target(v) { }
+ template <class StoredEdge>
+ bool operator()(const StoredEdge& e) const {
+ return e.get_target() == m_target;
+ }
+ Vertex m_target;
+ };
+
+ // O(E/V)
+ template <class EdgeList, class vertex_descriptor>
+ void erase_from_incidence_list(EdgeList& el, vertex_descriptor v,
+ allow_parallel_edge_tag)
+ {
+ boost::graph_detail::erase_if(el, detail::target_is<vertex_descriptor>(v));
+ }
+ // O(log(E/V))
+ template <class EdgeList, class vertex_descriptor>
+ void erase_from_incidence_list(EdgeList& el, vertex_descriptor v,
+ disallow_parallel_edge_tag)
+ {
+ typedef typename EdgeList::value_type StoredEdge;
+ el.erase(StoredEdge(v));
+ }
+
+ //=========================================================================
+ // Out-Edge and In-Edge Iterator Implementation
+
+ template <class BaseIter, class VertexDescriptor, class EdgeDescriptor, class Difference>
+ struct out_edge_iter
+ : iterator_adaptor<
+ out_edge_iter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>
+ , BaseIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , Difference
+ >
+ {
+ typedef iterator_adaptor<
+ out_edge_iter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>
+ , BaseIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , Difference
+ > super_t;
+
+ inline out_edge_iter() { }
+ inline out_edge_iter(const BaseIter& i, const VertexDescriptor& src)
+ : super_t(i), m_src(src) { }
+
+ inline EdgeDescriptor
+ dereference() const
+ {
+ return EdgeDescriptor(m_src, (*this->base()).get_target(),
+ &(*this->base()).get_property());
+ }
+ VertexDescriptor m_src;
+ };
+
+ template <class BaseIter, class VertexDescriptor, class EdgeDescriptor, class Difference>
+ struct in_edge_iter
+ : iterator_adaptor<
+ in_edge_iter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>
+ , BaseIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , Difference
+ >
+ {
+ typedef iterator_adaptor<
+ in_edge_iter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>
+ , BaseIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , Difference
+ > super_t;
+
+ inline in_edge_iter() { }
+ inline in_edge_iter(const BaseIter& i, const VertexDescriptor& src)
+ : super_t(i), m_src(src) { }
+
+ inline EdgeDescriptor
+ dereference() const
+ {
+ return EdgeDescriptor((*this->base()).get_target(), m_src,
+ &this->base()->get_property());
+ }
+ VertexDescriptor m_src;
+ };
+
+ //=========================================================================
+ // Undirected Edge Iterator Implementation
+
+ template <class EdgeIter, class EdgeDescriptor, class Difference>
+ struct undirected_edge_iter
+ : iterator_adaptor<
+ undirected_edge_iter<EdgeIter, EdgeDescriptor, Difference>
+ , EdgeIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , Difference
+ >
+ {
+ typedef iterator_adaptor<
+ undirected_edge_iter<EdgeIter, EdgeDescriptor, Difference>
+ , EdgeIter
+ , EdgeDescriptor
+ , use_default
+ , EdgeDescriptor
+ , Difference
+ > super_t;
+
+ undirected_edge_iter() {}
+
+ explicit undirected_edge_iter(EdgeIter i)
+ : super_t(i) {}
+
+ inline EdgeDescriptor
+ dereference() const {
+ return EdgeDescriptor(
+ (*this->base()).m_source
+ , (*this->base()).m_target
+ , &this->base()->get_property());
+ }
+ };
+
+ //=========================================================================
+ // Edge Storage Types (stored in the out-edge/in-edge lists)
+
+ template <class Vertex>
+ class stored_edge
+ : public boost::equality_comparable1< stored_edge<Vertex>,
+ boost::less_than_comparable1< stored_edge<Vertex> > >
+ {
+ public:
+ typedef no_property property_type;
+ inline stored_edge() { }
+ inline stored_edge(Vertex target, const no_property& = no_property())
+ : m_target(target) { }
+ // Need to write this explicitly so stored_edge_property can
+ // invoke Base::operator= (at least, for SGI MIPSPro compiler)
+ inline stored_edge& operator=(const stored_edge& x) {
+ m_target = x.m_target;
+ return *this;
+ }
+ inline Vertex& get_target() const { return m_target; }
+ inline const no_property& get_property() const { return s_prop; }
+ inline bool operator==(const stored_edge& x) const
+ { return m_target == x.get_target(); }
+ inline bool operator<(const stored_edge& x) const
+ { return m_target < x.get_target(); }
+ //protected: need to add hash<> as a friend
+ static no_property s_prop;
+ // Sometimes target not used as key in the set, and in that case
+ // it is ok to change the target.
+ mutable Vertex m_target;
+ };
+ template <class Vertex>
+ no_property stored_edge<Vertex>::s_prop;
+
+ template <class Vertex, class Property>
+ class stored_edge_property : public stored_edge<Vertex> {
+ typedef stored_edge_property self;
+ typedef stored_edge<Vertex> Base;
+ public:
+ typedef Property property_type;
+ inline stored_edge_property() { }
+ inline stored_edge_property(Vertex target,
+ const Property& p = Property())
+ : stored_edge<Vertex>(target), m_property(new Property(p)) { }
+ stored_edge_property(const self& x)
+ : Base(x), m_property(const_cast<self&>(x).m_property) { }
+ self& operator=(const self& x) {
+ Base::operator=(x);
+ m_property = const_cast<self&>(x).m_property;
+ return *this;
+ }
+ inline Property& get_property() { return *m_property; }
+ inline const Property& get_property() const { return *m_property; }
+ protected:
+ // Holding the property by-value causes edge-descriptor
+ // invalidation for add_edge() with EdgeList=vecS. Instead we
+ // hold a pointer to the property. std::auto_ptr is not
+ // a perfect fit for the job, but it is darn close.
+ std::auto_ptr<Property> m_property;
+ };
+
+
+ template <class Vertex, class Iter, class Property>
+ class stored_edge_iter
+ : public stored_edge<Vertex>
+ {
+ public:
+ typedef Property property_type;
+ inline stored_edge_iter() { }
+ inline stored_edge_iter(Vertex v)
+ : stored_edge<Vertex>(v) { }
+ inline stored_edge_iter(Vertex v, Iter i, void* = 0)
+ : stored_edge<Vertex>(v), m_iter(i) { }
+ inline Property& get_property() { return m_iter->get_property(); }
+ inline const Property& get_property() const {
+ return m_iter->get_property();
+ }
+ inline Iter get_iter() const { return m_iter; }
+ protected:
+ Iter m_iter;
+ };
+
+ // For when the EdgeList is a std::vector.
+ // Want to make the iterator stable, so use an offset
+ // instead of an iterator into a std::vector
+ template <class Vertex, class EdgeVec, class Property>
+ class stored_ra_edge_iter
+ : public stored_edge<Vertex>
+ {
+ typedef typename EdgeVec::iterator Iter;
+ public:
+ typedef Property property_type;
+ inline stored_ra_edge_iter() { }
+ inline stored_ra_edge_iter(Vertex v, Iter i = Iter(),
+ EdgeVec* edge_vec = 0)
+ : stored_edge<Vertex>(v), m_i(i - edge_vec->begin()), m_vec(edge_vec){ }
+ inline Property& get_property() { return (*m_vec)[m_i].get_property(); }
+ inline const Property& get_property() const {
+ return (*m_vec)[m_i].get_property();
+ }
+ inline Iter get_iter() const { return m_vec->begin() + m_i; }
+ protected:
+ std::size_t m_i;
+ EdgeVec* m_vec;
+ };
+
+ } // namespace detail
+
+ template <class Tag, class Vertex, class Property>
+ const typename property_value<Property,Tag>::type&
+ get(Tag property_tag,
+ const detail::stored_edge_property<Vertex, Property>& e)
+ {
+ return get_property_value(e.get_property(), property_tag);
+ }
+
+ template <class Tag, class Vertex, class Iter, class Property>
+ const typename property_value<Property,Tag>::type&
+ get(Tag property_tag,
+ const detail::stored_edge_iter<Vertex, Iter, Property>& e)
+ {
+ return get_property_value(e.get_property(), property_tag);
+ }
+
+ template <class Tag, class Vertex, class EdgeVec, class Property>
+ const typename property_value<Property,Tag>::type&
+ get(Tag property_tag,
+ const detail::stored_ra_edge_iter<Vertex, EdgeVec, Property>& e)
+ {
+ return get_property_value(e.get_property(), property_tag);
+ }
+
+ //=========================================================================
+ // Directed Edges Helper Class
+
+ namespace detail {
+
+ // O(E/V)
+ template <class edge_descriptor, class EdgeList, class StoredProperty>
+ inline void
+ remove_directed_edge_dispatch(edge_descriptor, EdgeList& el,
+ StoredProperty& p)
+ {
+ for (typename EdgeList::iterator i = el.begin();
+ i != el.end(); ++i)
+ if (&(*i).get_property() == &p) {
+ el.erase(i);
+ return;
+ }
+ }
+
+ template <class incidence_iterator, class EdgeList, class Predicate>
+ inline void
+ remove_directed_edge_if_dispatch(incidence_iterator first,
+ incidence_iterator last,
+ EdgeList& el, Predicate pred,
+ boost::allow_parallel_edge_tag)
+ {
+ // remove_if
+ while (first != last && !pred(*first))
+ ++first;
+ incidence_iterator i = first;
+ if (first != last)
+ for (; i != last; ++i)
+ if (!pred(*i)) {
+ *first.base() = *i.base();
+ ++first;
+ }
+ el.erase(first.base(), el.end());
+ }
+ template <class incidence_iterator, class EdgeList, class Predicate>
+ inline void
+ remove_directed_edge_if_dispatch(incidence_iterator first,
+ incidence_iterator last,
+ EdgeList& el,
+ Predicate pred,
+ boost::disallow_parallel_edge_tag)
+ {
+ for (incidence_iterator next = first;
+ first != last; first = next) {
+ ++next;
+ if (pred(*first))
+ el.erase( first.base() );
+ }
+ }
+
+ template <class PropT, class Graph, class incidence_iterator,
+ class EdgeList, class Predicate>
+ inline void
+ undirected_remove_out_edge_if_dispatch(Graph& g,
+ incidence_iterator first,
+ incidence_iterator last,
+ EdgeList& el, Predicate pred,
+ boost::allow_parallel_edge_tag)
+ {
+ typedef typename Graph::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ // remove_if
+ while (first != last && !pred(*first))
+ ++first;
+ incidence_iterator i = first;
+ bool self_loop_removed = false;
+ if (first != last)
+ for (; i != last; ++i) {
+ if (self_loop_removed) {
+ /* With self loops, the descriptor will show up
+ * twice. The first time it will be removed, and now it
+ * will be skipped.
+ */
+ self_loop_removed = false;
+ }
+ else if (!pred(*i)) {
+ *first.base() = *i.base();
+ ++first;
+ } else {
+ if (source(*i, g) == target(*i, g)) self_loop_removed = true;
+ else {
+ // Remove the edge from the target
+ detail::remove_directed_edge_dispatch
+ (*i,
+ g.out_edge_list(target(*i, g)),
+ *(PropT*)(*i).get_property());
+ }
+
+ // Erase the edge property
+ g.m_edges.erase( (*i.base()).get_iter() );
+ }
+ }
+ el.erase(first.base(), el.end());
+ }
+ template <class PropT, class Graph, class incidence_iterator,
+ class EdgeList, class Predicate>
+ inline void
+ undirected_remove_out_edge_if_dispatch(Graph& g,
+ incidence_iterator first,
+ incidence_iterator last,
+ EdgeList& el,
+ Predicate pred,
+ boost::disallow_parallel_edge_tag)
+ {
+ typedef typename Graph::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ for (incidence_iterator next = first;
+ first != last; first = next) {
+ ++next;
+ if (pred(*first)) {
+ if (source(*first, g) != target(*first, g)) {
+ // Remove the edge from the target
+ detail::remove_directed_edge_dispatch
+ (*first,
+ g.out_edge_list(target(*first, g)),
+ *(PropT*)(*first).get_property());
+ }
+
+ // Erase the edge property
+ g.m_edges.erase( (*first.base()).get_iter() );
+
+ // Erase the edge in the source
+ el.erase( first.base() );
+ }
+ }
+ }
+
+ // O(E/V)
+ template <class edge_descriptor, class EdgeList, class StoredProperty>
+ inline void
+ remove_directed_edge_dispatch(edge_descriptor e, EdgeList& el,
+ no_property&)
+ {
+ for (typename EdgeList::iterator i = el.begin();
+ i != el.end(); ++i)
+ if ((*i).get_target() == e.m_target) {
+ el.erase(i);
+ return;
+ }
+ }
+
+ } // namespace detail
+
+ template <class Config>
+ struct directed_edges_helper {
+
+ // Placement of these overloaded remove_edge() functions
+ // inside the class avoids a VC++ bug.
+
+ // O(E/V)
+ inline void
+ remove_edge(typename Config::edge_descriptor e)
+ {
+ typedef typename Config::graph_type graph_type;
+ graph_type& g = static_cast<graph_type&>(*this);
+ typename Config::OutEdgeList& el = g.out_edge_list(source(e, g));
+ typedef typename Config::OutEdgeList::value_type::property_type PType;
+ detail::remove_directed_edge_dispatch(e, el,
+ *(PType*)e.get_property());
+ }
+
+ // O(1)
+ inline void
+ remove_edge(typename Config::out_edge_iterator iter)
+ {
+ typedef typename Config::graph_type graph_type;
+ graph_type& g = static_cast<graph_type&>(*this);
+ typename Config::edge_descriptor e = *iter;
+ typename Config::OutEdgeList& el = g.out_edge_list(source(e, g));
+ el.erase(iter.base());
+ }
+
+ };
+
+ // O(1)
+ template <class Config>
+ inline std::pair<typename Config::edge_iterator,
+ typename Config::edge_iterator>
+ edges(const directed_edges_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::edge_iterator edge_iterator;
+ const graph_type& cg = static_cast<const graph_type&>(g_);
+ graph_type& g = const_cast<graph_type&>(cg);
+ return std::make_pair( edge_iterator(g.vertex_set().begin(),
+ g.vertex_set().begin(),
+ g.vertex_set().end(), g),
+ edge_iterator(g.vertex_set().begin(),
+ g.vertex_set().end(),
+ g.vertex_set().end(), g) );
+ }
+
+ //=========================================================================
+ // Directed Graph Helper Class
+
+ struct adj_list_dir_traversal_tag :
+ public virtual vertex_list_graph_tag,
+ public virtual incidence_graph_tag,
+ public virtual adjacency_graph_tag,
+ public virtual edge_list_graph_tag { };
+
+ template <class Config>
+ struct directed_graph_helper
+ : public directed_edges_helper<Config> {
+ typedef typename Config::edge_descriptor edge_descriptor;
+ typedef adj_list_dir_traversal_tag traversal_category;
+ };
+
+ // O(E/V)
+ template <class Config>
+ inline void
+ remove_edge(typename Config::vertex_descriptor u,
+ typename Config::vertex_descriptor v,
+ directed_graph_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::edge_parallel_category Cat;
+ graph_type& g = static_cast<graph_type&>(g_);
+ detail::erase_from_incidence_list(g.out_edge_list(u), v, Cat());
+ }
+
+ template <class Config, class Predicate>
+ inline void
+ remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred,
+ directed_graph_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ graph_type& g = static_cast<graph_type&>(g_);
+ typename Config::out_edge_iterator first, last;
+ tie(first, last) = out_edges(u, g);
+ typedef typename Config::edge_parallel_category edge_parallel_category;
+ detail::remove_directed_edge_if_dispatch
+ (first, last, g.out_edge_list(u), pred, edge_parallel_category());
+ }
+
+ template <class Config, class Predicate>
+ inline void
+ remove_edge_if(Predicate pred, directed_graph_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ graph_type& g = static_cast<graph_type&>(g_);
+
+ typename Config::vertex_iterator vi, vi_end;
+ for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ remove_out_edge_if(*vi, pred, g);
+ }
+
+ template <class EdgeOrIter, class Config>
+ inline void
+ remove_edge(EdgeOrIter e_or_iter, directed_graph_helper<Config>& g_)
+ {
+ g_.remove_edge(e_or_iter);
+ }
+
+ // O(V + E) for allow_parallel_edges
+ // O(V * log(E/V)) for disallow_parallel_edges
+ template <class Config>
+ inline void
+ clear_vertex(typename Config::vertex_descriptor u,
+ directed_graph_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::edge_parallel_category Cat;
+ graph_type& g = static_cast<graph_type&>(g_);
+ typename Config::vertex_iterator vi, viend;
+ for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
+ detail::erase_from_incidence_list(g.out_edge_list(*vi), u, Cat());
+ g.out_edge_list(u).clear();
+ // clear() should be a req of Sequence and AssociativeContainer,
+ // or maybe just Container
+ }
+
+ template <class Config>
+ inline void
+ clear_out_edges(typename Config::vertex_descriptor u,
+ directed_graph_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::edge_parallel_category Cat;
+ graph_type& g = static_cast<graph_type&>(g_);
+ g.out_edge_list(u).clear();
+ // clear() should be a req of Sequence and AssociativeContainer,
+ // or maybe just Container
+ }
+
+ // O(V), could do better...
+ template <class Config>
+ inline typename Config::edges_size_type
+ num_edges(const directed_graph_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ const graph_type& g = static_cast<const graph_type&>(g_);
+ typename Config::edges_size_type num_e = 0;
+ typename Config::vertex_iterator vi, vi_end;
+ for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ num_e += out_degree(*vi, g);
+ return num_e;
+ }
+ // O(1) for allow_parallel_edge_tag
+ // O(log(E/V)) for disallow_parallel_edge_tag
+ template <class Config>
+ inline std::pair<typename directed_graph_helper<Config>::edge_descriptor, bool>
+ add_edge(typename Config::vertex_descriptor u,
+ typename Config::vertex_descriptor v,
+ const typename Config::edge_property_type& p,
+ directed_graph_helper<Config>& g_)
+ {
+ typedef typename Config::edge_descriptor edge_descriptor;
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::StoredEdge StoredEdge;
+ graph_type& g = static_cast<graph_type&>(g_);
+ typename Config::OutEdgeList::iterator i;
+ bool inserted;
+ boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u),
+ StoredEdge(v, p));
+ return std::make_pair(edge_descriptor(u, v, &(*i).get_property()),
+ inserted);
+ }
+ // Did not use default argument here because that
+ // causes Visual C++ to get confused.
+ template <class Config>
+ inline std::pair<typename Config::edge_descriptor, bool>
+ add_edge(typename Config::vertex_descriptor u,
+ typename Config::vertex_descriptor v,
+ directed_graph_helper<Config>& g_)
+ {
+ typename Config::edge_property_type p;
+ return add_edge(u, v, p, g_);
+ }
+ //=========================================================================
+ // Undirected Graph Helper Class
+
+ template <class Config>
+ struct undirected_graph_helper;
+
+ struct undir_adj_list_traversal_tag :
+ public virtual vertex_list_graph_tag,
+ public virtual incidence_graph_tag,
+ public virtual adjacency_graph_tag,
+ public virtual edge_list_graph_tag,
+ public virtual bidirectional_graph_tag { };
+
+ namespace detail {
+
+ // using class with specialization for dispatch is a VC++ workaround.
+ template <class StoredProperty>
+ struct remove_undirected_edge_dispatch {
+
+ // O(E/V)
+ template <class edge_descriptor, class Config>
+ static void
+ apply(edge_descriptor e,
+ undirected_graph_helper<Config>& g_,
+ StoredProperty& p)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ graph_type& g = static_cast<graph_type&>(g_);
+
+ typename Config::OutEdgeList& out_el = g.out_edge_list(source(e, g));
+ typename Config::OutEdgeList::iterator out_i = out_el.begin();
+ for (; out_i != out_el.end(); ++out_i)
+ if (&(*out_i).get_property() == &p) {
+ out_el.erase(out_i);
+ break;
+ }
+ typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g));
+ typename Config::OutEdgeList::iterator in_i = in_el.begin();
+ for (; in_i != in_el.end(); ++in_i)
+ if (&(*in_i).get_property() == &p) {
+ g.m_edges.erase((*in_i).get_iter());
+ in_el.erase(in_i);
+ return;
+ }
+ }
+ };
+
+ template <>
+ struct remove_undirected_edge_dispatch<no_property> {
+ // O(E/V)
+ template <class edge_descriptor, class Config>
+ static void
+ apply(edge_descriptor e,
+ undirected_graph_helper<Config>& g_,
+ no_property&)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ graph_type& g = static_cast<graph_type&>(g_);
+ no_property* p = (no_property*)e.get_property();
+ typename Config::OutEdgeList& out_el = g.out_edge_list(source(e, g));
+ typename Config::OutEdgeList::iterator out_i = out_el.begin();
+ for (; out_i != out_el.end(); ++out_i)
+ if (&(*out_i).get_property() == p) {
+ out_el.erase(out_i);
+ break;
+ }
+ typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g));
+ typename Config::OutEdgeList::iterator in_i = in_el.begin();
+ for (; in_i != in_el.end(); ++in_i)
+ if (&(*in_i).get_property() == p) {
+ g.m_edges.erase((*in_i).get_iter());
+ in_el.erase(in_i);
+ return;
+ }
+ }
+ };
+
+ // O(E/V)
+ template <class Graph, class EdgeList, class Vertex>
+ inline void
+ remove_edge_and_property(Graph& g, EdgeList& el, Vertex v,
+ boost::allow_parallel_edge_tag cat)
+ {
+ typedef typename Graph::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename EdgeList::value_type StoredEdge;
+ typename EdgeList::iterator i = el.begin(), end = el.end();
+ for (; i != end; ++i)
+ if ((*i).get_target() == v)
+ g.m_edges.erase((*i).get_iter());
+ detail::erase_from_incidence_list(el, v, cat);
+ }
+ // O(log(E/V))
+ template <class Graph, class EdgeList, class Vertex>
+ inline void
+ remove_edge_and_property(Graph& g, EdgeList& el, Vertex v,
+ boost::disallow_parallel_edge_tag)
+ {
+ typedef typename Graph::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename EdgeList::value_type StoredEdge;
+ typename EdgeList::iterator i = el.find(StoredEdge(v)), end = el.end();
+ if (i != end) {
+ g.m_edges.erase((*i).get_iter());
+ el.erase(i);
+ }
+ }
+
+ } // namespace detail
+
+ template <class Vertex, class EdgeProperty>
+ struct list_edge // short name due to VC++ truncation and linker problems
+ : public boost::detail::edge_base<boost::undirected_tag, Vertex>
+ {
+ typedef EdgeProperty property_type;
+ typedef boost::detail::edge_base<boost::undirected_tag, Vertex> Base;
+ list_edge(Vertex u, Vertex v, const EdgeProperty& p = EdgeProperty())
+ : Base(u, v), m_property(p) { }
+ EdgeProperty& get_property() { return m_property; }
+ const EdgeProperty& get_property() const { return m_property; }
+ // the following methods should never be used, but are needed
+ // to make SGI MIPSpro C++ happy
+ list_edge() { }
+ bool operator==(const list_edge&) const { return false; }
+ bool operator<(const list_edge&) const { return false; }
+ EdgeProperty m_property;
+ };
+
+ template <class Config>
+ struct undirected_graph_helper {
+
+ typedef undir_adj_list_traversal_tag traversal_category;
+
+ // Placement of these overloaded remove_edge() functions
+ // inside the class avoids a VC++ bug.
+
+ // O(E/V)
+ inline void
+ remove_edge(typename Config::edge_descriptor e)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::OutEdgeList::value_type::property_type PType;
+ detail::remove_undirected_edge_dispatch<PType>::apply
+ (e, *this, *(PType*)e.get_property());
+ }
+ // O(E/V)
+ inline void
+ remove_edge(typename Config::out_edge_iterator iter)
+ {
+ this->remove_edge(*iter);
+ }
+ };
+
+ // Had to make these non-members to avoid accidental instantiation
+ // on SGI MIPSpro C++
+ template <class C>
+ inline typename C::InEdgeList&
+ in_edge_list(undirected_graph_helper<C>&,
+ typename C::vertex_descriptor v)
+ {
+ typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
+ return sv->m_out_edges;
+ }
+ template <class C>
+ inline const typename C::InEdgeList&
+ in_edge_list(const undirected_graph_helper<C>&,
+ typename C::vertex_descriptor v) {
+ typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
+ return sv->m_out_edges;
+ }
+
+ // O(E/V)
+ template <class EdgeOrIter, class Config>
+ inline void
+ remove_edge(EdgeOrIter e, undirected_graph_helper<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ g_.remove_edge(e);
+ }
+
+ // O(E/V) or O(log(E/V))
+ template <class Config>
+ void
+ remove_edge(typename Config::vertex_descriptor u,
+ typename Config::vertex_descriptor v,
+ undirected_graph_helper<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ graph_type& g = static_cast<graph_type&>(g_);
+ typedef typename Config::edge_parallel_category Cat;
+ detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat());
+ detail::erase_from_incidence_list(g.out_edge_list(v), u, Cat());
+ }
+
+ template <class Config, class Predicate>
+ void
+ remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred,
+ undirected_graph_helper<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::OutEdgeList::value_type::property_type PropT;
+ graph_type& g = static_cast<graph_type&>(g_);
+ typename Config::out_edge_iterator first, last;
+ tie(first, last) = out_edges(u, g);
+ typedef typename Config::edge_parallel_category Cat;
+ detail::undirected_remove_out_edge_if_dispatch<PropT>
+ (g, first, last, g.out_edge_list(u), pred, Cat());
+ }
+ template <class Config, class Predicate>
+ void
+ remove_in_edge_if(typename Config::vertex_descriptor u, Predicate pred,
+ undirected_graph_helper<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ remove_out_edge_if(u, pred, g_);
+ }
+
+ // O(E/V * E) or O(log(E/V) * E)
+ template <class Predicate, class Config>
+ void
+ remove_edge_if(Predicate pred, undirected_graph_helper<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ graph_type& g = static_cast<graph_type&>(g_);
+ typename Config::edge_iterator ei, ei_end, next;
+ tie(ei, ei_end) = edges(g);
+ for (next = ei; ei != ei_end; ei = next) {
+ ++next;
+ if (pred(*ei))
+ remove_edge(*ei, g);
+ }
+ }
+
+ // O(1)
+ template <class Config>
+ inline std::pair<typename Config::edge_iterator,
+ typename Config::edge_iterator>
+ edges(const undirected_graph_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::edge_iterator edge_iterator;
+ const graph_type& cg = static_cast<const graph_type&>(g_);
+ graph_type& g = const_cast<graph_type&>(cg);
+ return std::make_pair( edge_iterator(g.m_edges.begin()),
+ edge_iterator(g.m_edges.end()) );
+ }
+ // O(1)
+ template <class Config>
+ inline typename Config::edges_size_type
+ num_edges(const undirected_graph_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ const graph_type& g = static_cast<const graph_type&>(g_);
+ return g.m_edges.size();
+ }
+ // O(E/V * E/V)
+ template <class Config>
+ inline void
+ clear_vertex(typename Config::vertex_descriptor u,
+ undirected_graph_helper<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::edge_parallel_category Cat;
+ graph_type& g = static_cast<graph_type&>(g_);
+ typename Config::OutEdgeList& el = g.out_edge_list(u);
+ typename Config::OutEdgeList::iterator
+ ei = el.begin(), ei_end = el.end();
+ for (; ei != ei_end; ++ei) {
+ detail::erase_from_incidence_list
+ (g.out_edge_list((*ei).get_target()), u, Cat());
+ g.m_edges.erase((*ei).get_iter());
+ }
+ g.out_edge_list(u).clear();
+ }
+ // O(1) for allow_parallel_edge_tag
+ // O(log(E/V)) for disallow_parallel_edge_tag
+ template <class Config>
+ inline std::pair<typename Config::edge_descriptor, bool>
+ add_edge(typename Config::vertex_descriptor u,
+ typename Config::vertex_descriptor v,
+ const typename Config::edge_property_type& p,
+ undirected_graph_helper<Config>& g_)
+ {
+ typedef typename Config::StoredEdge StoredEdge;
+ typedef typename Config::edge_descriptor edge_descriptor;
+ typedef typename Config::graph_type graph_type;
+ graph_type& g = static_cast<graph_type&>(g_);
+
+ bool inserted;
+ typename Config::EdgeContainer::value_type e(u, v, p);
+ typename Config::EdgeContainer::iterator p_iter
+ = graph_detail::push(g.m_edges, e).first;
+
+ typename Config::OutEdgeList::iterator i;
+ boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u),
+ StoredEdge(v, p_iter, &g.m_edges));
+ if (inserted) {
+ boost::graph_detail::push(g.out_edge_list(v), StoredEdge(u, p_iter, &g.m_edges));
+ return std::make_pair(edge_descriptor(u, v, &p_iter->get_property()),
+ true);
+ } else {
+ g.m_edges.erase(p_iter);
+ return std::make_pair
+ (edge_descriptor(u, v, &i->get_iter()->get_property()), false);
+ }
+ }
+ template <class Config>
+ inline std::pair<typename Config::edge_descriptor, bool>
+ add_edge(typename Config::vertex_descriptor u,
+ typename Config::vertex_descriptor v,
+ undirected_graph_helper<Config>& g_)
+ {
+ typename Config::edge_property_type p;
+ return add_edge(u, v, p, g_);
+ }
+
+ // O(1)
+ template <class Config>
+ inline typename Config::degree_size_type
+ degree(typename Config::vertex_descriptor u,
+ const undirected_graph_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type Graph;
+ const Graph& g = static_cast<const Graph&>(g_);
+ return out_degree(u, g);
+ }
+
+ template <class Config>
+ inline std::pair<typename Config::in_edge_iterator,
+ typename Config::in_edge_iterator>
+ in_edges(typename Config::vertex_descriptor u,
+ const undirected_graph_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type Graph;
+ const Graph& cg = static_cast<const Graph&>(g_);
+ Graph& g = const_cast<Graph&>(cg);
+ typedef typename Config::in_edge_iterator in_edge_iterator;
+ return
+ std::make_pair(in_edge_iterator(g.out_edge_list(u).begin(), u),
+ in_edge_iterator(g.out_edge_list(u).end(), u));
+ }
+
+ template <class Config>
+ inline typename Config::degree_size_type
+ in_degree(typename Config::vertex_descriptor u,
+ const undirected_graph_helper<Config>& g_)
+ { return degree(u, g_); }
+
+ //=========================================================================
+ // Bidirectional Graph Helper Class
+
+ struct bidir_adj_list_traversal_tag :
+ public virtual vertex_list_graph_tag,
+ public virtual incidence_graph_tag,
+ public virtual adjacency_graph_tag,
+ public virtual edge_list_graph_tag,
+ public virtual bidirectional_graph_tag { };
+
+ template <class Config>
+ struct bidirectional_graph_helper
+ : public directed_edges_helper<Config> {
+ typedef bidir_adj_list_traversal_tag traversal_category;
+ };
+
+ // Had to make these non-members to avoid accidental instantiation
+ // on SGI MIPSpro C++
+ template <class C>
+ inline typename C::InEdgeList&
+ in_edge_list(bidirectional_graph_helper<C>&,
+ typename C::vertex_descriptor v)
+ {
+ typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
+ return sv->m_in_edges;
+ }
+ template <class C>
+ inline const typename C::InEdgeList&
+ in_edge_list(const bidirectional_graph_helper<C>&,
+ typename C::vertex_descriptor v) {
+ typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
+ return sv->m_in_edges;
+ }
+
+ template <class Predicate, class Config>
+ inline void
+ remove_edge_if(Predicate pred, bidirectional_graph_helper<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ graph_type& g = static_cast<graph_type&>(g_);
+ typename Config::edge_iterator ei, ei_end, next;
+ tie(ei, ei_end) = edges(g);
+ for (next = ei; ei != ei_end; ei = next) {
+ ++next;
+ if (pred(*ei))
+ remove_edge(*ei, g);
+ }
+ }
+
+ template <class Config>
+ inline std::pair<typename Config::in_edge_iterator,
+ typename Config::in_edge_iterator>
+ in_edges(typename Config::vertex_descriptor u,
+ const bidirectional_graph_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ const graph_type& cg = static_cast<const graph_type&>(g_);
+ graph_type& g = const_cast<graph_type&>(cg);
+ typedef typename Config::in_edge_iterator in_edge_iterator;
+ return
+ std::make_pair(in_edge_iterator(in_edge_list(g, u).begin(), u),
+ in_edge_iterator(in_edge_list(g, u).end(), u));
+ }
+
+ // O(1)
+ template <class Config>
+ inline std::pair<typename Config::edge_iterator,
+ typename Config::edge_iterator>
+ edges(const bidirectional_graph_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::edge_iterator edge_iterator;
+ const graph_type& cg = static_cast<const graph_type&>(g_);
+ graph_type& g = const_cast<graph_type&>(cg);
+ return std::make_pair( edge_iterator(g.m_edges.begin()),
+ edge_iterator(g.m_edges.end()) );
+ }
+
+ //=========================================================================
+ // Bidirectional Graph Helper Class (with edge properties)
+
+
+ template <class Config>
+ struct bidirectional_graph_helper_with_property
+ : public bidirectional_graph_helper<Config>
+ {
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::out_edge_iterator out_edge_iterator;
+
+ std::pair<out_edge_iterator, out_edge_iterator>
+ get_parallel_edge_sublist(typename Config::edge_descriptor e,
+ const graph_type& g,
+ void*)
+ { return out_edges(source(e, g), g); }
+
+ std::pair<out_edge_iterator, out_edge_iterator>
+ get_parallel_edge_sublist(typename Config::edge_descriptor e,
+ const graph_type& g,
+ setS*)
+ { return edge_range(source(e, g), target(e, g), g); }
+
+ std::pair<out_edge_iterator, out_edge_iterator>
+ get_parallel_edge_sublist(typename Config::edge_descriptor e,
+ const graph_type& g,
+ multisetS*)
+ { return edge_range(source(e, g), target(e, g), g); }
+
+#if !defined BOOST_NO_HASH
+ std::pair<out_edge_iterator, out_edge_iterator>
+ get_parallel_edge_sublist(typename Config::edge_descriptor e,
+ const graph_type& g,
+ hash_setS*)
+ { return edge_range(source(e, g), target(e, g), g); }
+#endif
+
+ // Placement of these overloaded remove_edge() functions
+ // inside the class avoids a VC++ bug.
+
+ // O(E/V) or O(log(E/V))
+ void
+ remove_edge(typename Config::edge_descriptor e)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ graph_type& g = static_cast<graph_type&>(*this);
+
+ typedef typename Config::edgelist_selector OutEdgeListS;
+
+ std::pair<out_edge_iterator, out_edge_iterator> rng =
+ get_parallel_edge_sublist(e, g, (OutEdgeListS*)(0));
+ rng.first = std::find(rng.first, rng.second, e);
+ assert(rng.first != rng.second);
+ remove_edge(rng.first);
+ }
+
+ inline void
+ remove_edge(typename Config::out_edge_iterator iter)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ graph_type& g = static_cast<graph_type&>(*this);
+ typename Config::edge_descriptor e = *iter;
+ typename Config::OutEdgeList& oel = g.out_edge_list(source(e, g));
+ typename Config::InEdgeList& iel = in_edge_list(g, target(e, g));
+ typedef typename Config::OutEdgeList::value_type::property_type PType;
+ PType& p = *(PType*)e.get_property();
+ detail::remove_directed_edge_dispatch(*iter, iel, p);
+ g.m_edges.erase(iter.base()->get_iter());
+ oel.erase(iter.base());
+ }
+ };
+
+ // O(E/V) for allow_parallel_edge_tag
+ // O(log(E/V)) for disallow_parallel_edge_tag
+ template <class Config>
+ inline void
+ remove_edge(typename Config::vertex_descriptor u,
+ typename Config::vertex_descriptor v,
+ bidirectional_graph_helper_with_property<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ graph_type& g = static_cast<graph_type&>(g_);
+ typedef typename Config::edge_parallel_category Cat;
+ detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat());
+ detail::erase_from_incidence_list(in_edge_list(g, v), u, Cat());
+ }
+
+ // O(E/V) or O(log(E/V))
+ template <class EdgeOrIter, class Config>
+ inline void
+ remove_edge(EdgeOrIter e,
+ bidirectional_graph_helper_with_property<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ g_.remove_edge(e);
+ }
+
+ template <class Config, class Predicate>
+ inline void
+ remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred,
+ bidirectional_graph_helper_with_property<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::OutEdgeList::value_type::property_type PropT;
+ graph_type& g = static_cast<graph_type&>(g_);
+
+ typedef typename Config::EdgeIter EdgeIter;
+ typedef std::vector<EdgeIter> Garbage;
+ Garbage garbage;
+
+ // First remove the edges from the targets' in-edge lists and
+ // from the graph's edge set list.
+ typename Config::out_edge_iterator out_i, out_end;
+ for (tie(out_i, out_end) = out_edges(u, g); out_i != out_end; ++out_i)
+ if (pred(*out_i)) {
+ detail::remove_directed_edge_dispatch
+ (*out_i, in_edge_list(g, target(*out_i, g)),
+ *(PropT*)(*out_i).get_property());
+ // Put in garbage to delete later. Will need the properties
+ // for the remove_if of the out-edges.
+ garbage.push_back((*out_i.base()).get_iter());
+ }
+
+ // Now remove the edges from this out-edge list.
+ typename Config::out_edge_iterator first, last;
+ tie(first, last) = out_edges(u, g);
+ typedef typename Config::edge_parallel_category Cat;
+ detail::remove_directed_edge_if_dispatch
+ (first, last, g.out_edge_list(u), pred, Cat());
+
+ // Now delete the edge properties from the g.m_edges list
+ for (typename Garbage::iterator i = garbage.begin();
+ i != garbage.end(); ++i)
+ g.m_edges.erase(*i);
+ }
+ template <class Config, class Predicate>
+ inline void
+ remove_in_edge_if(typename Config::vertex_descriptor v, Predicate pred,
+ bidirectional_graph_helper_with_property<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::OutEdgeList::value_type::property_type PropT;
+ graph_type& g = static_cast<graph_type&>(g_);
+
+ typedef typename Config::EdgeIter EdgeIter;
+ typedef std::vector<EdgeIter> Garbage;
+ Garbage garbage;
+
+ // First remove the edges from the sources' out-edge lists and
+ // from the graph's edge set list.
+ typename Config::in_edge_iterator in_i, in_end;
+ for (tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i)
+ if (pred(*in_i)) {
+ typename Config::vertex_descriptor u = source(*in_i, g);
+ detail::remove_directed_edge_dispatch
+ (*in_i, g.out_edge_list(u), *(PropT*)(*in_i).get_property());
+ // Put in garbage to delete later. Will need the properties
+ // for the remove_if of the out-edges.
+ garbage.push_back((*in_i.base()).get_iter());
+ }
+ // Now remove the edges from this in-edge list.
+ typename Config::in_edge_iterator first, last;
+ tie(first, last) = in_edges(v, g);
+ typedef typename Config::edge_parallel_category Cat;
+ detail::remove_directed_edge_if_dispatch
+ (first, last, in_edge_list(g, v), pred, Cat());
+
+ // Now delete the edge properties from the g.m_edges list
+ for (typename Garbage::iterator i = garbage.begin();
+ i != garbage.end(); ++i)
+ g.m_edges.erase(*i);
+ }
+
+ // O(1)
+ template <class Config>
+ inline typename Config::edges_size_type
+ num_edges(const bidirectional_graph_helper_with_property<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ const graph_type& g = static_cast<const graph_type&>(g_);
+ return g.m_edges.size();
+ }
+ // O(E/V * E/V) for allow_parallel_edge_tag
+ // O(E/V * log(E/V)) for disallow_parallel_edge_tag
+ template <class Config>
+ inline void
+ clear_vertex(typename Config::vertex_descriptor u,
+ bidirectional_graph_helper_with_property<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::edge_parallel_category Cat;
+ graph_type& g = static_cast<graph_type&>(g_);
+ typename Config::OutEdgeList& el = g.out_edge_list(u);
+ typename Config::OutEdgeList::iterator
+ ei = el.begin(), ei_end = el.end();
+ for (; ei != ei_end; ++ei) {
+ detail::erase_from_incidence_list
+ (in_edge_list(g, (*ei).get_target()), u, Cat());
+ g.m_edges.erase((*ei).get_iter());
+ }
+ typename Config::InEdgeList& in_el = in_edge_list(g, u);
+ typename Config::InEdgeList::iterator
+ in_ei = in_el.begin(), in_ei_end = in_el.end();
+ for (; in_ei != in_ei_end; ++in_ei) {
+ detail::erase_from_incidence_list
+ (g.out_edge_list((*in_ei).get_target()), u, Cat());
+ g.m_edges.erase((*in_ei).get_iter());
+ }
+ g.out_edge_list(u).clear();
+ in_edge_list(g, u).clear();
+ }
+
+ template <class Config>
+ inline void
+ clear_out_edges(typename Config::vertex_descriptor u,
+ bidirectional_graph_helper_with_property<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::edge_parallel_category Cat;
+ graph_type& g = static_cast<graph_type&>(g_);
+ typename Config::OutEdgeList& el = g.out_edge_list(u);
+ typename Config::OutEdgeList::iterator
+ ei = el.begin(), ei_end = el.end();
+ for (; ei != ei_end; ++ei) {
+ detail::erase_from_incidence_list
+ (in_edge_list(g, (*ei).get_target()), u, Cat());
+ g.m_edges.erase((*ei).get_iter());
+ }
+ g.out_edge_list(u).clear();
+ }
+
+ template <class Config>
+ inline void
+ clear_in_edges(typename Config::vertex_descriptor u,
+ bidirectional_graph_helper_with_property<Config>& g_)
+ {
+ typedef typename Config::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Config::graph_type graph_type;
+ typedef typename Config::edge_parallel_category Cat;
+ graph_type& g = static_cast<graph_type&>(g_);
+ typename Config::InEdgeList& in_el = in_edge_list(g, u);
+ typename Config::InEdgeList::iterator
+ in_ei = in_el.begin(), in_ei_end = in_el.end();
+ for (; in_ei != in_ei_end; ++in_ei) {
+ detail::erase_from_incidence_list
+ (g.out_edge_list((*in_ei).get_target()), u, Cat());
+ g.m_edges.erase((*in_ei).get_iter());
+ }
+ in_edge_list(g, u).clear();
+ }
+
+ // O(1) for allow_parallel_edge_tag
+ // O(log(E/V)) for disallow_parallel_edge_tag
+ template <class Config>
+ inline std::pair<typename Config::edge_descriptor, bool>
+ add_edge(typename Config::vertex_descriptor u,
+ typename Config::vertex_descriptor v,
+ const typename Config::edge_property_type& p,
+ bidirectional_graph_helper_with_property<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ graph_type& g = static_cast<graph_type&>(g_);
+ typedef typename Config::edge_descriptor edge_descriptor;
+ typedef typename Config::StoredEdge StoredEdge;
+ bool inserted;
+ typename Config::EdgeContainer::value_type e(u, v, p);
+ typename Config::EdgeContainer::iterator p_iter
+ = graph_detail::push(g.m_edges, e).first;
+ typename Config::OutEdgeList::iterator i;
+ boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u),
+ StoredEdge(v, p_iter, &g.m_edges));
+ if (inserted) {
+ boost::graph_detail::push(in_edge_list(g, v), StoredEdge(u, p_iter, &g.m_edges));
+ return std::make_pair(edge_descriptor(u, v, &p_iter->m_property),
+ true);
+ } else {
+ g.m_edges.erase(p_iter);
+ return std::make_pair(edge_descriptor(u, v,
+ &i->get_iter()->get_property()),
+ false);
+ }
+ }
+
+ template <class Config>
+ inline std::pair<typename Config::edge_descriptor, bool>
+ add_edge(typename Config::vertex_descriptor u,
+ typename Config::vertex_descriptor v,
+ bidirectional_graph_helper_with_property<Config>& g_)
+ {
+ typename Config::edge_property_type p;
+ return add_edge(u, v, p, g_);
+ }
+ // O(1)
+ template <class Config>
+ inline typename Config::degree_size_type
+ degree(typename Config::vertex_descriptor u,
+ const bidirectional_graph_helper_with_property<Config>& g_)
+ {
+ typedef typename Config::graph_type graph_type;
+ const graph_type& g = static_cast<const graph_type&>(g_);
+ return in_degree(u, g) + out_degree(u, g);
+ }
+
+ //=========================================================================
+ // Adjacency List Helper Class
+
+ template <class Config, class Base>
+ struct adj_list_helper : public Base
+ {
+ typedef typename Config::graph_type AdjList;
+ typedef typename Config::vertex_descriptor vertex_descriptor;
+ typedef typename Config::edge_descriptor edge_descriptor;
+ typedef typename Config::out_edge_iterator out_edge_iterator;
+ typedef typename Config::in_edge_iterator in_edge_iterator;
+ typedef typename Config::adjacency_iterator adjacency_iterator;
+ typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator;
+ typedef typename Config::vertex_iterator vertex_iterator;
+ typedef typename Config::edge_iterator edge_iterator;
+ typedef typename Config::directed_category directed_category;
+ typedef typename Config::edge_parallel_category edge_parallel_category;
+ typedef typename Config::vertices_size_type vertices_size_type;
+ typedef typename Config::edges_size_type edges_size_type;
+ typedef typename Config::degree_size_type degree_size_type;
+ typedef typename Config::StoredEdge StoredEdge;
+ typedef typename Config::edge_property_type edge_property_type;
+
+ typedef typename Config::global_edgelist_selector
+ global_edgelist_selector;
+
+ // protected:
+
+ // The edge_dispatch() functions should be static, but
+ // Borland gets confused about constness.
+
+ // O(E/V)
+ inline std::pair<edge_descriptor,bool>
+ edge_dispatch(const AdjList& g,
+ vertex_descriptor u, vertex_descriptor v,
+ boost::allow_parallel_edge_tag) const
+ {
+ bool found;
+ const typename Config::OutEdgeList& el = g.out_edge_list(u);
+ typename Config::OutEdgeList::const_iterator
+ i = std::find_if(el.begin(), el.end(),
+ detail::target_is<vertex_descriptor>(v));
+ found = (i != g.out_edge_list(u).end());
+ if (found)
+ return std::make_pair(edge_descriptor(u, v, &(*i).get_property()),
+ true);
+ else
+ return std::make_pair(edge_descriptor(u, v, 0), false);
+ }
+ // O(log(E/V))
+ inline std::pair<edge_descriptor,bool>
+ edge_dispatch(const AdjList& g,
+ vertex_descriptor u, vertex_descriptor v,
+ boost::disallow_parallel_edge_tag) const
+ {
+ bool found;
+ /* According to the standard, this should be iterator, not const_iterator,
+ but the VC++ std::set::find() const returns const_iterator.
+ And since iterator should be convertible to const_iterator, the
+ following should work everywhere. -Jeremy */
+ typename Config::OutEdgeList::const_iterator
+ i = g.out_edge_list(u).find(StoredEdge(v)),
+ end = g.out_edge_list(u).end();
+ found = (i != end);
+ if (found)
+ return std::make_pair(edge_descriptor(u, v, &(*i).get_property()),
+ true);
+ else
+ return std::make_pair(edge_descriptor(u, v, 0), false);
+ }
+ };
+
+ template <class Config, class Base>
+ inline std::pair<typename Config::adjacency_iterator,
+ typename Config::adjacency_iterator>
+ adjacent_vertices(typename Config::vertex_descriptor u,
+ const adj_list_helper<Config, Base>& g_)
+ {
+ typedef typename Config::graph_type AdjList;
+ const AdjList& cg = static_cast<const AdjList&>(g_);
+ AdjList& g = const_cast<AdjList&>(cg);
+ typedef typename Config::adjacency_iterator adjacency_iterator;
+ typename Config::out_edge_iterator first, last;
+ boost::tie(first, last) = out_edges(u, g);
+ return std::make_pair(adjacency_iterator(first, &g),
+ adjacency_iterator(last, &g));
+ }
+ template <class Config, class Base>
+ inline std::pair<typename Config::inv_adjacency_iterator,
+ typename Config::inv_adjacency_iterator>
+ inv_adjacent_vertices(typename Config::vertex_descriptor u,
+ const adj_list_helper<Config, Base>& g_)
+ {
+ typedef typename Config::graph_type AdjList;
+ const AdjList& cg = static_cast<const AdjList&>(g_);
+ AdjList& g = const_cast<AdjList&>(cg);
+ typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator;
+ typename Config::in_edge_iterator first, last;
+ boost::tie(first, last) = in_edges(u, g);
+ return std::make_pair(inv_adjacency_iterator(first, &g),
+ inv_adjacency_iterator(last, &g));
+ }
+ template <class Config, class Base>
+ inline std::pair<typename Config::out_edge_iterator,
+ typename Config::out_edge_iterator>
+ out_edges(typename Config::vertex_descriptor u,
+ const adj_list_helper<Config, Base>& g_)
+ {
+ typedef typename Config::graph_type AdjList;
+ typedef typename Config::out_edge_iterator out_edge_iterator;
+ const AdjList& cg = static_cast<const AdjList&>(g_);
+ AdjList& g = const_cast<AdjList&>(cg);
+ return
+ std::make_pair(out_edge_iterator(g.out_edge_list(u).begin(), u),
+ out_edge_iterator(g.out_edge_list(u).end(), u));
+ }
+ template <class Config, class Base>
+ inline std::pair<typename Config::vertex_iterator,
+ typename Config::vertex_iterator>
+ vertices(const adj_list_helper<Config, Base>& g_)
+ {
+ typedef typename Config::graph_type AdjList;
+ const AdjList& cg = static_cast<const AdjList&>(g_);
+ AdjList& g = const_cast<AdjList&>(cg);
+ return std::make_pair( g.vertex_set().begin(), g.vertex_set().end() );
+ }
+ template <class Config, class Base>
+ inline typename Config::vertices_size_type
+ num_vertices(const adj_list_helper<Config, Base>& g_)
+ {
+ typedef typename Config::graph_type AdjList;
+ const AdjList& g = static_cast<const AdjList&>(g_);
+ return g.vertex_set().size();
+ }
+ template <class Config, class Base>
+ inline typename Config::degree_size_type
+ out_degree(typename Config::vertex_descriptor u,
+ const adj_list_helper<Config, Base>& g_)
+ {
+ typedef typename Config::graph_type AdjList;
+ const AdjList& g = static_cast<const AdjList&>(g_);
+ return g.out_edge_list(u).size();
+ }
+ template <class Config, class Base>
+ inline std::pair<typename Config::edge_descriptor, bool>
+ edge(typename Config::vertex_descriptor u,
+ typename Config::vertex_descriptor v,
+ const adj_list_helper<Config, Base>& g_)
+ {
+ typedef typename Config::graph_type Graph;
+ typedef typename Config::edge_parallel_category Cat;
+ const Graph& g = static_cast<const Graph&>(g_);
+ return g_.edge_dispatch(g, u, v, Cat());
+ }
+ template <class Config, class Base>
+ inline std::pair<typename Config::out_edge_iterator,
+ typename Config::out_edge_iterator>
+ edge_range(typename Config::vertex_descriptor u,
+ typename Config::vertex_descriptor v,
+ const adj_list_helper<Config, Base>& g_)
+ {
+ typedef typename Config::graph_type Graph;
+ typedef typename Config::StoredEdge StoredEdge;
+ const Graph& cg = static_cast<const Graph&>(g_);
+ Graph& g = const_cast<Graph&>(cg);
+ typedef typename Config::out_edge_iterator out_edge_iterator;
+ typename Config::OutEdgeList& el = g.out_edge_list(u);
+ typename Config::OutEdgeList::iterator first, last;
+ typename Config::EdgeContainer fake_edge_container;
+ tie(first, last) =
+ std::equal_range(el.begin(), el.end(),
+ StoredEdge(v, fake_edge_container.end(),
+ &fake_edge_container));
+ return std::make_pair(out_edge_iterator(first, u),
+ out_edge_iterator(last, u));
+ }
+
+ template <class Config>
+ inline typename Config::degree_size_type
+ in_degree(typename Config::vertex_descriptor u,
+ const directed_edges_helper<Config>& g_)
+ {
+ typedef typename Config::graph_type Graph;
+ const Graph& cg = static_cast<const Graph&>(g_);
+ Graph& g = const_cast<Graph&>(cg);
+ return in_edge_list(g, u).size();
+ }
+
+ namespace detail {
+ template <class Config, class Base, class Property>
+ inline
+ typename boost::property_map<typename Config::graph_type,
+ Property>::type
+ get_dispatch(adj_list_helper<Config,Base>&, Property,
+ boost::edge_property_tag) {
+ typedef typename Config::graph_type Graph;
+ typedef typename boost::property_map<Graph, Property>::type PA;
+ return PA();
+ }
+ template <class Config, class Base, class Property>
+ inline
+ typename boost::property_map<typename Config::graph_type,
+ Property>::const_type
+ get_dispatch(const adj_list_helper<Config,Base>&, Property,
+ boost::edge_property_tag) {
+ typedef typename Config::graph_type Graph;
+ typedef typename boost::property_map<Graph, Property>::const_type PA;
+ return PA();
+ }
+
+ template <class Config, class Base, class Property>
+ inline
+ typename boost::property_map<typename Config::graph_type,
+ Property>::type
+ get_dispatch(adj_list_helper<Config,Base>& g, Property,
+ boost::vertex_property_tag) {
+ typedef typename Config::graph_type Graph;
+ typedef typename boost::property_map<Graph, Property>::type PA;
+ return PA(&static_cast<Graph&>(g));
+ }
+ template <class Config, class Base, class Property>
+ inline
+ typename boost::property_map<typename Config::graph_type,
+ Property>::const_type
+ get_dispatch(const adj_list_helper<Config, Base>& g, Property,
+ boost::vertex_property_tag) {
+ typedef typename Config::graph_type Graph;
+ typedef typename boost::property_map<Graph, Property>::const_type PA;
+ const Graph& cg = static_cast<const Graph&>(g);
+ return PA(&cg);
+ }
+
+ } // namespace detail
+
+ // Implementation of the PropertyGraph interface
+ template <class Config, class Base, class Property>
+ inline
+ typename boost::property_map<typename Config::graph_type, Property>::type
+ get(Property p, adj_list_helper<Config, Base>& g) {
+ typedef typename property_kind<Property>::type Kind;
+ return detail::get_dispatch(g, p, Kind());
+ }
+ template <class Config, class Base, class Property>
+ inline
+ typename boost::property_map<typename Config::graph_type,
+ Property>::const_type
+ get(Property p, const adj_list_helper<Config, Base>& g) {
+ typedef typename property_kind<Property>::type Kind;
+ return detail::get_dispatch(g, p, Kind());
+ }
+
+ template <class Config, class Base, class Property, class Key>
+ inline
+ typename boost::property_traits<
+ typename boost::property_map<typename Config::graph_type,
+ Property>::type
+ >::reference
+ get(Property p, adj_list_helper<Config, Base>& g, const Key& key) {
+ return get(get(p, g), key);
+ }
+
+ template <class Config, class Base, class Property, class Key>
+ inline
+ typename boost::property_traits<
+ typename boost::property_map<typename Config::graph_type,
+ Property>::const_type
+ >::reference
+ get(Property p, const adj_list_helper<Config, Base>& g, const Key& key) {
+ return get(get(p, g), key);
+ }
+
+ template <class Config, class Base, class Property, class Key,class Value>
+ inline void
+ put(Property p, adj_list_helper<Config, Base>& g,
+ const Key& key, const Value& value)
+ {
+ typedef typename Config::graph_type Graph;
+ typedef typename boost::property_map<Graph, Property>::type Map;
+ Map pmap = get(p, static_cast<Graph&>(g));
+ put(pmap, key, value);
+ }
+
+
+ //=========================================================================
+ // Generalize Adjacency List Implementation
+
+ struct adj_list_tag { };
+
+ template <class Derived, class Config, class Base>
+ class adj_list_impl
+ : public adj_list_helper<Config, Base>
+ {
+ typedef typename Config::OutEdgeList OutEdgeList;
+ typedef typename Config::InEdgeList InEdgeList;
+ typedef typename Config::StoredVertexList StoredVertexList;
+ public:
+ typedef typename Config::stored_vertex stored_vertex;
+ typedef typename Config::EdgeContainer EdgeContainer;
+ typedef typename Config::vertex_descriptor vertex_descriptor;
+ typedef typename Config::edge_descriptor edge_descriptor;
+ typedef typename Config::vertex_iterator vertex_iterator;
+ typedef typename Config::edge_iterator edge_iterator;
+ typedef typename Config::edge_parallel_category edge_parallel_category;
+ typedef typename Config::vertices_size_type vertices_size_type;
+ typedef typename Config::edges_size_type edges_size_type;
+ typedef typename Config::degree_size_type degree_size_type;
+ typedef typename Config::edge_property_type edge_property_type;
+ typedef adj_list_tag graph_tag;
+
+ static vertex_descriptor null_vertex()
+ {
+ return 0;
+ }
+
+ inline adj_list_impl() { }
+
+ inline adj_list_impl(const adj_list_impl& x) {
+ copy_impl(x);
+ }
+ inline adj_list_impl& operator=(const adj_list_impl& x) {
+ this->clear();
+ copy_impl(x);
+ return *this;
+ }
+ inline void clear() {
+ for (typename StoredVertexList::iterator i = m_vertices.begin();
+ i != m_vertices.end(); ++i)
+ delete (stored_vertex*)*i;
+ m_vertices.clear();
+ m_edges.clear();
+ }
+ inline adj_list_impl(vertices_size_type num_vertices) {
+ for (vertices_size_type i = 0; i < num_vertices; ++i)
+ add_vertex(static_cast<Derived&>(*this));
+ }
+ template <class EdgeIterator>
+ inline adj_list_impl(vertices_size_type num_vertices,
+ EdgeIterator first, EdgeIterator last)
+ {
+ vertex_descriptor* v = new vertex_descriptor[num_vertices];
+ for (vertices_size_type i = 0; i < num_vertices; ++i)
+ v[i] = add_vertex(static_cast<Derived&>(*this));
+
+ while (first != last) {
+ add_edge(v[(*first).first], v[(*first).second], *this);
+ ++first;
+ }
+ delete [] v;
+ }
+ template <class EdgeIterator, class EdgePropertyIterator>
+ inline adj_list_impl(vertices_size_type num_vertices,
+ EdgeIterator first, EdgeIterator last,
+ EdgePropertyIterator ep_iter)
+ {
+ vertex_descriptor* v = new vertex_descriptor[num_vertices];
+ for (vertices_size_type i = 0; i < num_vertices; ++i)
+ v[i] = add_vertex(static_cast<Derived&>(*this));
+
+ while (first != last) {
+ add_edge(v[(*first).first], v[(*first).second], *ep_iter, *this);
+ ++first;
+ ++ep_iter;
+ }
+ delete [] v;
+ }
+ ~adj_list_impl() {
+ for (typename StoredVertexList::iterator i = m_vertices.begin();
+ i != m_vertices.end(); ++i)
+ delete (stored_vertex*)*i;
+ }
+ // protected:
+ inline OutEdgeList& out_edge_list(vertex_descriptor v) {
+ stored_vertex* sv = (stored_vertex*)v;
+ return sv->m_out_edges;
+ }
+ inline const OutEdgeList& out_edge_list(vertex_descriptor v) const {
+ stored_vertex* sv = (stored_vertex*)v;
+ return sv->m_out_edges;
+ }
+ inline StoredVertexList& vertex_set() { return m_vertices; }
+ inline const StoredVertexList& vertex_set() const { return m_vertices; }
+
+ inline void copy_impl(const adj_list_impl& x_)
+ {
+ const Derived& x = static_cast<const Derived&>(x_);
+
+ // Would be better to have a constant time way to get from
+ // vertices in x to the corresponding vertices in *this.
+ std::map<stored_vertex*,stored_vertex*> vertex_map;
+
+ // Copy the stored vertex objects by adding each vertex
+ // and copying its property object.
+ vertex_iterator vi, vi_end;
+ for (tie(vi, vi_end) = vertices(x); vi != vi_end; ++vi) {
+ stored_vertex* v = (stored_vertex*)add_vertex(*this);
+ v->m_property = ((stored_vertex*)*vi)->m_property;
+ vertex_map[(stored_vertex*)*vi] = v;
+ }
+ // Copy the edges by adding each edge and copying its
+ // property object.
+ edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = edges(x); ei != ei_end; ++ei) {
+ edge_descriptor e;
+ bool inserted;
+ vertex_descriptor s = source(*ei,x), t = target(*ei,x);
+ tie(e, inserted) = add_edge(vertex_map[(stored_vertex*)s],
+ vertex_map[(stored_vertex*)t], *this);
+ *((edge_property_type*)e.m_eproperty)
+ = *((edge_property_type*)(*ei).m_eproperty);
+ }
+ }
+
+
+ typename Config::EdgeContainer m_edges;
+ StoredVertexList m_vertices;
+ };
+
+ // O(1)
+ template <class Derived, class Config, class Base>
+ inline typename Config::vertex_descriptor
+ add_vertex(adj_list_impl<Derived, Config, Base>& g_)
+ {
+ Derived& g = static_cast<Derived&>(g_);
+ typedef typename Config::stored_vertex stored_vertex;
+ stored_vertex* v = new stored_vertex;
+ typename Config::StoredVertexList::iterator pos;
+ bool inserted;
+ boost::tie(pos,inserted) = boost::graph_detail::push(g.m_vertices, v);
+ v->m_position = pos;
+ return v;
+ }
+ // O(1)
+ template <class Derived, class Config, class Base>
+ inline typename Config::vertex_descriptor
+ add_vertex(const typename Config::vertex_property_type& p,
+ adj_list_impl<Derived, Config, Base>& g_)
+ {
+ Derived& g = static_cast<Derived&>(g_);
+ typedef typename Config::stored_vertex stored_vertex;
+ stored_vertex* v = new stored_vertex(p);
+ typename Config::StoredVertexList::iterator pos;
+ bool inserted;
+ boost::tie(pos,inserted) = boost::graph_detail::push(g.m_vertices, v);
+ v->m_position = pos;
+ return v;
+ }
+ // O(1)
+ template <class Derived, class Config, class Base>
+ inline void remove_vertex(typename Config::vertex_descriptor u,
+ adj_list_impl<Derived, Config, Base>& g_)
+ {
+ typedef typename Config::stored_vertex stored_vertex;
+ Derived& g = static_cast<Derived&>(g_);
+ stored_vertex* su = (stored_vertex*)u;
+ g.m_vertices.erase(su->m_position);
+ delete su;
+ }
+ // O(V)
+ template <class Derived, class Config, class Base>
+ inline typename Config::vertex_descriptor
+ vertex(typename Config::vertices_size_type n,
+ const adj_list_impl<Derived, Config, Base>& g_)
+ {
+ const Derived& g = static_cast<const Derived&>(g_);
+ typename Config::vertex_iterator i = vertices(g).first;
+ while (n--) ++i; // std::advance(i, n); (not VC++ portable)
+ return *i;
+ }
+
+ //=========================================================================
+ // Vector-Backbone Adjacency List Implementation
+
+ namespace detail {
+
+ template <class Graph, class vertex_descriptor>
+ inline void
+ remove_vertex_dispatch(Graph& g, vertex_descriptor u,
+ boost::directed_tag)
+ {
+ typedef typename Graph::edge_parallel_category edge_parallel_category;
+ g.m_vertices.erase(g.m_vertices.begin() + u);
+ vertex_descriptor V = num_vertices(g);
+ if (u != V) {
+ for (vertex_descriptor v = 0; v < V; ++v)
+ reindex_edge_list(g.out_edge_list(v), u, edge_parallel_category());
+ }
+ }
+
+ template <class Graph, class vertex_descriptor>
+ inline void
+ remove_vertex_dispatch(Graph& g, vertex_descriptor u,
+ boost::undirected_tag)
+ {
+ typedef typename Graph::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Graph::edge_parallel_category edge_parallel_category;
+ g.m_vertices.erase(g.m_vertices.begin() + u);
+ vertex_descriptor V = num_vertices(g);
+ for (vertex_descriptor v = 0; v < V; ++v)
+ reindex_edge_list(g.out_edge_list(v), u,
+ edge_parallel_category());
+ typedef typename Graph::EdgeContainer Container;
+ typedef typename Container::iterator Iter;
+ Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end();
+ for (; ei != ei_end; ++ei) {
+ if (ei->m_source > u)
+ --ei->m_source;
+ if (ei->m_target > u)
+ --ei->m_target;
+ }
+ }
+ template <class Graph, class vertex_descriptor>
+ inline void
+ remove_vertex_dispatch(Graph& g, vertex_descriptor u,
+ boost::bidirectional_tag)
+ {
+ typedef typename Graph::global_edgelist_selector EdgeListS;
+ BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
+
+ typedef typename Graph::edge_parallel_category edge_parallel_category;
+ g.m_vertices.erase(g.m_vertices.begin() + u);
+ vertex_descriptor V = num_vertices(g);
+ vertex_descriptor v;
+ if (u != V) {
+ for (v = 0; v < V; ++v)
+ reindex_edge_list(g.out_edge_list(v), u,
+ edge_parallel_category());
+ for (v = 0; v < V; ++v)
+ reindex_edge_list(in_edge_list(g, v), u,
+ edge_parallel_category());
+
+ typedef typename Graph::EdgeContainer Container;
+ typedef typename Container::iterator Iter;
+ Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end();
+ for (; ei != ei_end; ++ei) {
+ if (ei->m_source > u)
+ --ei->m_source;
+ if (ei->m_target > u)
+ --ei->m_target;
+ }
+ }
+ }
+
+ template <class EdgeList, class vertex_descriptor>
+ inline void
+ reindex_edge_list(EdgeList& el, vertex_descriptor u,
+ boost::allow_parallel_edge_tag)
+ {
+ typename EdgeList::iterator ei = el.begin(), e_end = el.end();
+ for (; ei != e_end; ++ei)
+ if ((*ei).get_target() > u)
+ --(*ei).get_target();
+ }
+ template <class EdgeList, class vertex_descriptor>
+ inline void
+ reindex_edge_list(EdgeList& el, vertex_descriptor u,
+ boost::disallow_parallel_edge_tag)
+ {
+ typename EdgeList::iterator ei = el.begin(), e_end = el.end();
+ while (ei != e_end) {
+ typename EdgeList::value_type ce = *ei;
+ ++ei;
+ if (ce.get_target() > u) {
+ el.erase(ce);
+ --ce.get_target();
+ el.insert(ce);
+ }
+ }
+ }
+ } // namespace detail
+
+ struct vec_adj_list_tag { };
+
+ template <class Graph, class Config, class Base>
+ class vec_adj_list_impl
+ : public adj_list_helper<Config, Base>
+ {
+ typedef typename Config::OutEdgeList OutEdgeList;
+ typedef typename Config::InEdgeList InEdgeList;
+ typedef typename Config::StoredVertexList StoredVertexList;
+ public:
+ typedef typename Config::vertex_descriptor vertex_descriptor;
+ typedef typename Config::edge_descriptor edge_descriptor;
+ typedef typename Config::out_edge_iterator out_edge_iterator;
+ typedef typename Config::edge_iterator edge_iterator;
+ typedef typename Config::directed_category directed_category;
+ typedef typename Config::vertices_size_type vertices_size_type;
+ typedef typename Config::edges_size_type edges_size_type;
+ typedef typename Config::degree_size_type degree_size_type;
+ typedef typename Config::StoredEdge StoredEdge;
+ typedef typename Config::stored_vertex stored_vertex;
+ typedef typename Config::EdgeContainer EdgeContainer;
+ typedef typename Config::edge_property_type edge_property_type;
+ typedef vec_adj_list_tag graph_tag;
+
+ static vertex_descriptor null_vertex()
+ {
+ return (std::numeric_limits<vertex_descriptor>::max)();
+ }
+
+ inline vec_adj_list_impl() { }
+
+ inline vec_adj_list_impl(const vec_adj_list_impl& x) {
+ copy_impl(x);
+ }
+ inline vec_adj_list_impl& operator=(const vec_adj_list_impl& x) {
+ this->clear();
+ copy_impl(x);
+ return *this;
+ }
+ inline void clear() {
+ m_vertices.clear();
+ m_edges.clear();
+ }
+
+ inline vec_adj_list_impl(vertices_size_type _num_vertices)
+ : m_vertices(_num_vertices) { }
+
+ template <class EdgeIterator>
+ inline vec_adj_list_impl(vertices_size_type num_vertices,
+ EdgeIterator first, EdgeIterator last)
+ : m_vertices(num_vertices)
+ {
+ while (first != last) {
+ add_edge((*first).first, (*first).second,
+ static_cast<Graph&>(*this));
+ ++first;
+ }
+ }
+ template <class EdgeIterator, class EdgePropertyIterator>
+ inline vec_adj_list_impl(vertices_size_type num_vertices,
+ EdgeIterator first, EdgeIterator last,
+ EdgePropertyIterator ep_iter)
+ : m_vertices(num_vertices)
+ {
+ while (first != last) {
+ add_edge((*first).first, (*first).second, *ep_iter,
+ static_cast<Graph&>(*this));
+ ++first;
+ ++ep_iter;
+ }
+ }
+
+ // protected:
+ inline boost::integer_range<vertex_descriptor> vertex_set() const {
+ return boost::integer_range<vertex_descriptor>(0, m_vertices.size());
+ }
+ inline OutEdgeList& out_edge_list(vertex_descriptor v) {
+ return m_vertices[v].m_out_edges;
+ }
+ inline const OutEdgeList& out_edge_list(vertex_descriptor v) const {
+ return m_vertices[v].m_out_edges;
+ }
+ inline void copy_impl(const vec_adj_list_impl& x_)
+ {
+ const Graph& x = static_cast<const Graph&>(x_);
+ // Copy the stored vertex objects by adding each vertex
+ // and copying its property object.
+ for (vertices_size_type i = 0; i < num_vertices(x); ++i) {
+ vertex_descriptor v = add_vertex(*this);
+ m_vertices[v].m_property = x.m_vertices[i].m_property;
+ }
+ // Copy the edges by adding each edge and copying its
+ // property object.
+ edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = edges(x); ei != ei_end; ++ei) {
+ edge_descriptor e;
+ bool inserted;
+ tie(e, inserted) = add_edge(source(*ei,x), target(*ei,x) , *this);
+ *((edge_property_type*)e.m_eproperty)
+ = *((edge_property_type*)(*ei).m_eproperty);
+ }
+ }
+ typename Config::EdgeContainer m_edges;
+ StoredVertexList m_vertices;
+ };
+ // Had to make these non-members to avoid accidental instantiation
+ // on SGI MIPSpro C++
+ template <class G, class C, class B>
+ inline typename C::InEdgeList&
+ in_edge_list(vec_adj_list_impl<G,C,B>& g,
+ typename C::vertex_descriptor v) {
+ return g.m_vertices[v].m_in_edges;
+ }
+ template <class G, class C, class B>
+ inline const typename C::InEdgeList&
+ in_edge_list(const vec_adj_list_impl<G,C,B>& g,
+ typename C::vertex_descriptor v) {
+ return g.m_vertices[v].m_in_edges;
+ }
+
+ // O(1)
+ template <class Graph, class Config, class Base>
+ inline typename Config::vertex_descriptor
+ add_vertex(vec_adj_list_impl<Graph, Config, Base>& g_) {
+ Graph& g = static_cast<Graph&>(g_);
+ g.m_vertices.resize(g.m_vertices.size() + 1);
+ return g.m_vertices.size() - 1;
+ }
+
+ template <class Graph, class Config, class Base>
+ inline typename Config::vertex_descriptor
+ add_vertex(const typename Config::vertex_property_type& p,
+ vec_adj_list_impl<Graph, Config, Base>& g_) {
+ Graph& g = static_cast<Graph&>(g_);
+ typedef typename Config::stored_vertex stored_vertex;
+ g.m_vertices.push_back(stored_vertex(p));
+ return g.m_vertices.size() - 1;
+ }
+
+ // Here we override the directed_graph_helper add_edge() function
+ // so that the number of vertices is automatically changed if
+ // either u or v is greater than the number of vertices.
+ template <class Graph, class Config, class Base>
+ inline std::pair<typename Config::edge_descriptor, bool>
+ add_edge(typename Config::vertex_descriptor u,
+ typename Config::vertex_descriptor v,
+ const typename Config::edge_property_type& p,
+ vec_adj_list_impl<Graph, Config, Base>& g_)
+ {
+ BOOST_USING_STD_MAX();
+ typename Config::vertex_descriptor x = max BOOST_PREVENT_MACRO_SUBSTITUTION(u, v);
+ if (x >= num_vertices(g_))
+ g_.m_vertices.resize(x + 1);
+ adj_list_helper<Config, Base>& g = g_;
+ return add_edge(u, v, p, g);
+ }
+ template <class Graph, class Config, class Base>
+ inline std::pair<typename Config::edge_descriptor, bool>
+ add_edge(typename Config::vertex_descriptor u,
+ typename Config::vertex_descriptor v,
+ vec_adj_list_impl<Graph, Config, Base>& g_)
+ {
+ typename Config::edge_property_type p;
+ return add_edge(u, v, p, g_);
+ }
+
+
+ // O(V + E)
+ template <class Graph, class Config, class Base>
+ inline void remove_vertex(typename Config::vertex_descriptor v,
+ vec_adj_list_impl<Graph, Config, Base>& g_)
+ {
+ typedef typename Config::directed_category Cat;
+ Graph& g = static_cast<Graph&>(g_);
+ detail::remove_vertex_dispatch(g, v, Cat());
+ }
+ // O(1)
+ template <class Graph, class Config, class Base>
+ inline typename Config::vertex_descriptor
+ vertex(typename Config::vertices_size_type n,
+ const vec_adj_list_impl<Graph, Config, Base>&)
+ {
+ return n;
+ }
+
+
+ namespace detail {
+
+ //=========================================================================
+ // Adjacency List Generator
+
+ template <class Graph, class VertexListS, class OutEdgeListS,
+ class DirectedS, class VertexProperty, class EdgeProperty,
+ class GraphProperty, class EdgeListS>
+ struct adj_list_gen
+ {
+ typedef typename detail::is_random_access<VertexListS>::type
+ is_rand_access;
+ typedef typename has_property<EdgeProperty>::type has_edge_property;
+ typedef typename DirectedS::is_directed_t DirectedT;
+ typedef typename DirectedS::is_bidir_t BidirectionalT;
+
+ struct config
+ {
+ typedef OutEdgeListS edgelist_selector;
+ typedef EdgeListS global_edgelist_selector;
+
+ typedef Graph graph_type;
+ typedef EdgeProperty edge_property_type;
+ typedef VertexProperty vertex_property_type;
+ typedef GraphProperty graph_property_type;
+ typedef std::size_t vertices_size_type;
+
+ typedef adjacency_list_traits<OutEdgeListS, VertexListS, DirectedS>
+ Traits;
+
+ typedef typename Traits::directed_category directed_category;
+ typedef typename Traits::edge_parallel_category edge_parallel_category;
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+ typedef typename Traits::edge_descriptor edge_descriptor;
+
+ typedef void* vertex_ptr;
+
+ // need to reorganize this to avoid instantiating stuff
+ // that doesn't get used -JGS
+
+ // VertexList and vertex_iterator
+ typedef typename container_gen<VertexListS,
+ vertex_ptr>::type SeqVertexList;
+ typedef boost::integer_range<std::size_t> RandVertexList;
+ typedef typename mpl::if_<is_rand_access,
+ RandVertexList, SeqVertexList>::type VertexList;
+
+ typedef typename VertexList::iterator vertex_iterator;
+
+ // EdgeContainer and StoredEdge
+
+ typedef typename container_gen<EdgeListS,
+ list_edge<vertex_descriptor, EdgeProperty> >::type EdgeContainer;
+
+ typedef typename mpl::and_<DirectedT,
+ typename mpl::not_<BidirectionalT>::type >::type on_edge_storage;
+
+ typedef typename mpl::if_<on_edge_storage,
+ std::size_t, typename EdgeContainer::size_type
+ >::type edges_size_type;
+
+ typedef typename EdgeContainer::iterator EdgeIter;
+
+ typedef typename detail::is_random_access<EdgeListS>::type is_edge_ra;
+
+ typedef typename mpl::if_<on_edge_storage,
+ stored_edge_property<vertex_descriptor, EdgeProperty>,
+ typename mpl::if_<is_edge_ra,
+ stored_ra_edge_iter<vertex_descriptor, EdgeContainer, EdgeProperty>,
+ stored_edge_iter<vertex_descriptor, EdgeIter, EdgeProperty>
+ >::type
+ >::type StoredEdge;
+
+ // Adjacency Types
+
+ typedef typename container_gen<OutEdgeListS, StoredEdge>::type
+ OutEdgeList;
+ typedef typename OutEdgeList::size_type degree_size_type;
+ typedef typename OutEdgeList::iterator OutEdgeIter;
+
+ typedef boost::detail::iterator_traits<OutEdgeIter> OutEdgeIterTraits;
+ typedef typename OutEdgeIterTraits::iterator_category OutEdgeIterCat;
+ typedef typename OutEdgeIterTraits::difference_type OutEdgeIterDiff;
+
+ typedef out_edge_iter<
+ OutEdgeIter, vertex_descriptor, edge_descriptor, OutEdgeIterDiff
+ > out_edge_iterator;
+
+ typedef typename adjacency_iterator_generator<graph_type,
+ vertex_descriptor, out_edge_iterator>::type adjacency_iterator;
+
+ typedef OutEdgeList InEdgeList;
+ typedef OutEdgeIter InEdgeIter;
+ typedef OutEdgeIterCat InEdgeIterCat;
+ typedef OutEdgeIterDiff InEdgeIterDiff;
+
+ typedef in_edge_iter<
+ InEdgeIter, vertex_descriptor, edge_descriptor, InEdgeIterDiff
+ > in_edge_iterator;
+
+ typedef typename inv_adjacency_iterator_generator<graph_type,
+ vertex_descriptor, in_edge_iterator>::type inv_adjacency_iterator;
+
+ // Edge Iterator
+
+ typedef boost::detail::iterator_traits<EdgeIter> EdgeIterTraits;
+ typedef typename EdgeIterTraits::iterator_category EdgeIterCat;
+ typedef typename EdgeIterTraits::difference_type EdgeIterDiff;
+
+ typedef undirected_edge_iter<
+ EdgeIter
+ , edge_descriptor
+ , EdgeIterDiff
+ > UndirectedEdgeIter; // also used for bidirectional
+
+ typedef adj_list_edge_iterator<vertex_iterator, out_edge_iterator,
+ graph_type> DirectedEdgeIter;
+
+ typedef typename mpl::if_<on_edge_storage,
+ DirectedEdgeIter, UndirectedEdgeIter>::type edge_iterator;
+
+ // stored_vertex and StoredVertexList
+ typedef typename container_gen<VertexListS, vertex_ptr>::type
+ SeqStoredVertexList;
+ struct seq_stored_vertex {
+ seq_stored_vertex() { }
+ seq_stored_vertex(const VertexProperty& p) : m_property(p) { }
+ OutEdgeList m_out_edges;
+ VertexProperty m_property;
+ typename SeqStoredVertexList::iterator m_position;
+ };
+ struct bidir_seq_stored_vertex {
+ bidir_seq_stored_vertex() { }
+ bidir_seq_stored_vertex(const VertexProperty& p) : m_property(p) { }
+ OutEdgeList m_out_edges;
+ InEdgeList m_in_edges;
+ VertexProperty m_property;
+ typename SeqStoredVertexList::iterator m_position;
+ };
+ struct rand_stored_vertex {
+ rand_stored_vertex() { }
+ rand_stored_vertex(const VertexProperty& p) : m_property(p) { }
+ OutEdgeList m_out_edges;
+ VertexProperty m_property;
+ };
+ struct bidir_rand_stored_vertex {
+ bidir_rand_stored_vertex() { }
+ bidir_rand_stored_vertex(const VertexProperty& p) : m_property(p) { }
+ OutEdgeList m_out_edges;
+ InEdgeList m_in_edges;
+ VertexProperty m_property;
+ };
+ typedef typename mpl::if_<is_rand_access,
+ typename mpl::if_<BidirectionalT,
+ bidir_rand_stored_vertex, rand_stored_vertex>::type,
+ typename mpl::if_<BidirectionalT,
+ bidir_seq_stored_vertex, seq_stored_vertex>::type
+ >::type StoredVertex;
+ struct stored_vertex : public StoredVertex {
+ stored_vertex() { }
+ stored_vertex(const VertexProperty& p) : StoredVertex(p) { }
+ };
+
+ typedef typename container_gen<VertexListS, stored_vertex>::type
+ RandStoredVertexList;
+ typedef typename mpl::if_< is_rand_access,
+ RandStoredVertexList, SeqStoredVertexList>::type StoredVertexList;
+ }; // end of config
+
+
+ typedef typename mpl::if_<BidirectionalT,
+ bidirectional_graph_helper_with_property<config>,
+ typename mpl::if_<DirectedT,
+ directed_graph_helper<config>,
+ undirected_graph_helper<config>
+ >::type
+ >::type DirectedHelper;
+
+ typedef typename mpl::if_<is_rand_access,
+ vec_adj_list_impl<Graph, config, DirectedHelper>,
+ adj_list_impl<Graph, config, DirectedHelper>
+ >::type type;
+
+ };
+
+ } // namespace detail
+
+ //=========================================================================
+ // Vertex Property Maps
+
+ template <class Graph, class ValueType, class Reference, class Tag>
+ struct adj_list_vertex_property_map
+ : public boost::put_get_helper<
+ Reference,
+ adj_list_vertex_property_map<Graph, ValueType, Reference, Tag>
+ >
+ {
+ typedef typename Graph::stored_vertex StoredVertex;
+ typedef ValueType value_type;
+ typedef Reference reference;
+ typedef typename Graph::vertex_descriptor key_type;
+ typedef boost::lvalue_property_map_tag category;
+ inline adj_list_vertex_property_map() { }
+ inline adj_list_vertex_property_map(const Graph*) { }
+ inline Reference operator[](key_type v) const {
+ StoredVertex* sv = (StoredVertex*)v;
+ return get_property_value(sv->m_property, Tag());
+ }
+ inline Reference operator()(key_type v) const {
+ return this->operator[](v);
+ }
+ };
+
+ template <class Graph, class Property, class PropRef>
+ struct adj_list_vertex_all_properties_map
+ : public boost::put_get_helper<PropRef,
+ adj_list_vertex_all_properties_map<Graph, Property, PropRef>
+ >
+ {
+ typedef typename Graph::stored_vertex StoredVertex;
+ typedef Property value_type;
+ typedef PropRef reference;
+ typedef typename Graph::vertex_descriptor key_type;
+ typedef boost::lvalue_property_map_tag category;
+ inline adj_list_vertex_all_properties_map() { }
+ inline adj_list_vertex_all_properties_map(const Graph*) { }
+ inline PropRef operator[](key_type v) const {
+ StoredVertex* sv = (StoredVertex*)v;
+ return sv->m_property;
+ }
+ inline PropRef operator()(key_type v) const {
+ return this->operator[](v);
+ }
+ };
+
+ template <class Graph, class GraphPtr, class ValueType, class Reference,
+ class Tag>
+ struct vec_adj_list_vertex_property_map
+ : public boost::put_get_helper<
+ Reference,
+ vec_adj_list_vertex_property_map<Graph,GraphPtr,ValueType,Reference,
+ Tag>
+ >
+ {
+ typedef ValueType value_type;
+ typedef Reference reference;
+ typedef typename boost::graph_traits<Graph>::vertex_descriptor key_type;
+ typedef boost::lvalue_property_map_tag category;
+ vec_adj_list_vertex_property_map() { }
+ vec_adj_list_vertex_property_map(GraphPtr g) : m_g(g) { }
+ inline Reference operator[](key_type v) const {
+ return get_property_value(m_g->m_vertices[v].m_property, Tag());
+ }
+ inline Reference operator()(key_type v) const {
+ return this->operator[](v);
+ }
+ GraphPtr m_g;
+ };
+
+ template <class Graph, class GraphPtr, class Property, class PropertyRef>
+ struct vec_adj_list_vertex_all_properties_map
+ : public boost::put_get_helper<PropertyRef,
+ vec_adj_list_vertex_all_properties_map<Graph,GraphPtr,Property,
+ PropertyRef>
+ >
+ {
+ typedef Property value_type;
+ typedef PropertyRef reference;
+ typedef typename boost::graph_traits<Graph>::vertex_descriptor key_type;
+ typedef boost::lvalue_property_map_tag category;
+ vec_adj_list_vertex_all_properties_map() { }
+ vec_adj_list_vertex_all_properties_map(GraphPtr g) : m_g(g) { }
+ inline PropertyRef operator[](key_type v) const {
+ return m_g->m_vertices[v].m_property;
+ }
+ inline PropertyRef operator()(key_type v) const {
+ return this->operator[](v);
+ }
+ GraphPtr m_g;
+ };
+
+ struct adj_list_any_vertex_pa {
+ template <class Tag, class Graph, class Property>
+ struct bind_ {
+ typedef typename property_value<Property, Tag>::type value_type;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+
+ typedef adj_list_vertex_property_map
+ <Graph, value_type, reference, Tag> type;
+ typedef adj_list_vertex_property_map
+ <Graph, value_type, const_reference, Tag> const_type;
+ };
+ };
+ struct adj_list_all_vertex_pa {
+ template <class Tag, class Graph, class Property>
+ struct bind_ {
+ typedef typename Graph::vertex_descriptor Vertex;
+ typedef adj_list_vertex_all_properties_map<Graph,Property,
+ Property&> type;
+ typedef adj_list_vertex_all_properties_map<Graph,Property,
+ const Property&> const_type;
+ };
+ };
+
+ template <class Property, class Vertex>
+ struct vec_adj_list_vertex_id_map
+ : public boost::put_get_helper<
+ Vertex, vec_adj_list_vertex_id_map<Property, Vertex>
+ >
+ {
+ typedef Vertex value_type;
+ typedef Vertex key_type;
+ typedef Vertex reference;
+ typedef boost::readable_property_map_tag category;
+ inline vec_adj_list_vertex_id_map() { }
+ template <class Graph>
+ inline vec_adj_list_vertex_id_map(const Graph&) { }
+ inline value_type operator[](key_type v) const { return v; }
+ inline value_type operator()(key_type v) const { return v; }
+ };
+
+ struct vec_adj_list_any_vertex_pa {
+ template <class Tag, class Graph, class Property>
+ struct bind_ {
+ typedef typename property_value<Property, Tag>::type value_type;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+
+ typedef vec_adj_list_vertex_property_map
+ <Graph, Graph*, value_type, reference, Tag> type;
+ typedef vec_adj_list_vertex_property_map
+ <Graph, const Graph*, value_type, const_reference, Tag> const_type;
+ };
+ };
+ struct vec_adj_list_id_vertex_pa {
+ template <class Tag, class Graph, class Property>
+ struct bind_ {
+ typedef typename Graph::vertex_descriptor Vertex;
+ typedef vec_adj_list_vertex_id_map<Property, Vertex> type;
+ typedef vec_adj_list_vertex_id_map<Property, Vertex> const_type;
+ };
+ };
+ struct vec_adj_list_all_vertex_pa {
+ template <class Tag, class Graph, class Property>
+ struct bind_ {
+ typedef typename Graph::vertex_descriptor Vertex;
+ typedef vec_adj_list_vertex_all_properties_map
+ <Graph, Graph*, Property, Property&> type;
+ typedef vec_adj_list_vertex_all_properties_map
+ <Graph, const Graph*, Property, const Property&> const_type;
+ };
+ };
+ namespace detail {
+ template <class Tag>
+ struct adj_list_choose_vertex_pa_helper {
+ typedef adj_list_any_vertex_pa type;
+ };
+ template <>
+ struct adj_list_choose_vertex_pa_helper<vertex_all_t> {
+ typedef adj_list_all_vertex_pa type;
+ };
+ template <class Tag, class Graph, class Property>
+ struct adj_list_choose_vertex_pa {
+ typedef typename adj_list_choose_vertex_pa_helper<Tag>::type Helper;
+ typedef typename Helper::template bind_<Tag,Graph,Property> Bind;
+ typedef typename Bind::type type;
+ typedef typename Bind::const_type const_type;
+ };
+
+
+ template <class Tag>
+ struct vec_adj_list_choose_vertex_pa_helper {
+ typedef vec_adj_list_any_vertex_pa type;
+ };
+ template <>
+ struct vec_adj_list_choose_vertex_pa_helper<vertex_index_t> {
+ typedef vec_adj_list_id_vertex_pa type;
+ };
+ template <>
+ struct vec_adj_list_choose_vertex_pa_helper<vertex_all_t> {
+ typedef vec_adj_list_all_vertex_pa type;
+ };
+ template <class Tag, class Graph, class Property>
+ struct vec_adj_list_choose_vertex_pa {
+ typedef typename vec_adj_list_choose_vertex_pa_helper<Tag>::type Helper;
+ typedef typename Helper::template bind_<Tag,Graph,Property> Bind;
+ typedef typename Bind::type type;
+ typedef typename Bind::const_type const_type;
+ };
+ } // namespace detail
+
+ //=========================================================================
+ // Edge Property Map
+
+ template <class Directed, class Value, class Ref, class Vertex,
+ class Property, class Tag>
+ struct adj_list_edge_property_map
+ : public put_get_helper<
+ Ref,
+ adj_list_edge_property_map<Directed, Value, Ref, Vertex, Property,
+ Tag>
+ >
+ {
+ typedef Value value_type;
+ typedef Ref reference;
+ typedef detail::edge_desc_impl<Directed, Vertex> key_type;
+ typedef boost::lvalue_property_map_tag category;
+ inline Ref operator[](key_type e) const {
+ Property& p = *(Property*)e.get_property();
+ return get_property_value(p, Tag());
+ }
+ inline Ref operator()(key_type e) const {
+ return this->operator[](e);
+ }
+ };
+
+ template <class Directed, class Property, class PropRef, class PropPtr,
+ class Vertex>
+ struct adj_list_edge_all_properties_map
+ : public put_get_helper<PropRef,
+ adj_list_edge_all_properties_map<Directed, Property, PropRef,
+ PropPtr, Vertex>
+ >
+ {
+ typedef Property value_type;
+ typedef PropRef reference;
+ typedef detail::edge_desc_impl<Directed, Vertex> key_type;
+ typedef boost::lvalue_property_map_tag category;
+ inline PropRef operator[](key_type e) const {
+ return *(PropPtr)e.get_property();
+ }
+ inline PropRef operator()(key_type e) const {
+ return this->operator[](e);
+ }
+ };
+
+ // Edge Property Maps
+
+ namespace detail {
+ struct adj_list_any_edge_pmap {
+ template <class Graph, class Property, class Tag>
+ struct bind_ {
+ typedef typename property_value<Property,Tag>::type value_type;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+
+ typedef adj_list_edge_property_map
+ <typename Graph::directed_category, value_type, reference,
+ typename Graph::vertex_descriptor,Property,Tag> type;
+ typedef adj_list_edge_property_map
+ <typename Graph::directed_category, value_type, const_reference,
+ typename Graph::vertex_descriptor,const Property, Tag> const_type;
+ };
+ };
+ struct adj_list_all_edge_pmap {
+ template <class Graph, class Property, class Tag>
+ struct bind_ {
+ typedef adj_list_edge_all_properties_map
+ <typename Graph::directed_category, Property, Property&, Property*,
+ typename Graph::vertex_descriptor> type;
+ typedef adj_list_edge_all_properties_map
+ <typename Graph::directed_category, Property, const Property&,
+ const Property*, typename Graph::vertex_descriptor> const_type;
+ };
+ };
+
+ template <class Tag>
+ struct adj_list_choose_edge_pmap_helper {
+ typedef adj_list_any_edge_pmap type;
+ };
+ template <>
+ struct adj_list_choose_edge_pmap_helper<edge_all_t> {
+ typedef adj_list_all_edge_pmap type;
+ };
+ template <class Tag, class Graph, class Property>
+ struct adj_list_choose_edge_pmap {
+ typedef typename adj_list_choose_edge_pmap_helper<Tag>::type Helper;
+ typedef typename Helper::template bind_<Graph,Property,Tag> Bind;
+ typedef typename Bind::type type;
+ typedef typename Bind::const_type const_type;
+ };
+ struct adj_list_edge_property_selector {
+ template <class Graph, class Property, class Tag>
+ struct bind_ {
+ typedef adj_list_choose_edge_pmap<Tag,Graph,Property> Choice;
+ typedef typename Choice::type type;
+ typedef typename Choice::const_type const_type;
+ };
+ };
+ } // namespace detail
+
+ template <>
+ struct edge_property_selector<adj_list_tag> {
+ typedef detail::adj_list_edge_property_selector type;
+ };
+ template <>
+ struct edge_property_selector<vec_adj_list_tag> {
+ typedef detail::adj_list_edge_property_selector type;
+ };
+
+ // Vertex Property Maps
+
+ struct adj_list_vertex_property_selector {
+ template <class Graph, class Property, class Tag>
+ struct bind_ {
+ typedef detail::adj_list_choose_vertex_pa<Tag,Graph,Property> Choice;
+ typedef typename Choice::type type;
+ typedef typename Choice::const_type const_type;
+ };
+ };
+ template <>
+ struct vertex_property_selector<adj_list_tag> {
+ typedef adj_list_vertex_property_selector type;
+ };
+
+ struct vec_adj_list_vertex_property_selector {
+ template <class Graph, class Property, class Tag>
+ struct bind_ {
+ typedef detail::vec_adj_list_choose_vertex_pa<Tag,Graph,Property> Choice;
+ typedef typename Choice::type type;
+ typedef typename Choice::const_type const_type;
+ };
+ };
+ template <>
+ struct vertex_property_selector<vec_adj_list_tag> {
+ typedef vec_adj_list_vertex_property_selector type;
+ };
+
+} // namespace boost
+
+#if !defined(BOOST_NO_HASH) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+namespace BOOST_STD_EXTENSION_NAMESPACE {
+
+ #if BOOST_WORKAROUND( _STLPORT_VERSION, >= 0x500 )
+ // STLport 5 already defines a hash<void*> specialization.
+ #else
+ template <>
+ struct hash< void* > // Need this when vertex_descriptor=void*
+ {
+ std::size_t
+ operator()(void* v) const { return (std::size_t)v; }
+ };
+ #endif
+
+ template <typename V>
+ struct hash< boost::detail::stored_edge<V> >
+ {
+ std::size_t
+ operator()(const boost::detail::stored_edge<V>& e) const
+ {
+ return hash<V>()(e.m_target);
+ }
+ };
+
+ template <typename V, typename P>
+ struct hash< boost::detail::stored_edge_property <V,P> >
+ {
+ std::size_t
+ operator()(const boost::detail::stored_edge_property<V,P>& e) const
+ {
+ return hash<V>()(e.m_target);
+ }
+ };
+
+ template <typename V, typename I, typename P>
+ struct hash< boost::detail::stored_edge_iter<V,I, P> >
+ {
+ std::size_t
+ operator()(const boost::detail::stored_edge_iter<V,I,P>& e) const
+ {
+ return hash<V>()(e.m_target);
+ }
+ };
+
+}
+#endif
+
+
+#undef stored_edge
+#undef stored_edge_property
+#undef stored_edge_iter
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+// Stay out of the way of the concept checking class
+#undef Graph
+#endif
+
+#endif // BOOST_GRAPH_DETAIL_DETAIL_ADJACENCY_LIST_CCT
+
+/*
+ Implementation Notes:
+
+ Many of the public interface functions in this file would have been
+ more conveniently implemented as inline friend functions.
+ However there are a few compiler bugs that make that approach
+ non-portable.
+
+ 1. g++ inline friend in namespace bug
+ 2. g++ using clause doesn't work with inline friends
+ 3. VC++ doesn't have Koenig lookup
+
+ For these reasons, the functions were all written as non-inline free
+ functions, and static cast was used to convert from the helper
+ class to the adjacency_list derived class.
+
+ Looking back, it might have been better to write out all functions
+ in terms of the adjacency_list, and then use a tag to dispatch
+ to the various helpers instead of using inheritance.
+
+ */
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/array_binary_tree.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/array_binary_tree.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,182 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef ADSTL_ARRAY_BINARY_TREE_HPP
+#define ADSTL_ARRAY_BINARY_TREE_HPP
+
+#include <iterator>
+#include <functional>
+#include <boost/config.hpp>
+
+namespace adstl {
+ /*
+ Note: array_binary_tree is a completey balanced binary tree
+ */
+
+#if !defined BOOST_NO_STD_ITERATOR_TRAITS
+ template <class RandomAccessIterator, class ID>
+#else
+ template <class RandomAccessIterator, class ValueType, class ID>
+#endif
+class array_binary_tree_node {
+public:
+ typedef array_binary_tree_node ArrayBinaryTreeNode;
+ typedef RandomAccessIterator rep_iterator;
+#if !defined BOOST_NO_STD_ITERATOR_TRAITS
+ typedef typename std::iterator_traits<RandomAccessIterator>::difference_type
+ difference_type;
+ typedef typename std::iterator_traits<RandomAccessIterator>::value_type
+ value_type;
+#else
+ typedef int difference_type;
+ typedef ValueType value_type;
+#endif
+ typedef difference_type size_type;
+
+ struct children_type {
+ struct iterator
+ : boost::iterator<std::bidirectional_iterator_tag, ArrayBinaryTreeNode,
+ difference_type, array_binary_tree_node*, ArrayBinaryTreeNode&>
+ { // replace with iterator_adaptor implementation -JGS
+
+ inline iterator() : i(0), n(0) { }
+ inline iterator(const iterator& x) : r(x.r), i(x.i), n(x.n), id(x.id) { }
+ inline iterator& operator=(const iterator& x) {
+ r = x.r; i = x.i; n = x.n;
+ /*egcs generate a warning*/
+ id = x.id;
+ return *this;
+ }
+ inline iterator(rep_iterator rr,
+ size_type ii,
+ size_type nn,
+ const ID& _id) : r(rr), i(ii), n(nn), id(_id) { }
+ inline array_binary_tree_node operator*() {
+ return ArrayBinaryTreeNode(r, i, n, id); }
+ inline iterator& operator++() { ++i; return *this; }
+ inline iterator operator++(int)
+ { iterator t = *this; ++(*this); return t; }
+ inline bool operator==(const iterator& x) const { return i == x.i; }
+ inline bool operator!=(const iterator& x) const
+ { return !(*this == x); }
+ rep_iterator r;
+ size_type i;
+ size_type n;
+ ID id;
+ };
+ inline children_type() : i(0), n(0) { }
+ inline children_type(const children_type& x)
+ : r(x.r), i(x.i), n(x.n), id(x.id) { }
+ inline children_type& operator=(const children_type& x) {
+ r = x.r; i = x.i; n = x.n;
+ /*egcs generate a warning*/
+ id = x.id;
+ return *this;
+ }
+ inline children_type(rep_iterator rr,
+ size_type ii,
+ size_type nn,
+ const ID& _id) : r(rr), i(ii), n(nn), id(_id) { }
+ inline iterator begin() { return iterator(r, 2 * i + 1, n, id); }
+ inline iterator end() { return iterator(r, 2 * i + 1 + size(), n, id); }
+ inline size_type size() const {
+ size_type c = 2 * i + 1;
+ size_type s;
+ if (c + 1 < n) s = 2;
+ else if (c < n) s = 1;
+ else s = 0;
+ return s;
+ }
+ rep_iterator r;
+ size_type i;
+ size_type n;
+ ID id;
+ };
+ inline array_binary_tree_node() : i(0), n(0) { }
+ inline array_binary_tree_node(const array_binary_tree_node& x)
+ : r(x.r), i(x.i), n(x.n), id(x.id) { }
+ inline ArrayBinaryTreeNode& operator=(const ArrayBinaryTreeNode& x) {
+ r = x.r;
+ i = x.i;
+ n = x.n;
+ /*egcs generate a warning*/
+ id = x.id;
+ return *this;
+ }
+ inline array_binary_tree_node(rep_iterator start,
+ rep_iterator end,
+ rep_iterator pos, const ID& _id)
+ : r(start), i(pos - start), n(end - start), id(_id) { }
+ inline array_binary_tree_node(rep_iterator rr,
+ size_type ii,
+ size_type nn, const ID& _id)
+ : r(rr), i(ii), n(nn), id(_id) { }
+ inline value_type& value() { return *(r + i); }
+ inline const value_type& value() const { return *(r + i); }
+ inline ArrayBinaryTreeNode parent() const {
+ return ArrayBinaryTreeNode(r, (i - 1) / 2, n, id);
+ }
+ inline bool has_parent() const { return i != 0; }
+ inline children_type children() { return children_type(r, i, n, id); }
+ /*
+ inline void swap(array_binary_tree_node x) {
+ value_type tmp = x.value();
+ x.value() = value();
+ value() = tmp;
+ i = x.i;
+ }
+ */
+ template <class ExternalData>
+ inline void swap(ArrayBinaryTreeNode x, ExternalData& edata ) {
+ using boost::get;
+
+ value_type tmp = x.value();
+
+ /*swap external data*/
+ edata[ get(id, tmp) ] = i;
+ edata[ get(id, value()) ] = x.i;
+
+ x.value() = value();
+ value() = tmp;
+ i = x.i;
+ }
+ inline const children_type children() const {
+ return children_type(r, i, n);
+ }
+ inline size_type index() const { return i; }
+ rep_iterator r;
+ size_type i;
+ size_type n;
+ ID id;
+};
+
+template <class RandomAccessContainer,
+ class Compare = std::less<typename RandomAccessContainer::value_type> >
+struct compare_array_node {
+ typedef typename RandomAccessContainer::value_type value_type;
+ compare_array_node(const Compare& x) : comp(x) {}
+ compare_array_node(const compare_array_node& x) : comp(x.comp) {}
+
+ template< class node_type >
+ inline bool operator()(const node_type& x, const node_type& y) {
+ return comp(x.value(), y.value());
+ }
+
+ template< class node_type >
+ inline bool operator()(const node_type& x, const node_type& y) const {
+ return comp(x.value(), y.value());
+ }
+ Compare comp;
+};
+
+
+} /* namespace adstl */
+
+#endif /* ADSTL_ARRAY_BINARY_TREE_H */
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/connected_components.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/connected_components.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,208 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_GRAPH_DETAIL_CONNECTED_COMPONENTS_HPP
+#define BOOST_GRAPH_DETAIL_CONNECTED_COMPONENTS_HPP
+
+#if defined(__sgi) && !defined(__GNUC__)
+#pragma set woff 1234
+#endif
+
+#include <boost/operators.hpp>
+
+namespace boost {
+
+ namespace detail {
+
+ //=========================================================================
+ // Implementation details of connected_components
+
+ // This is used both in the connected_components algorithm and in
+ // the kosaraju strong components algorithm during the second DFS
+ // traversal.
+ template <class ComponentsPA, class DFSVisitor>
+ class components_recorder : public DFSVisitor
+ {
+ typedef typename property_traits<ComponentsPA>::value_type comp_type;
+ public:
+ components_recorder(ComponentsPA c,
+ comp_type& c_count,
+ DFSVisitor v)
+ : DFSVisitor(v), m_component(c), m_count(c_count) {}
+
+ template <class Vertex, class Graph>
+ void start_vertex(Vertex u, Graph& g) {
+ ++m_count;
+ DFSVisitor::start_vertex(u, g);
+ }
+ template <class Vertex, class Graph>
+ void discover_vertex(Vertex u, Graph& g) {
+ put(m_component, u, m_count);
+ DFSVisitor::discover_vertex(u, g);
+ }
+ protected:
+ ComponentsPA m_component;
+ comp_type& m_count;
+ };
+
+ template <class DiscoverTimeMap, class FinishTimeMap, class TimeT,
+ class DFSVisitor>
+ class time_recorder : public DFSVisitor
+ {
+ public:
+ time_recorder(DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor v)
+ : DFSVisitor(v), m_discover_time(d), m_finish_time(f), m_t(t) {}
+
+ template <class Vertex, class Graph>
+ void discover_vertex(Vertex u, Graph& g) {
+ put(m_discover_time, u, ++m_t);
+ DFSVisitor::discover_vertex(u, g);
+ }
+ template <class Vertex, class Graph>
+ void finish_vertex(Vertex u, Graph& g) {
+ put(m_finish_time, u, ++m_t);
+ DFSVisitor::discover_vertex(u, g);
+ }
+ protected:
+ DiscoverTimeMap m_discover_time;
+ FinishTimeMap m_finish_time;
+ TimeT m_t;
+ };
+ template <class DiscoverTimeMap, class FinishTimeMap, class TimeT,
+ class DFSVisitor>
+ time_recorder<DiscoverTimeMap, FinishTimeMap, TimeT, DFSVisitor>
+ record_times(DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor vis)
+ {
+ return time_recorder<DiscoverTimeMap, FinishTimeMap, TimeT, DFSVisitor>
+ (d, f, t, vis);
+ }
+
+ //=========================================================================
+ // Implementation detail of dynamic_components
+
+
+ //-------------------------------------------------------------------------
+ // Helper functions for the component_index class
+
+ // Record the representative vertices in the header array.
+ // Representative vertices now point to the component number.
+
+ template <class Parent, class OutputIterator, class Integer>
+ inline void
+ build_components_header(Parent p,
+ OutputIterator header,
+ Integer num_nodes)
+ {
+ Parent component = p;
+ Integer component_num = 0;
+ for (Integer v = 0; v != num_nodes; ++v)
+ if (p[v] == v) {
+ *header++ = v;
+ component[v] = component_num++;
+ }
+ }
+
+
+ // Pushes x onto the front of the list. The list is represented in
+ // an array.
+ template <class Next, class T, class V>
+ inline void push_front(Next next, T& head, V x)
+ {
+ T tmp = head;
+ head = x;
+ next[x] = tmp;
+ }
+
+
+ // Create a linked list of the vertices in each component
+ // by reusing the representative array.
+ template <class Parent1, class Parent2,
+ class Integer>
+ void
+ link_components(Parent1 component, Parent2 header,
+ Integer num_nodes, Integer num_components)
+ {
+ // Make the non-representative vertices point to their component
+ Parent1 representative = component;
+ for (Integer v = 0; v != num_nodes; ++v)
+ if (component[v] >= num_components || header[component[v]] != v)
+ component[v] = component[representative[v]];
+
+ // initialize the "head" of the lists to "NULL"
+ std::fill_n(header, num_components, num_nodes);
+
+ // Add each vertex to the linked list for its component
+ Parent1 next = component;
+ for (Integer k = 0; k != num_nodes; ++k)
+ push_front(next, header[component[k]], k);
+ }
+
+
+
+ template <class IndexContainer, class HeaderContainer>
+ void
+ construct_component_index(IndexContainer& index, HeaderContainer& header)
+ {
+ build_components_header(index.begin(),
+ std::back_inserter(header),
+ index.end() - index.begin());
+
+ link_components(index.begin(), header.begin(),
+ index.end() - index.begin(),
+ header.end() - header.begin());
+ }
+
+
+
+ template <class IndexIterator, class Integer, class Distance>
+ class component_iterator
+ : boost::forward_iterator_helper<
+ component_iterator<IndexIterator,Integer,Distance>,
+ Integer, Distance,Integer*, Integer&>
+ {
+ public:
+ typedef component_iterator self;
+
+ IndexIterator next;
+ Integer node;
+
+ typedef std::forward_iterator_tag iterator_category;
+ typedef Integer value_type;
+ typedef Integer& reference;
+ typedef Integer* pointer;
+ typedef Distance difference_type;
+
+ component_iterator() {}
+ component_iterator(IndexIterator x, Integer i)
+ : next(x), node(i) {}
+ Integer operator*() const {
+ return node;
+ }
+ self& operator++() {
+ node = next[node];
+ return *this;
+ }
+ };
+
+ template <class IndexIterator, class Integer, class Distance>
+ inline bool
+ operator==(const component_iterator<IndexIterator, Integer, Distance>& x,
+ const component_iterator<IndexIterator, Integer, Distance>& y)
+ {
+ return x.node == y.node;
+ }
+
+ } // namespace detail
+
+} // namespace detail
+
+#if defined(__sgi) && !defined(__GNUC__)
+#pragma reset woff 1234
+#endif
+
+#endif
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/edge.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/edge.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,124 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_DETAIL_EDGE_HPP
+#define BOOST_GRAPH_DETAIL_EDGE_HPP
+
+#if __GNUC__ < 3
+#include <iostream>
+#else
+#include <iosfwd>
+#endif
+
+namespace boost {
+
+ namespace detail {
+
+ template <typename Directed, typename Vertex>
+ struct edge_base
+ {
+ inline edge_base() {}
+ inline edge_base(Vertex s, Vertex d)
+ : m_source(s), m_target(d) { }
+ Vertex m_source;
+ Vertex m_target;
+ };
+
+ template <typename Directed, typename Vertex>
+ class edge_desc_impl : public edge_base<Directed,Vertex> {
+ typedef edge_desc_impl self;
+ typedef edge_base<Directed,Vertex> Base;
+ public:
+ typedef void property_type;
+
+ inline edge_desc_impl() : m_eproperty(0) {}
+
+ inline edge_desc_impl(Vertex s, Vertex d, const property_type* eplug)
+ : Base(s,d), m_eproperty(const_cast<property_type*>(eplug)) { }
+
+ property_type* get_property() { return m_eproperty; }
+ const property_type* get_property() const { return m_eproperty; }
+
+ // protected:
+ property_type* m_eproperty;
+ };
+
+ template <class D, class V>
+ inline bool
+ operator==(const detail::edge_desc_impl<D,V>& a,
+ const detail::edge_desc_impl<D,V>& b)
+ {
+ return a.get_property() == b.get_property();
+ }
+ template <class D, class V>
+ inline bool
+ operator!=(const detail::edge_desc_impl<D,V>& a,
+ const detail::edge_desc_impl<D,V>& b)
+ {
+ return ! (a.get_property() == b.get_property());
+ }
+
+ // Order edges according to the address of their property object
+ template <class D, class V>
+ inline bool
+ operator<(const detail::edge_desc_impl<D,V>& a,
+ const detail::edge_desc_impl<D,V>& b)
+ {
+ return a.get_property() < b.get_property();
+ }
+ template <class D, class V>
+ inline bool
+ operator<=(const detail::edge_desc_impl<D,V>& a,
+ const detail::edge_desc_impl<D,V>& b)
+ {
+ return a.get_property() <= b.get_property();
+ }
+ template <class D, class V>
+ inline bool
+ operator>(const detail::edge_desc_impl<D,V>& a,
+ const detail::edge_desc_impl<D,V>& b)
+ {
+ return a.get_property() > b.get_property();
+ }
+ template <class D, class V>
+ inline bool
+ operator>=(const detail::edge_desc_impl<D,V>& a,
+ const detail::edge_desc_impl<D,V>& b)
+ {
+ return a.get_property() >= b.get_property();
+ }
+
+ } //namespace detail
+
+} // namespace boost
+
+namespace std {
+
+#if __GNUC__ < 3
+ template <class D, class V>
+ std::ostream&
+ operator<<(std::ostream& os, const boost::detail::edge_desc_impl<D,V>& e)
+ {
+ return os << "(" << e.m_source << "," << e.m_target << ")";
+ }
+#else
+ template <class Char, class Traits, class D, class V>
+ std::basic_ostream<Char, Traits>&
+ operator<<(std::basic_ostream<Char, Traits>& os,
+ const boost::detail::edge_desc_impl<D,V>& e)
+ {
+ return os << "(" << e.m_source << "," << e.m_target << ")";
+ }
+#endif
+
+}
+
+
+#endif // BOOST_GRAPH_DETAIL_DETAIL_EDGE_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/incidence_iterator.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/incidence_iterator.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,79 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_DETAIL_INCIDENCE_ITERATOR_HPP
+#define BOOST_GRAPH_DETAIL_INCIDENCE_ITERATOR_HPP
+
+#include <utility>
+#include <iterator>
+
+// OBSOLETE
+
+namespace boost {
+
+ namespace detail {
+ // EdgeDir tags
+ struct in_edge_tag { };
+ struct out_edge_tag { };
+
+ template <class Vertex, class Edge, class Iterator1D, class EdgeDir>
+ struct bidir_incidence_iterator {
+ typedef bidir_incidence_iterator self;
+ typedef Edge edge_type;
+ typedef typename Edge::property_type EdgeProperty;
+ public:
+ typedef int difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef edge_type reference;
+ typedef edge_type value_type;
+ typedef value_type* pointer;
+ inline bidir_incidence_iterator() {}
+ inline bidir_incidence_iterator(Iterator1D ii, Vertex src)
+ : i(ii), _src(src) { }
+
+ inline self& operator++() { ++i; return *this; }
+ inline self operator++(int) { self tmp = *this; ++(*this); return tmp; }
+
+ inline reference operator*() const {
+ return deref_helper(EdgeDir());
+ }
+ inline self* operator->() { return this; }
+
+ Iterator1D& iter() { return i; }
+ const Iterator1D& iter() const { return i; }
+
+ Iterator1D i;
+ Vertex _src;
+ protected:
+ inline reference deref_helper(out_edge_tag) const {
+ return edge_type( _src, (*i).get_target(), &(*i).get_property() );
+ }
+ inline reference deref_helper(in_edge_tag) const {
+ return edge_type((*i).get_target(), _src, &(*i).get_property() );
+ }
+ };
+
+ template <class V, class E, class Iter, class Dir>
+ inline bool operator==(const bidir_incidence_iterator<V,E,Iter,Dir>& x,
+ const bidir_incidence_iterator<V,E,Iter,Dir>& y)
+ {
+ return x.i == y.i;
+ }
+ template <class V, class E, class Iter, class Dir>
+ inline bool operator!=(const bidir_incidence_iterator<V,E,Iter,Dir>& x,
+ const bidir_incidence_iterator<V,E,Iter,Dir>& y)
+ {
+ return x.i != y.i;
+ }
+
+
+ }
+}
+#endif
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/incremental_components.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/incremental_components.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,141 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP
+#define BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP
+
+#include <boost/operators.hpp>
+#include <boost/pending/disjoint_sets.hpp>
+
+namespace boost {
+
+ namespace detail {
+
+ //=========================================================================
+ // Implementation detail of incremental_components
+
+
+ //-------------------------------------------------------------------------
+ // Helper functions for the component_index class
+
+ // Record the representative vertices in the header array.
+ // Representative vertices now point to the component number.
+
+ template <class Parent, class OutputIterator, class Integer>
+ inline void
+ build_components_header(Parent p,
+ OutputIterator header,
+ Integer num_nodes)
+ {
+ Parent component = p;
+ Integer component_num = 0;
+ for (Integer v = 0; v != num_nodes; ++v)
+ if (p[v] == v) {
+ *header++ = v;
+ component[v] = component_num++;
+ }
+ }
+
+
+ // Pushes x onto the front of the list. The list is represented in
+ // an array.
+ template <class Next, class T, class V>
+ inline void array_push_front(Next next, T& head, V x)
+ {
+ T tmp = head;
+ head = x;
+ next[x] = tmp;
+ }
+
+
+ // Create a linked list of the vertices in each component
+ // by reusing the representative array.
+ template <class Parent1, class Parent2,
+ class Integer>
+ void
+ link_components(Parent1 component, Parent2 header,
+ Integer num_nodes, Integer num_components)
+ {
+ // Make the non-representative vertices point to their component
+ Parent1 representative = component;
+ for (Integer v = 0; v != num_nodes; ++v)
+ if (component[v] >= num_components
+ || header[component[v]] != v)
+ component[v] = component[representative[v]];
+
+ // initialize the "head" of the lists to "NULL"
+ std::fill_n(header, num_components, num_nodes);
+
+ // Add each vertex to the linked list for its component
+ Parent1 next = component;
+ for (Integer k = 0; k != num_nodes; ++k)
+ array_push_front(next, header[component[k]], k);
+ }
+
+
+
+ template <class IndexContainer, class HeaderContainer>
+ void
+ construct_component_index(IndexContainer& index, HeaderContainer& header)
+ {
+ typedef typename IndexContainer::value_type Integer;
+ build_components_header(index.begin(),
+ std::back_inserter(header),
+ Integer(index.end() - index.begin()));
+
+ link_components(index.begin(), header.begin(),
+ Integer(index.end() - index.begin()),
+ Integer(header.end() - header.begin()));
+ }
+
+
+
+ template <class IndexIterator, class Integer, class Distance>
+ class component_iterator
+ : boost::forward_iterator_helper<
+ component_iterator<IndexIterator,Integer,Distance>,
+ Integer, Distance,Integer*, Integer&>
+ {
+ public:
+ typedef component_iterator self;
+
+ IndexIterator next;
+ Integer node;
+
+ typedef std::forward_iterator_tag iterator_category;
+ typedef Integer value_type;
+ typedef Integer& reference;
+ typedef Integer* pointer;
+ typedef Distance difference_type;
+
+ component_iterator() {}
+ component_iterator(IndexIterator x, Integer i)
+ : next(x), node(i) {}
+ Integer operator*() const {
+ return node;
+ }
+ self& operator++() {
+ node = next[node];
+ return *this;
+ }
+ };
+
+ template <class IndexIterator, class Integer, class Distance>
+ inline bool
+ operator==(const component_iterator<IndexIterator, Integer, Distance>& x,
+ const component_iterator<IndexIterator, Integer, Distance>& y)
+ {
+ return x.node == y.node;
+ }
+
+ } // namespace detail
+
+} // namespace detail
+
+#endif // BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/indexed_properties.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/indexed_properties.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,180 @@
+// Copyright 2005 The Trustees of Indiana University.
+
+// 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)
+
+// Authors: Jeremiah Willcock
+// Douglas Gregor
+// Andrew Lumsdaine
+
+// Indexed properties -- used for CSR and CSR-like graphs
+
+#ifndef BOOST_GRAPH_INDEXED_PROPERTIES_HPP
+#define BOOST_GRAPH_INDEXED_PROPERTIES_HPP
+
+#include <vector>
+#include <utility>
+#include <algorithm>
+#include <climits>
+#include <iterator>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/iterator/counting_iterator.hpp>
+#include <boost/integer.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/mpl/if.hpp>
+
+namespace boost {
+namespace detail {
+
+template<typename Derived, typename Property, typename Descriptor>
+class indexed_vertex_properties
+{
+public:
+ typedef no_property vertex_property_type;
+ typedef Property vertex_bundled;
+
+ // Directly access a vertex or edge bundle
+ Property& operator[](Descriptor v)
+ { return m_vertex_properties[get(vertex_index, derived(), v)]; }
+
+ const Property& operator[](Descriptor v) const
+ { return m_vertex_properties[get(vertex_index, derived(), v)]; }
+
+protected:
+ // Default-construct with no property values
+ indexed_vertex_properties() {}
+
+ // Initialize with n default-constructed property values
+ indexed_vertex_properties(std::size_t n) : m_vertex_properties(n) { }
+
+public:
+ // Resize the properties vector
+ void resize(std::size_t n)
+ {
+ m_vertex_properties.resize(n);
+ }
+
+ // Reserve space in the vector of properties
+ void reserve(std::size_t n)
+ {
+ m_vertex_properties.reserve(n);
+ }
+
+ // Add a new property value to the back
+ void push_back(const Property& prop)
+ {
+ m_vertex_properties.push_back(prop);
+ }
+
+ // Access to the derived object
+ Derived& derived() { return *static_cast<Derived*>(this); }
+
+ const Derived& derived() const
+ { return *static_cast<const Derived*>(this); }
+
+public: // should be private, but friend templates not portable
+ std::vector<Property> m_vertex_properties;
+};
+
+template<typename Derived, typename Descriptor>
+class indexed_vertex_properties<Derived, void, Descriptor>
+{
+ struct secret {};
+
+ public:
+ typedef no_property vertex_property_type;
+ typedef void vertex_bundled;
+
+ secret operator[](secret) { return secret(); }
+
+ protected:
+ // All operations do nothing.
+ indexed_vertex_properties() { }
+ indexed_vertex_properties(std::size_t) { }
+
+public:
+ void resize(std::size_t) { }
+ void reserve(std::size_t) { }
+};
+
+template<typename Derived, typename Property, typename Descriptor>
+class indexed_edge_properties
+{
+public:
+ typedef no_property edge_property_type;
+ typedef Property edge_bundled;
+ typedef Property edge_push_back_type;
+
+ // Directly access a edge or edge bundle
+ Property& operator[](Descriptor v)
+ { return m_edge_properties[get(edge_index, derived(), v)]; }
+
+ const Property& operator[](Descriptor v) const
+ { return m_edge_properties[get(edge_index, derived(), v)]; }
+
+protected:
+ // Default-construct with no property values
+ indexed_edge_properties() {}
+
+ // Initialize with n default-constructed property values
+ indexed_edge_properties(std::size_t n) : m_edge_properties(n) { }
+
+ // Resize the properties vector
+ void resize(std::size_t n)
+ {
+ m_edge_properties.resize(n);
+ }
+
+ // Reserve space in the vector of properties
+ void reserve(std::size_t n)
+ {
+ m_edge_properties.reserve(n);
+ }
+
+ public:
+ // Add a new property value to the back
+ void push_back(const Property& prop)
+ {
+ m_edge_properties.push_back(prop);
+ }
+
+ private:
+ // Access to the derived object
+ Derived& derived() { return *static_cast<Derived*>(this); }
+
+ const Derived& derived() const
+ { return *static_cast<const Derived*>(this); }
+
+public: // should be private, but friend templates not portable
+ std::vector<Property> m_edge_properties;
+};
+
+template<typename Derived, typename Descriptor>
+class indexed_edge_properties<Derived, void, Descriptor>
+{
+ struct secret {};
+
+ public:
+ typedef no_property edge_property_type;
+ typedef void edge_bundled;
+ typedef void* edge_push_back_type;
+
+ secret operator[](secret) { return secret(); }
+
+ protected:
+ // All operations do nothing.
+ indexed_edge_properties() { }
+ indexed_edge_properties(std::size_t) { }
+ void resize(std::size_t) { }
+ void reserve(std::size_t) { }
+
+ public:
+ void push_back(const edge_push_back_type&) { }
+};
+
+}
+}
+
+#endif // BOOST_GRAPH_INDEXED_PROPERTIES_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/is_same.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/is_same.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,40 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_GRAPH_DETAIL_IS_SAME_HPP
+#define BOOST_GRAPH_DETAIL_IS_SAME_HPP
+
+#include <boost/mpl/if.hpp>
+
+namespace boost {
+ struct false_tag;
+ struct true_tag;
+
+ namespace graph_detail {
+
+#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ template <class U, class V>
+ struct is_same {
+ typedef boost::false_tag is_same_tag;
+ };
+ template <class U>
+ struct is_same<U, U> {
+ typedef boost::true_tag is_same_tag;
+ };
+#else
+ template <class U, class V>
+ struct is_same {
+ enum { Unum = U::num, Vnum = V::num };
+ typedef typename mpl::if_c< (Unum == Vnum),
+ boost::true_tag, boost::false_tag>::type is_same_tag;
+ };
+#endif
+ } // namespace graph_detail
+} // namespace boost
+
+#endif
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/list_base.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/list_base.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,220 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_LIST_BASE_HPP
+#define BOOST_LIST_BASE_HPP
+
+#include <boost/iterator_adaptors.hpp>
+
+// Perhaps this should go through formal review, and move to <boost/>.
+
+/*
+ An alternate interface idea:
+ Extend the std::list functionality by creating remove/insert
+ functions that do not require the container object!
+ */
+
+namespace boost {
+ namespace detail {
+
+ //=========================================================================
+ // Linked-List Generic Implementation Functions
+
+ template <class Node, class Next>
+ inline Node
+ slist_insert_after(Node pos, Node x,
+ Next next)
+ {
+ next(x) = next(pos);
+ next(pos) = x;
+ return x;
+ }
+
+ // return next(pos) or next(next(pos)) ?
+ template <class Node, class Next>
+ inline Node
+ slist_remove_after(Node pos,
+ Next next)
+ {
+ Node n = next(pos);
+ next(pos) = next(n);
+ return n;
+ }
+
+ template <class Node, class Next>
+ inline Node
+ slist_remove_range(Node before_first, Node last,
+ Next next)
+ {
+ next(before_first) = last;
+ return last;
+ }
+
+ template <class Node, class Next>
+ inline Node
+ slist_previous(Node head, Node x, Node nil,
+ Next next)
+ {
+ while (head != nil && next(head) != x)
+ head = next(head);
+ return head;
+ }
+
+ template<class Node, class Next>
+ inline void
+ slist_splice_after(Node pos, Node before_first, Node before_last,
+ Next next)
+ {
+ if (pos != before_first && pos != before_last) {
+ Node first = next(before_first);
+ Node after = next(pos);
+ next(before_first) = next(before_last);
+ next(pos) = first;
+ next(before_last) = after;
+ }
+ }
+
+ template <class Node, class Next>
+ inline Node
+ slist_reverse(Node node, Node nil,
+ Next next)
+ {
+ Node result = node;
+ node = next(node);
+ next(result) = nil;
+ while(node) {
+ Node next = next(node);
+ next(node) = result;
+ result = node;
+ node = next;
+ }
+ return result;
+ }
+
+ template <class Node, class Next>
+ inline std::size_t
+ slist_size(Node head, Node nil,
+ Next next)
+ {
+ std::size_t s = 0;
+ for ( ; head != nil; head = next(head))
+ ++s;
+ return s;
+ }
+
+ template <class Next, class Data>
+ class slist_iterator_policies
+ {
+ public:
+ explicit slist_iterator_policies(const Next& n, const Data& d)
+ : m_next(n), m_data(d) { }
+
+ template <class Reference, class Node>
+ Reference dereference(type<Reference>, const Node& x) const
+ { return m_data(x); }
+
+ template <class Node>
+ void increment(Node& x) const
+ { x = m_next(x); }
+
+ template <class Node>
+ bool equal(Node& x, Node& y) const
+ { return x == y; }
+
+ protected:
+ Next m_next;
+ Data m_data;
+ };
+
+ //===========================================================================
+ // Doubly-Linked List Generic Implementation Functions
+
+ template <class Node, class Next, class Prev>
+ inline void
+ dlist_insert_before(Node pos, Node x,
+ Next next, Prev prev)
+ {
+ next(x) = pos;
+ prev(x) = prev(pos);
+ next(prev(pos)) = x;
+ prev(pos) = x;
+ }
+
+ template <class Node, class Next, class Prev>
+ void
+ dlist_remove(Node pos,
+ Next next, Prev prev)
+ {
+ Node next_node = next(pos);
+ Node prev_node = prev(pos);
+ next(prev_node) = next_node;
+ prev(next_node) = prev_node;
+ }
+
+ // This deletes every node in the list except the
+ // sentinel node.
+ template <class Node, class Delete>
+ inline void
+ dlist_clear(Node sentinel, Delete del)
+ {
+ Node i, tmp;
+ i = next(sentinel);
+ while (i != sentinel) {
+ tmp = i;
+ i = next(i);
+ del(tmp);
+ }
+ }
+
+ template <class Node>
+ inline bool
+ dlist_empty(Node dummy)
+ {
+ return next(dummy) == dummy;
+ }
+
+ template <class Node, class Next, class Prev>
+ void
+ dlist_transfer(Node pos, Node first, Node last,
+ Next next, Prev prev)
+ {
+ if (pos != last) {
+ // Remove [first,last) from its old position
+ next(prev(last)) = pos;
+ next(prev(first)) = last;
+ next(prev(pos)) = first;
+
+ // Splice [first,last) into its new position
+ Node tmp = prev(pos);
+ prev(pos) = prev(last);
+ prev(last) = prev(first);
+ prev(first) = tmp;
+ }
+ }
+
+ template <class Next, class Prev, class Data>
+ class dlist_iterator_policies
+ : public slist_iterator_policies<Next, Data>
+ {
+ typedef slist_iterator_policies<Next, Data> Base;
+ public:
+ template <class Node>
+ void decrement(Node& x) const
+ { x = m_prev(x); }
+
+ dlist_iterator_policies(Next n, Prev p, Data d)
+ : Base(n,d), m_prev(p) { }
+ protected:
+ Prev m_prev;
+ };
+
+ } // namespace detail
+} // namespace boost
+
+#endif // BOOST_LIST_BASE_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/permutation.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/permutation.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,205 @@
+// (C) Copyright Jeremy Siek 2001.
+// 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)
+
+#ifndef BOOST_PERMUTATION_HPP
+#define BOOST_PERMUTATION_HPP
+
+#include <vector>
+#include <memory>
+#include <functional>
+#include <algorithm>
+#include <boost/graph/detail/shadow_iterator.hpp>
+
+namespace boost {
+
+template <class Iter1, class Iter2>
+void permute_serial(Iter1 permuter, Iter1 last, Iter2 result)
+{
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ typedef std::ptrdiff_t D:
+#else
+ typedef typename std::iterator_traits<Iter1>::difference_type D;
+#endif
+
+ D n = 0;
+ while (permuter != last) {
+ std::swap(result[n], result[*permuter]);
+ ++n;
+ ++permuter;
+ }
+}
+
+template <class InIter, class RandIterP, class RandIterR>
+void permute_copy(InIter first, InIter last, RandIterP p, RandIterR result)
+{
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ typedef std::ptrdiff_t i = 0;
+#else
+ typename std::iterator_traits<RandIterP>::difference_type i = 0;
+#endif
+ for (; first != last; ++first, ++i)
+ result[p[i]] = *first;
+}
+
+namespace detail {
+
+template <class RandIter, class RandIterPerm, class D, class T>
+void permute_helper(RandIter first, RandIter last, RandIterPerm p, D, T)
+{
+ D i = 0, pi, n = last - first, cycle_start;
+ T tmp;
+ std::vector<int> visited(n, false);
+
+ while (i != n) { // continue until all elements have been processed
+ cycle_start = i;
+ tmp = first[i];
+ do { // walk around a cycle
+ pi = p[i];
+ visited[pi] = true;
+ std::swap(tmp, first[pi]);
+ i = pi;
+ } while (i != cycle_start);
+
+ // find the next cycle
+ for (i = 0; i < n; ++i)
+ if (visited[i] == false)
+ break;
+ }
+}
+
+} // namespace detail
+
+template <class RandIter, class RandIterPerm>
+void permute(RandIter first, RandIter last, RandIterPerm p)
+{
+ detail::permute_helper(first, last, p, last - first, *first);
+}
+
+
+// Knuth 1.3.3, Vol. 1 p 176
+// modified for zero-based arrays
+// time complexity?
+//
+// WARNING: T must be a signed integer!
+template <class PermIter>
+void invert_permutation(PermIter X, PermIter Xend)
+{
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ typedef std::ptrdiff_t T:
+#else
+ typedef typename std::iterator_traits<PermIter>::value_type T;
+#endif
+ T n = Xend - X;
+ T m = n;
+ T j = -1;
+
+ while (m > 0) {
+ T i = X[m-1] + 1;
+ if (i > 0) {
+ do {
+ X[m-1] = j - 1;
+ j = -m;
+ m = i;
+ i = X[m-1] + 1;
+ } while (i > 0);
+ i = j;
+ }
+ X[m-1] = -i - 1;
+ --m;
+ }
+}
+
+// Takes a "normal" permutation array (and its inverse), and turns it
+// into a BLAS-style permutation array (which can be thought of as a
+// serialized permutation).
+template <class Iter1, class Iter2, class Iter3>
+inline void serialize_permutation(Iter1 q, Iter1 q_end, Iter2 q_inv, Iter3 p)
+{
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ typedef std::ptrdiff_t P1;
+ typedef std::ptrdiff_t P2;
+ typedef std::ptrdiff_t D;
+#else
+ typedef typename std::iterator_traits<Iter1>::value_type P1;
+ typedef typename std::iterator_traits<Iter2>::value_type P2;
+ typedef typename std::iterator_traits<Iter1>::difference_type D;
+#endif
+ D n = q_end - q;
+ for (D i = 0; i < n; ++i) {
+ P1 qi = q[i];
+ P2 qii = q_inv[i];
+ *p++ = qii;
+ std::swap(q[i], q[qii]);
+ std::swap(q_inv[i], q_inv[qi]);
+ }
+}
+
+// Not used anymore, leaving it here for future reference.
+template <typename Iter, typename Compare>
+void merge_sort(Iter first, Iter last, Compare cmp)
+{
+ if (first + 1 < last) {
+ Iter mid = first + (last - first)/2;
+ merge_sort(first, mid, cmp);
+ merge_sort(mid, last, cmp);
+ std::inplace_merge(first, mid, last, cmp);
+ }
+}
+
+
+// time: N log N + 3N + ?
+// space: 2N
+template <class Iter, class IterP, class Cmp, class Alloc>
+inline void sortp(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc)
+{
+ typedef typename std::iterator_traits<IterP>::value_type P;
+ typedef typename std::iterator_traits<IterP>::difference_type D;
+ D n = last - first;
+ std::vector<P, Alloc> q(n);
+ for (D i = 0; i < n; ++i)
+ q[i] = i;
+ std::sort(make_shadow_iter(first, q.begin()),
+ make_shadow_iter(last, q.end()),
+ shadow_cmp<Cmp>(cmp));
+ invert_permutation(q.begin(), q.end());
+ std::copy(q.begin(), q.end(), p);
+}
+
+template <class Iter, class IterP, class Cmp>
+inline void sortp(Iter first, Iter last, IterP p, Cmp cmp)
+{
+ typedef typename std::iterator_traits<IterP>::value_type P;
+ sortp(first, last, p, cmp, std::allocator<P>());
+}
+
+template <class Iter, class IterP>
+inline void sortp(Iter first, Iter last, IterP p)
+{
+ typedef typename std::iterator_traits<Iter>::value_type T;
+ typedef typename std::iterator_traits<IterP>::value_type P;
+ sortp(first, last, p, std::less<T>(), std::allocator<P>());
+}
+
+template <class Iter, class IterP, class Cmp, class Alloc>
+inline void sortv(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc)
+{
+ typedef typename std::iterator_traits<IterP>::value_type P;
+ typedef typename std::iterator_traits<IterP>::difference_type D;
+ D n = last - first;
+ std::vector<P, Alloc> q(n), q_inv(n);
+ for (D i = 0; i < n; ++i)
+ q_inv[i] = i;
+ std::sort(make_shadow_iter(first, q_inv.begin()),
+ make_shadow_iter(last, q_inv.end()),
+ shadow_cmp<Cmp>(cmp));
+ std::copy(q_inv, q_inv.end(), q.begin());
+ invert_permutation(q.begin(), q.end());
+ serialize_permutation(q.begin(), q.end(), q_inv.end(), p);
+}
+
+
+} // namespace boost
+
+#endif // BOOST_PERMUTATION_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/read_graphviz_spirit.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/read_graphviz_spirit.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,610 @@
+// Copyright 2004-5 Trustees of Indiana University
+
+// 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)
+
+//
+// read_graphviz_spirit.hpp -
+// Initialize a model of the BGL's MutableGraph concept and an associated
+// collection of property maps using a graph expressed in the GraphViz
+// DOT Language.
+//
+// Based on the grammar found at:
+// http://www.graphviz.org/cvs/doc/info/lang.html
+//
+// See documentation for this code at:
+// http://www.boost.org/libs/graph/doc/read-graphviz.html
+//
+
+// Author: Ronald Garcia
+//
+
+#ifndef BOOST_READ_GRAPHVIZ_SPIRIT_HPP
+#define BOOST_READ_GRAPHVIZ_SPIRIT_HPP
+
+// Phoenix/Spirit set these limits to 3, but I need more.
+#define PHOENIX_LIMIT 6
+#define BOOST_SPIRIT_CLOSURE_LIMIT 6
+
+
+#include <boost/spirit/iterator/multi_pass.hpp>
+#include <boost/spirit/core.hpp>
+#include <boost/spirit/utility/confix.hpp>
+#include <boost/spirit/utility/distinct.hpp>
+#include <boost/spirit/utility/lists.hpp>
+#include <boost/spirit/utility/escape_char.hpp>
+#include <boost/spirit/attribute.hpp>
+#include <boost/spirit/dynamic.hpp>
+#include <boost/spirit/actor.hpp>
+#include <boost/spirit/phoenix.hpp>
+#include <boost/spirit/phoenix/binders.hpp>
+#include <boost/ref.hpp>
+#include <boost/function/function2.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/dynamic_property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/detail/workaround.hpp>
+#include <algorithm>
+#include <exception> // for std::exception
+#include <string>
+#include <vector>
+#include <set>
+#include <utility>
+#include <map>
+#include <boost/graph/graphviz.hpp>
+
+namespace phoenix {
+// Workaround: std::map::operator[] uses a different return type than all
+// other standard containers. Phoenix doesn't account for that.
+template <typename TK, typename T0, typename T1>
+struct binary_operator<index_op, std::map<TK,T0>, T1>
+{
+ typedef typename std::map<TK,T0>::mapped_type& result_type;
+ static result_type eval(std::map<TK,T0>& container, T1 const& index)
+ { return container[index]; }
+};
+} // namespace phoenix
+
+namespace boost {
+namespace detail {
+namespace graph {
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Application-specific type definitions
+/////////////////////////////////////////////////////////////////////////////
+
+typedef std::set<edge_t> edges_t;
+typedef std::set<node_t> nodes_t;
+typedef std::set<id_t> ids_t;
+typedef std::map<edge_t,ids_t> edge_map_t;
+typedef std::map<node_t,ids_t> node_map_t;
+typedef std::map<id_t,id_t> props_t;
+typedef std::map<id_t,props_t> subgraph_props_t;
+typedef boost::function2<void, id_t const&, id_t const&> actor_t;
+typedef std::vector<edge_t> edge_stack_t;
+typedef std::map<id_t,nodes_t> subgraph_nodes_t;
+typedef std::map<id_t,edges_t> subgraph_edges_t;
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Stack frames used by semantic actions
+/////////////////////////////////////////////////////////////////////////////
+struct id_closure : boost::spirit::closure<id_closure, node_t> {
+ member1 name;
+};
+
+
+struct node_id_closure : boost::spirit::closure<node_id_closure, node_t> {
+ member1 name;
+};
+
+struct attr_list_closure : boost::spirit::closure<attr_list_closure, actor_t> {
+ member1 prop_actor;
+};
+
+struct property_closure : boost::spirit::closure<property_closure, id_t, id_t> {
+ member1 key;
+ member2 value;
+};
+
+struct data_stmt_closure : boost::spirit::closure<data_stmt_closure,
+ nodes_t,nodes_t,edge_stack_t,bool,node_t> {
+ member1 sources;
+ member2 dests;
+ member3 edge_stack;
+ member4 saw_node;
+ member5 active_node;
+};
+
+struct subgraph_closure : boost::spirit::closure<subgraph_closure,
+ nodes_t, edges_t, node_t> {
+ member1 nodes;
+ member2 edges;
+ member3 name;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Grammar and Actions for the DOT Language
+/////////////////////////////////////////////////////////////////////////////
+
+// Grammar for a dot file.
+struct dot_grammar : public boost::spirit::grammar<dot_grammar> {
+ mutate_graph& graph_;
+ explicit dot_grammar(mutate_graph& graph) : graph_(graph) { }
+
+ template <class ScannerT>
+ struct definition {
+
+ definition(dot_grammar const& self) : self(self), subgraph_depth(0),
+ keyword_p("0-9a-zA-Z_") {
+ using namespace boost::spirit;
+ using namespace phoenix;
+
+ // RG - Future Work
+ // - Handle multi-line strings using \ line continuation
+ // - Make keywords case insensitive
+ ID
+ = ( lexeme_d[((alpha_p | ch_p('_')) >> *(alnum_p | ch_p('_')))]
+ | real_p
+ | lexeme_d[confix_p('"', *c_escape_ch_p, '"')]
+ | comment_nest_p('<', '>')
+ )[ID.name = construct_<std::string>(arg1,arg2)]
+ ;
+
+ a_list
+ = list_p( ID[(a_list.key = arg1),
+ (a_list.value = "true")
+ ]
+ >> !( ch_p('=')
+ >> ID[a_list.value = arg1])
+ [phoenix::bind(&definition::call_prop_actor)
+ (var(*this),a_list.key,a_list.value)],!ch_p(','));
+
+ attr_list = +(ch_p('[') >> !a_list >> ch_p(']'));
+
+ // RG - disregard port id's for now.
+ port_location
+ = (ch_p(':') >> ID)
+ | (ch_p(':') >> ch_p('(') >> ID >> ch_p(',') >> ID >> ch_p(')'))
+ ;
+
+ port_angle = ch_p('@') >> ID;
+
+ port
+ = port_location >> (!port_angle)
+ | port_angle >> (!port_location);
+
+
+ node_id
+ = ( ID[node_id.name = arg1] >> (!port) )
+ [phoenix::bind(&definition::memoize_node)(var(*this))];
+
+ graph_stmt
+ = (ID[graph_stmt.key = arg1] >>
+ ch_p('=') >>
+ ID[graph_stmt.value = arg1])
+ [phoenix::bind(&definition::call_graph_prop)
+ (var(*this),graph_stmt.key,graph_stmt.value)]
+ ; // Graph property.
+
+ attr_stmt
+ = (as_lower_d[keyword_p("graph")]
+ >> attr_list(actor_t(phoenix::bind(&definition::default_graph_prop)
+ (var(*this),arg1,arg2))))
+ | (as_lower_d[keyword_p("node")]
+ >> attr_list(actor_t(phoenix::bind(&definition::default_node_prop)
+ (var(*this),arg1,arg2))))
+ | (as_lower_d[keyword_p("edge")]
+ >> attr_list(actor_t(phoenix::bind(&definition::default_edge_prop)
+ (var(*this),arg1,arg2))))
+ ;
+
+ // edge_head is set depending on the graph type (directed/undirected)
+ edgeop = ch_p('-') >> ch_p(boost::ref(edge_head));
+
+ edgeRHS
+ = +( edgeop[(data_stmt.sources = data_stmt.dests),
+ (data_stmt.dests = construct_<nodes_t>())]
+ >> ( subgraph[data_stmt.dests = arg1]
+ | node_id[phoenix::bind(&definition::insert_node)
+ (var(*this),data_stmt.dests,arg1)]
+ )
+ [phoenix::bind(&definition::activate_edge)
+ (var(*this),data_stmt.sources,data_stmt.dests,
+ var(edges), var(default_edge_props))]
+ );
+
+
+ // To avoid backtracking, edge, node, and subgraph statements are
+ // processed as one nonterminal.
+ data_stmt
+ = ( subgraph[(data_stmt.dests = arg1),// will get moved in rhs
+ (data_stmt.saw_node = false)]
+ | node_id[(phoenix::bind(&definition::insert_node)
+ (var(*this),data_stmt.dests,arg1)),
+ (data_stmt.saw_node = true),
+#ifdef BOOST_GRAPH_DEBUG
+ (std::cout << val("AcTive Node: ") << arg1 << "\n"),
+#endif // BOOST_GRAPH_DEBUG
+ (data_stmt.active_node = arg1)]
+ ) >> if_p(edgeRHS)[
+ !attr_list(
+ actor_t(phoenix::bind(&definition::edge_prop)
+ (var(*this),arg1,arg2)))
+ ].else_p[
+ if_p(data_stmt.saw_node)[
+ !attr_list(
+ actor_t(phoenix::bind(&definition::node_prop)
+ (var(*this),arg1,arg2)))
+ ] // otherwise it's a subgraph, nothing more to do.
+ ];
+
+
+ stmt
+ = graph_stmt
+ | attr_stmt
+ | data_stmt
+ ;
+
+ stmt_list = *( stmt >> !ch_p(';') );
+
+ subgraph
+ = !( as_lower_d[keyword_p("subgraph")]
+ >> (!ID[(subgraph.name = arg1),
+ (subgraph.nodes = (var(subgraph_nodes))[arg1]),
+ (subgraph.edges = (var(subgraph_edges))[arg1])])
+ )
+ >> ch_p('{')[++var(subgraph_depth)]
+ >> stmt_list
+ >> ch_p('}')[--var(subgraph_depth)]
+ [(var(subgraph_nodes))[subgraph.name] = subgraph.nodes]
+ [(var(subgraph_edges))[subgraph.name] = subgraph.edges]
+
+ | as_lower_d[keyword_p("subgraph")]
+ >> ID[(subgraph.nodes = (var(subgraph_nodes))[arg1]),
+ (subgraph.edges = (var(subgraph_edges))[arg1])]
+ ;
+
+ the_grammar
+ = (!as_lower_d[keyword_p("strict")])
+ >> ( as_lower_d[keyword_p("graph")][
+ (var(edge_head) = '-'),
+ (phoenix::bind(&definition::check_undirected)(var(*this)))]
+ | as_lower_d[keyword_p("digraph")][
+ (var(edge_head) = '>'),
+ (phoenix::bind(&definition::check_directed)(var(*this)))]
+ )
+ >> (!ID) >> ch_p('{') >> stmt_list >> ch_p('}');
+
+ } // definition()
+
+ typedef boost::spirit::rule<ScannerT> rule_t;
+
+ rule_t const& start() const { return the_grammar; }
+
+
+ //
+ // Semantic actions
+ //
+
+ void check_undirected() {
+ if(self.graph_.is_directed())
+ throw boost::undirected_graph_error();
+ }
+
+ void check_directed() {
+ if(!self.graph_.is_directed())
+ throw boost::directed_graph_error();
+ }
+
+ void memoize_node() {
+ id_t const& node = node_id.name();
+ props_t& node_props = default_node_props;
+
+ if(nodes.find(node) == nodes.end()) {
+ nodes.insert(node);
+ self.graph_.do_add_vertex(node);
+
+ node_map.insert(std::make_pair(node,ids_t()));
+
+#ifdef BOOST_GRAPH_DEBUG
+ std::cout << "Add new node " << node << std::endl;
+#endif // BOOST_GRAPH_DEBUG
+ // Set the default properties for this edge
+ // RG: Here I would actually set the properties
+ for(props_t::iterator i = node_props.begin();
+ i != node_props.end(); ++i) {
+ set_node_property(node,i->first,i->second);
+ }
+ if(subgraph_depth > 0) {
+ subgraph.nodes().insert(node);
+ // Set the subgraph's default properties as well
+ props_t& props = subgraph_node_props[subgraph.name()];
+ for(props_t::iterator i = props.begin(); i != props.end(); ++i) {
+ set_node_property(node,i->first,i->second);
+ }
+ }
+ } else {
+#ifdef BOOST_GRAPH_DEBUG
+ std::cout << "See node " << node << std::endl;
+#endif // BOOST_GRAPH_DEBUG
+ }
+ }
+
+ void activate_edge(nodes_t& sources, nodes_t& dests, edges_t& edges,
+ props_t& edge_props) {
+ edge_stack_t& edge_stack = data_stmt.edge_stack();
+ for(nodes_t::iterator i = sources.begin(); i != sources.end(); ++i) {
+ for(nodes_t::iterator j = dests.begin(); j != dests.end(); ++j) {
+ // Create the edge and push onto the edge stack.
+#ifdef BOOST_GRAPH_DEBUG
+ std::cout << "Edge " << *i << " to " << *j << std::endl;
+#endif // BOOST_GRAPH_DEBUG
+
+ edge_t edge = edge_t::new_edge();
+ edge_stack.push_back(edge);
+ edges.insert(edge);
+ edge_map.insert(std::make_pair(edge,ids_t()));
+
+ // Add the real edge.
+ self.graph_.do_add_edge(edge, *i, *j);
+
+ // Set the default properties for this edge
+ for(props_t::iterator k = edge_props.begin();
+ k != edge_props.end(); ++k) {
+ set_edge_property(edge,k->first,k->second);
+ }
+ if(subgraph_depth > 0) {
+ subgraph.edges().insert(edge);
+ // Set the subgraph's default properties as well
+ props_t& props = subgraph_edge_props[subgraph.name()];
+ for(props_t::iterator k = props.begin(); k != props.end(); ++k) {
+ set_edge_property(edge,k->first,k->second);
+ }
+ }
+ }
+ }
+ }
+
+ // node_prop - Assign the property for the current active node.
+ void node_prop(id_t const& key, id_t const& value) {
+ node_t& active_object = data_stmt.active_node();
+ set_node_property(active_object, key, value);
+ }
+
+ // edge_prop - Assign the property for the current active edges.
+ void edge_prop(id_t const& key, id_t const& value) {
+ edge_stack_t const& active_edges_ = data_stmt.edge_stack();
+ for (edge_stack_t::const_iterator i = active_edges_.begin();
+ i != active_edges_.end(); ++i) {
+ set_edge_property(*i,key,value);
+ }
+ }
+
+ // default_graph_prop - Store as a graph property.
+ void default_graph_prop(id_t const& key, id_t const& value) {
+#ifdef BOOST_GRAPH_DEBUG
+ std::cout << key << " = " << value << std::endl;
+#endif // BOOST_GRAPH_DEBUG
+ self.graph_.set_graph_property(key, value);
+ }
+
+ // default_node_prop - declare default properties for any future new nodes
+ void default_node_prop(id_t const& key, id_t const& value) {
+ nodes_t& nodes_ =
+ subgraph_depth == 0 ? nodes : subgraph.nodes();
+ props_t& node_props_ =
+ subgraph_depth == 0 ?
+ default_node_props :
+ subgraph_node_props[subgraph.name()];
+
+ // add this to the selected list of default node properties.
+ node_props_[key] = value;
+ // for each node, set its property to default-constructed value
+ // if it hasn't been set already.
+ // set the dynamic property map value
+ for(nodes_t::iterator i = nodes_.begin(); i != nodes_.end(); ++i)
+ if(node_map[*i].find(key) == node_map[*i].end()) {
+ set_node_property(*i,key,id_t());
+ }
+ }
+
+ // default_edge_prop - declare default properties for any future new edges
+ void default_edge_prop(id_t const& key, id_t const& value) {
+ edges_t& edges_ =
+ subgraph_depth == 0 ? edges : subgraph.edges();
+ props_t& edge_props_ =
+ subgraph_depth == 0 ?
+ default_edge_props :
+ subgraph_edge_props[subgraph.name()];
+
+ // add this to the list of default edge properties.
+ edge_props_[key] = value;
+ // for each edge, set its property to be empty string
+ // set the dynamic property map value
+ for(edges_t::iterator i = edges_.begin(); i != edges_.end(); ++i)
+ if(edge_map[*i].find(key) == edge_map[*i].end())
+ set_edge_property(*i,key,id_t());
+ }
+
+ // helper function
+ void insert_node(nodes_t& nodes, id_t const& name) {
+ nodes.insert(name);
+ }
+
+ void call_prop_actor(std::string const& lhs, std::string const& rhs) {
+ actor_t& actor = attr_list.prop_actor();
+ // If first and last characters of the rhs are double-quotes,
+ // remove them.
+ if (!rhs.empty() && rhs[0] == '"' && rhs[rhs.size() - 1] == '"')
+ actor(lhs, rhs.substr(1, rhs.size()-2));
+ else
+ actor(lhs,rhs);
+ }
+
+ void call_graph_prop(std::string const& lhs, std::string const& rhs) {
+ // If first and last characters of the rhs are double-quotes,
+ // remove them.
+ if (!rhs.empty() && rhs[0] == '"' && rhs[rhs.size() - 1] == '"')
+ this->default_graph_prop(lhs, rhs.substr(1, rhs.size()-2));
+ else
+ this->default_graph_prop(lhs,rhs);
+ }
+
+ void set_node_property(node_t const& node, id_t const& key,
+ id_t const& value) {
+
+ // Add the property key to the "set" table to avoid default overwrite
+ node_map[node].insert(key);
+ // Set the user's property map
+ self.graph_.set_node_property(key, node, value);
+#ifdef BOOST_GRAPH_DEBUG
+ // Tell the world
+ std::cout << node << ": " << key << " = " << value << std::endl;
+#endif // BOOST_GRAPH_DEBUG
+ }
+
+ void set_edge_property(edge_t const& edge, id_t const& key,
+ id_t const& value) {
+
+ // Add the property key to the "set" table to avoid default overwrite
+ edge_map[edge].insert(key);
+ // Set the user's property map
+ self.graph_.set_edge_property(key, edge, value);
+#ifdef BOOST_GRAPH_DEBUG
+ // Tell the world
+#if 0 // RG - edge representation changed,
+ std::cout << "(" << edge.first << "," << edge.second << "): "
+#else
+ std::cout << "an edge: "
+#endif // 0
+ << key << " = " << value << std::endl;
+#endif // BOOST_GRAPH_DEBUG
+ }
+
+ // Variables explicitly initialized
+ dot_grammar const& self;
+ // if subgraph_depth > 0, then we're processing a subgraph.
+ int subgraph_depth;
+
+ // Keywords;
+ const boost::spirit::distinct_parser<> keyword_p;
+ //
+ // rules that make up the grammar
+ //
+ boost::spirit::rule<ScannerT,id_closure::context_t> ID;
+ boost::spirit::rule<ScannerT,property_closure::context_t> a_list;
+ boost::spirit::rule<ScannerT,attr_list_closure::context_t> attr_list;
+ rule_t port_location;
+ rule_t port_angle;
+ rule_t port;
+ boost::spirit::rule<ScannerT,node_id_closure::context_t> node_id;
+ boost::spirit::rule<ScannerT,property_closure::context_t> graph_stmt;
+ rule_t attr_stmt;
+ boost::spirit::rule<ScannerT,data_stmt_closure::context_t> data_stmt;
+ boost::spirit::rule<ScannerT,subgraph_closure::context_t> subgraph;
+ rule_t edgeop;
+ rule_t edgeRHS;
+ rule_t stmt;
+ rule_t stmt_list;
+ rule_t the_grammar;
+
+
+ // The grammar uses edge_head to dynamically set the syntax for edges
+ // directed graphs: edge_head = '>', and so edgeop = "->"
+ // undirected graphs: edge_head = '-', and so edgeop = "--"
+ char edge_head;
+
+
+ //
+ // Support data structures
+ //
+
+ nodes_t nodes; // list of node names seen
+ edges_t edges; // list of edges seen
+ node_map_t node_map; // remember the properties set for each node
+ edge_map_t edge_map; // remember the properties set for each edge
+
+ subgraph_nodes_t subgraph_nodes; // per-subgraph lists of nodes
+ subgraph_edges_t subgraph_edges; // per-subgraph lists of edges
+
+ props_t default_node_props; // global default node properties
+ props_t default_edge_props; // global default edge properties
+ subgraph_props_t subgraph_node_props; // per-subgraph default node properties
+ subgraph_props_t subgraph_edge_props; // per-subgraph default edge properties
+ }; // struct definition
+}; // struct dot_grammar
+
+
+
+//
+// dot_skipper - GraphViz whitespace and comment skipper
+//
+struct dot_skipper : public boost::spirit::grammar<dot_skipper>
+{
+ dot_skipper() {}
+
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(dot_skipper const& /*self*/) {
+ using namespace boost::spirit;
+ using namespace phoenix;
+ // comment forms
+ skip = eol_p >> comment_p("#")
+ | space_p
+ | comment_p("//")
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
+ | confix_p(str_p("/*") ,*anychar_p, str_p("*/"))
+#else
+ | confix_p("/*" ,*anychar_p, "*/")
+#endif
+ ;
+
+#ifdef BOOST_SPIRIT_DEBUG
+ BOOST_SPIRIT_DEBUG_RULE(skip);
+#endif
+ }
+
+ boost::spirit::rule<ScannerT> skip;
+ boost::spirit::rule<ScannerT> const&
+ start() const { return skip; }
+ }; // definition
+}; // dot_skipper
+
+} // namespace graph
+} // namespace detail
+
+template <typename MultiPassIterator, typename MutableGraph>
+bool read_graphviz(MultiPassIterator begin, MultiPassIterator end,
+ MutableGraph& graph, dynamic_properties& dp,
+ std::string const& node_id = "node_id") {
+ using namespace boost;
+ using namespace boost::spirit;
+
+ typedef MultiPassIterator iterator_t;
+ typedef skip_parser_iteration_policy< boost::detail::graph::dot_skipper>
+ iter_policy_t;
+ typedef scanner_policies<iter_policy_t> scanner_policies_t;
+ typedef scanner<iterator_t, scanner_policies_t> scanner_t;
+
+ ::boost::detail::graph::mutate_graph_impl<MutableGraph>
+ m_graph(graph, dp, node_id);
+
+ ::boost::detail::graph::dot_grammar p(m_graph);
+ ::boost::detail::graph::dot_skipper skip_p;
+
+ iter_policy_t iter_policy(skip_p);
+ scanner_policies_t policies(iter_policy);
+
+ scanner_t scan(begin, end, policies);
+
+ return p.parse(scan);
+}
+
+} // namespace boost
+
+#endif // BOOST_READ_GRAPHVIZ_SPIRIT_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/self_avoiding_walk.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/self_avoiding_walk.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,418 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_SELF_AVOIDING_WALK_HPP
+#define BOOST_SELF_AVOIDING_WALK_HPP
+
+/*
+ This file defines necessary components for SAW.
+
+ mesh language: (defined by myself to clearify what is what)
+ A triangle in mesh is called an triangle.
+ An edge in mesh is called an line.
+ A vertex in mesh is called a point.
+
+ A triangular mesh corresponds to a graph in which a vertex is a
+ triangle and an edge(u, v) stands for triangle u and triangle v
+ share an line.
+
+ After this point, a vertex always refers to vertex in graph,
+ therefore it is a traingle in mesh.
+
+ */
+
+#include <utility>
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map.hpp>
+
+#define SAW_SENTINAL -1
+
+namespace boost {
+
+ template <class T1, class T2, class T3>
+ struct triple {
+ T1 first;
+ T2 second;
+ T3 third;
+ triple(const T1& a, const T2& b, const T3& c) : first(a), second(b), third(c) {}
+ triple() : first(SAW_SENTINAL), second(SAW_SENTINAL), third(SAW_SENTINAL) {}
+ };
+
+ typedef triple<int, int, int> Triple;
+
+ /* Define a vertex property which has a triangle inside. Triangle is
+ represented by a triple. */
+ struct triangle_tag { enum { num = 100 }; };
+ typedef property<triangle_tag,Triple> triangle_property;
+
+ /* Define an edge property with a line. A line is represented by a
+ pair. This is not required for SAW though.
+ */
+ struct line_tag { enum { num = 101 }; };
+ template <class T> struct line_property
+ : public property<line_tag, std::pair<T,T> > { };
+
+ /*Precondition: Points in a Triangle are in order */
+ template <class Triangle, class Line>
+ inline void get_sharing(const Triangle& a, const Triangle& b, Line& l)
+ {
+ l.first = SAW_SENTINAL;
+ l.second = SAW_SENTINAL;
+
+ if ( a.first == b.first ) {
+ l.first = a.first;
+ if ( a.second == b.second || a.second == b.third )
+ l.second = a.second;
+ else if ( a.third == b.second || a.third == b.third )
+ l.second = a.third;
+
+ } else if ( a.first == b.second ) {
+ l.first = a.first;
+ if ( a.second == b.third )
+ l.second = a.second;
+ else if ( a.third == b.third )
+ l.second = a.third;
+
+ } else if ( a.first == b.third ) {
+ l.first = a.first;
+
+
+ } else if ( a.second == b.first ) {
+ l.first = a.second;
+ if ( a.third == b.second || a.third == b.third )
+ l.second = a.third;
+
+ } else if ( a.second == b.second ) {
+ l.first = a.second;
+ if ( a.third == b.third )
+ l.second = a.third;
+
+ } else if ( a.second == b.third ) {
+ l.first = a.second;
+
+
+ } else if ( a.third == b.first
+ || a.third == b.second
+ || a.third == b.third )
+ l.first = a.third;
+
+ /*Make it in order*/
+ if ( l.first > l.second ) {
+ typename Line::first_type i = l.first;
+ l.first = l.second;
+ l.second = i;
+ }
+
+ }
+
+ template <class TriangleDecorator, class Vertex, class Line>
+ struct get_vertex_sharing {
+ typedef std::pair<Vertex, Line> Pair;
+ get_vertex_sharing(const TriangleDecorator& _td) : td(_td) {}
+ inline Line operator()(const Vertex& u, const Vertex& v) const {
+ Line l;
+ get_sharing(td[u], td[v], l);
+ return l;
+ }
+ inline Line operator()(const Pair& u, const Vertex& v) const {
+ Line l;
+ get_sharing(td[u.first], td[v], l);
+ return l;
+ }
+ inline Line operator()(const Pair& u, const Pair& v) const {
+ Line l;
+ get_sharing(td[u.first], td[v.first], l);
+ return l;
+ }
+ TriangleDecorator td;
+ };
+
+ /* HList has to be a handle of data holder so that pass-by-value is
+ * in right logic.
+ *
+ * The element of HList is a pair of vertex and line. (remember a
+ * line is a pair of two ints.). That indicates the walk w from
+ * current vertex is across line. (If the first of line is -1, it is
+ * a point though.
+ */
+ template < class TriangleDecorator, class HList, class IteratorD>
+ class SAW_visitor
+ : public bfs_visitor<>, public dfs_visitor<>
+ {
+ typedef typename boost::property_traits<IteratorD>::value_type iter;
+ /*use boost shared_ptr*/
+ typedef typename HList::element_type::value_type::second_type Line;
+ public:
+
+ typedef tree_edge_tag category;
+
+ inline SAW_visitor(TriangleDecorator _td, HList _hlist, IteratorD ia)
+ : td(_td), hlist(_hlist), iter_d(ia) {}
+
+ template <class Vertex, class Graph>
+ inline void start_vertex(Vertex v, Graph&) {
+ Line l1;
+ l1.first = SAW_SENTINAL;
+ l1.second = SAW_SENTINAL;
+ hlist->push_front(std::make_pair(v, l1));
+ iter_d[v] = hlist->begin();
+ }
+
+ /*Several symbols:
+ w(i): i-th triangle in walk w
+ w(i) |- w(i+1): w enter w(i+1) from w(i) over a line
+ w(i) ~> w(i+1): w enter w(i+1) from w(i) over a point
+ w(i) -> w(i+1): w enter w(i+1) from w(i)
+ w(i) ^ w(i+1): the line or point w go over from w(i) to w(i+1)
+ */
+ template <class Edge, class Graph>
+ bool tree_edge(Edge e, Graph& G) {
+ using std::make_pair;
+ typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
+ Vertex tau = target(e, G);
+ Vertex i = source(e, G);
+
+ get_vertex_sharing<TriangleDecorator, Vertex, Line> get_sharing_line(td);
+
+ Line tau_i = get_sharing_line(tau, i);
+
+ iter w_end = hlist->end();
+
+ iter w_i = iter_d[i];
+
+ iter w_i_m_1 = w_i;
+ iter w_i_p_1 = w_i;
+
+ /*----------------------------------------------------------
+ * true false
+ *==========================================================
+ *a w(i-1) |- w(i) w(i-1) ~> w(i) or w(i-1) is null
+ *----------------------------------------------------------
+ *b w(i) |- w(i+1) w(i) ~> w(i+1) or no w(i+1) yet
+ *----------------------------------------------------------
+ */
+
+ bool a = false, b = false;
+
+ --w_i_m_1;
+ ++w_i_p_1;
+ b = ( w_i->second.first != SAW_SENTINAL );
+
+ if ( w_i_m_1 != w_end ) {
+ a = ( w_i_m_1->second.first != SAW_SENTINAL );
+ }
+
+ if ( a ) {
+
+ if ( b ) {
+ /*Case 1:
+
+ w(i-1) |- w(i) |- w(i+1)
+ */
+ Line l1 = get_sharing_line(*w_i_m_1, tau);
+
+ iter w_i_m_2 = w_i_m_1;
+ --w_i_m_2;
+
+ bool c = true;
+
+ if ( w_i_m_2 != w_end ) {
+ c = w_i_m_2->second != l1;
+ }
+
+ if ( c ) { /* w(i-1) ^ tau != w(i-2) ^ w(i-1) */
+ /*extension: w(i-1) -> tau |- w(i) */
+ w_i_m_1->second = l1;
+ /*insert(pos, const T&) is to insert before pos*/
+ iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
+
+ } else { /* w(i-1) ^ tau == w(i-2) ^ w(i-1) */
+ /*must be w(i-2) ~> w(i-1) */
+
+ bool d = true;
+ //need to handle the case when w_i_p_1 is null
+ Line l3 = get_sharing_line(*w_i_p_1, tau);
+ if ( w_i_p_1 != w_end )
+ d = w_i_p_1->second != l3;
+ if ( d ) { /* w(i+1) ^ tau != w(i+1) ^ w(i+2) */
+ /*extension: w(i) |- tau -> w(i+1) */
+ w_i->second = tau_i;
+ iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l3));
+ } else { /* w(i+1) ^ tau == w(i+1) ^ w(i+2) */
+ /*must be w(1+1) ~> w(i+2) */
+ Line l5 = get_sharing_line(*w_i_m_1, *w_i_p_1);
+ if ( l5 != w_i_p_1->second ) { /* w(i-1) ^ w(i+1) != w(i+1) ^ w(i+2) */
+ /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1) */
+ w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
+ iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
+ w_i->second = w_i_m_1->second;
+ w_i_m_1->second = l5;
+ iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
+ hlist->erase(w_i_m_1);
+ } else {
+ /*mesh is tetrahedral*/
+ // dont know what that means.
+ ;
+ }
+ }
+
+ }
+ } else {
+ /*Case 2:
+
+ w(i-1) |- w(i) ~> w(1+1)
+ */
+
+ if ( w_i->second.second == tau_i.first
+ || w_i->second.second == tau_i.second ) { /*w(i) ^ w(i+1) < w(i) ^ tau*/
+ /*extension: w(i) |- tau -> w(i+1) */
+ w_i->second = tau_i;
+ Line l1 = get_sharing_line(*w_i_p_1, tau);
+ iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
+ } else { /*w(i) ^ w(i+1) !< w(i) ^ tau*/
+ Line l1 = get_sharing_line(*w_i_m_1, tau);
+ bool c = true;
+ iter w_i_m_2 = w_i_m_1;
+ --w_i_m_2;
+ if ( w_i_m_2 != w_end )
+ c = l1 != w_i_m_2->second;
+ if (c) { /*w(i-1) ^ tau != w(i-2) ^ w(i-1)*/
+ /*extension: w(i-1) -> tau |- w(i)*/
+ w_i_m_1->second = l1;
+ iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
+ } else { /*w(i-1) ^ tau == w(i-2) ^ w(i-1)*/
+ /*must be w(i-2)~>w(i-1)*/
+ /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1)*/
+ w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
+ iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
+ w_i->second = w_i_m_1->second;
+ w_i_m_1->second = get_sharing_line(*w_i_m_1, *w_i_p_1);
+ iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
+ hlist->erase(w_i_m_1);
+ }
+
+ }
+
+ }
+
+ } else {
+
+ if ( b ) {
+ /*Case 3:
+
+ w(i-1) ~> w(i) |- w(i+1)
+ */
+ bool c = false;
+ if ( w_i_m_1 != w_end )
+ c = ( w_i_m_1->second.second == tau_i.first)
+ || ( w_i_m_1->second.second == tau_i.second);
+
+ if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau*/
+ /* extension: w(i-1) -> tau |- w(i) */
+ if ( w_i_m_1 != w_end )
+ w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
+ iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
+ } else {
+ bool d = true;
+ Line l1;
+ l1.first = SAW_SENTINAL;
+ l1.second = SAW_SENTINAL;
+ if ( w_i_p_1 != w_end ) {
+ l1 = get_sharing_line(*w_i_p_1, tau);
+ d = l1 != w_i_p_1->second;
+ }
+ if (d) { /*w(i+1) ^ tau != w(i+1) ^ w(i+2)*/
+ /*extension: w(i) |- tau -> w(i+1) */
+ w_i->second = tau_i;
+ iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
+ } else {
+ /*must be w(i+1) ~> w(i+2)*/
+ /*extension: w(i-1) -> w(i+1) |- w(i) |- tau -> w(i+2) */
+ iter w_i_p_2 = w_i_p_1;
+ ++w_i_p_2;
+
+ w_i_p_1->second = w_i->second;
+ iter_d[i] = hlist->insert(w_i_p_2, make_pair(i, tau_i));
+ hlist->erase(w_i);
+ Line l2 = get_sharing_line(*w_i_p_2, tau);
+ iter_d[tau] = hlist->insert(w_i_p_2, make_pair(tau, l2));
+ }
+ }
+
+ } else {
+ /*Case 4:
+
+ w(i-1) ~> w(i) ~> w(i+1)
+
+ */
+ bool c = false;
+ if ( w_i_m_1 != w_end ) {
+ c = (w_i_m_1->second.second == tau_i.first)
+ || (w_i_m_1->second.second == tau_i.second);
+ }
+ if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau */
+ /*extension: w(i-1) -> tau |- w(i) */
+ if ( w_i_m_1 != w_end )
+ w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
+ iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
+ } else {
+ /*extension: w(i) |- tau -> w(i+1) */
+ w_i->second = tau_i;
+ Line l1;
+ l1.first = SAW_SENTINAL;
+ l1.second = SAW_SENTINAL;
+ if ( w_i_p_1 != w_end )
+ l1 = get_sharing_line(*w_i_p_1, tau);
+ iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
+ }
+ }
+
+ }
+
+ return true;
+ }
+
+ protected:
+ TriangleDecorator td; /*a decorator for vertex*/
+ HList hlist;
+ /*This must be a handle of list to record the SAW
+ The element type of the list is pair<Vertex, Line>
+ */
+
+ IteratorD iter_d;
+ /*Problem statement: Need a fast access to w for triangle i.
+ *Possible solution: mantain an array to record.
+ iter_d[i] will return an iterator
+ which points to w(i), where i is a vertex
+ representing triangle i.
+ */
+ };
+
+ template <class Triangle, class HList, class Iterator>
+ inline
+ SAW_visitor<Triangle, HList, Iterator>
+ visit_SAW(Triangle t, HList hl, Iterator i) {
+ return SAW_visitor<Triangle, HList, Iterator>(t, hl, i);
+ }
+
+ template <class Tri, class HList, class Iter>
+ inline
+ SAW_visitor< random_access_iterator_property_map<Tri*,Tri,Tri&>,
+ HList, random_access_iterator_property_map<Iter*,Iter,Iter&> >
+ visit_SAW_ptr(Tri* t, HList hl, Iter* i) {
+ typedef random_access_iterator_property_map<Tri*,Tri,Tri&> TriD;
+ typedef random_access_iterator_property_map<Iter*,Iter,Iter&> IterD;
+ return SAW_visitor<TriD, HList, IterD>(t, hl, i);
+ }
+
+ // should also have combo's of pointers, and also const :(
+
+}
+
+#endif /*BOOST_SAW_H*/
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/set_adaptor.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/set_adaptor.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,117 @@
+// (C) Copyright Jeremy Siek 2001.
+// 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)
+
+#ifndef BOOST_SET_ADAPTOR_HPP
+#define BOOST_SET_ADAPTOR_HPP
+
+#include <set>
+
+namespace boost {
+
+ template <class K, class C, class A, class T>
+ bool set_contains(const std::set<K,C,A>& s, const T& x) {
+ return s.find(x) != s.end();
+ }
+
+ template <class K, class C, class A>
+ bool set_equal(const std::set<K,C,A>& x,
+ const std::set<K,C,A>& y)
+ {
+ return x == y;
+ }
+
+ // Not the same as lexicographical_compare_3way applied to std::set.
+ // this is equivalent semantically to bitset::operator<()
+ template <class K, class C, class A>
+ int set_lex_order(const std::set<K,C,A>& x,
+ const std::set<K,C,A>& y)
+ {
+ typename std::set<K,C,A>::iterator
+ xi = x.begin(), yi = y.begin(), xend = x.end(), yend = y.end();
+ for (; xi != xend && yi != yend; ++xi, ++yi) {
+ if (*xi < *yi)
+ return 1;
+ else if (*yi < *xi)
+ return -1;
+ }
+ if (xi == xend)
+ return (yi == yend) ? 0 : -1;
+ else
+ return 1;
+ }
+
+ template <class K, class C, class A>
+ void set_clear(std::set<K,C,A>& x) {
+ x.clear();
+ }
+
+ template <class K, class C, class A>
+ bool set_empty(const std::set<K,C,A>& x) {
+ return x.empty();
+ }
+
+ template <class K, class C, class A, class T>
+ void set_insert(std::set<K,C,A>& x, const T& a) {
+ x.insert(a);
+ }
+
+ template <class K, class C, class A, class T>
+ void set_remove(std::set<K,C,A>& x, const T& a) {
+ x.erase(a);
+ }
+
+ template <class K, class C, class A>
+ void set_intersect(const std::set<K,C,A>& x,
+ const std::set<K,C,A>& y,
+ std::set<K,C,A>& z)
+ {
+ z.clear();
+ std::set_intersection(x.begin(), x.end(),
+ y.begin(), y.end(),
+ std::inserter(z));
+ }
+
+ template <class K, class C, class A>
+ void set_union(const std::set<K,C,A>& x,
+ const std::set<K,C,A>& y,
+ std::set<K,C,A>& z)
+ {
+ z.clear();
+ std::set_union(x.begin(), x.end(),
+ y.begin(), y.end(),
+ std::inserter(z));
+ }
+
+ template <class K, class C, class A>
+ void set_difference(const std::set<K,C,A>& x,
+ const std::set<K,C,A>& y,
+ std::set<K,C,A>& z)
+ {
+ z.clear();
+ std::set_difference(x.begin(), x.end(),
+ y.begin(), y.end(),
+ std::inserter(z, z.begin()));
+ }
+
+ template <class K, class C, class A>
+ bool set_subset(const std::set<K,C,A>& x,
+ const std::set<K,C,A>& y)
+ {
+ return std::includes(x.begin(), x.end(), y.begin(), y.end());
+ }
+
+ // Shit, can't implement this without knowing the size of the
+ // universe.
+ template <class K, class C, class A>
+ void set_compliment(const std::set<K,C,A>& x,
+ std::set<K,C,A>& z)
+ {
+ z.clear();
+
+ }
+
+} // namespace boost
+
+#endif // BOOST_SET_ADAPTOR_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/shadow_iterator.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/shadow_iterator.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,139 @@
+// (C) Copyright Jeremy Siek 2001.
+// 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)
+
+#ifndef BOOST_SHADOW_ITERATOR_HPP
+#define BOOST_SHADOW_ITERATOR_HPP
+
+#include <boost/iterator_adaptors.hpp>
+#include <boost/operators.hpp>
+
+namespace boost {
+
+ namespace detail {
+
+ template <class A, class B, class D>
+ class shadow_proxy
+ : boost::operators< shadow_proxy<A,B,D> >
+ {
+ typedef shadow_proxy self;
+ public:
+ inline shadow_proxy(A aa, B bb) : a(aa), b(bb) { }
+ inline shadow_proxy(const self& x) : a(x.a), b(x.b) { }
+ template <class Self>
+ inline shadow_proxy(Self x) : a(x.a), b(x.b) { }
+ inline self& operator=(const self& x) { a = x.a; b = x.b; return *this; }
+ inline self& operator++() { ++a; return *this; }
+ inline self& operator--() { --a; return *this; }
+ inline self& operator+=(const self& x) { a += x.a; return *this; }
+ inline self& operator-=(const self& x) { a -= x.a; return *this; }
+ inline self& operator*=(const self& x) { a *= x.a; return *this; }
+ inline self& operator/=(const self& x) { a /= x.a; return *this; }
+ inline self& operator%=(const self& x) { return *this; } // JGS
+ inline self& operator&=(const self& x) { return *this; } // JGS
+ inline self& operator|=(const self& x) { return *this; } // JGS
+ inline self& operator^=(const self& x) { return *this; } // JGS
+ inline friend D operator-(const self& x, const self& y) {
+ return x.a - y.a;
+ }
+ inline bool operator==(const self& x) const { return a == x.a; }
+ inline bool operator<(const self& x) const { return a < x.a; }
+ // protected:
+ A a;
+ B b;
+ };
+
+ struct shadow_iterator_policies
+ {
+ template <typename iter_pair>
+ void initialize(const iter_pair&) { }
+
+ template <typename Iter>
+ typename Iter::reference dereference(const Iter& i) const {
+ typedef typename Iter::reference R;
+ return R(*i.base().first, *i.base().second);
+ }
+ template <typename Iter>
+ bool equal(const Iter& p1, const Iter& p2) const {
+ return p1.base().first == p2.base().first;
+ }
+ template <typename Iter>
+ void increment(Iter& i) { ++i.base().first; ++i.base().second; }
+
+ template <typename Iter>
+ void decrement(Iter& i) { --i.base().first; --i.base().second; }
+
+ template <typename Iter>
+ bool less(const Iter& x, const Iter& y) const {
+ return x.base().first < y.base().first;
+ }
+ template <typename Iter>
+ typename Iter::difference_type
+ distance(const Iter& x, const Iter& y) const {
+ return y.base().first - x.base().first;
+ }
+ template <typename D, typename Iter>
+ void advance(Iter& p, D n) { p.base().first += n; p.base().second += n; }
+ };
+
+ } // namespace detail
+
+ template <typename IterA, typename IterB>
+ struct shadow_iterator_generator {
+
+ // To use the iterator_adaptor we can't derive from
+ // random_access_iterator because we don't have a real reference.
+ // However, we want the STL algorithms to treat the shadow
+ // iterator like a random access iterator.
+ struct shadow_iterator_tag : public std::input_iterator_tag {
+ operator std::random_access_iterator_tag() {
+ return std::random_access_iterator_tag();
+ };
+ };
+ typedef typename std::iterator_traits<IterA>::value_type Aval;
+ typedef typename std::iterator_traits<IterB>::value_type Bval;
+ typedef typename std::iterator_traits<IterA>::reference Aref;
+ typedef typename std::iterator_traits<IterB>::reference Bref;
+ typedef typename std::iterator_traits<IterA>::difference_type D;
+ typedef detail::shadow_proxy<Aval,Bval,Aval> V;
+ typedef detail::shadow_proxy<Aref,Bref,Aval> R;
+ typedef iterator_adaptor< std::pair<IterA, IterB>,
+ detail::shadow_iterator_policies,
+ V, R, V*, shadow_iterator_tag,
+ D> type;
+ };
+
+ // short cut for creating a shadow iterator
+ template <class IterA, class IterB>
+ inline typename shadow_iterator_generator<IterA,IterB>::type
+ make_shadow_iter(IterA a, IterB b) {
+ typedef typename shadow_iterator_generator<IterA,IterB>::type Iter;
+ return Iter(std::make_pair(a,b));
+ }
+
+ template <class Cmp>
+ struct shadow_cmp {
+ inline shadow_cmp(const Cmp& c) : cmp(c) { }
+ template <class ShadowProxy1, class ShadowProxy2>
+ inline bool operator()(const ShadowProxy1& x, const ShadowProxy2& y) const
+ {
+ return cmp(x.a, y.a);
+ }
+ Cmp cmp;
+ };
+
+} // namespace boost
+
+namespace std {
+ template <class A1, class B1, class D1,
+ class A2, class B2, class D2>
+ void swap(boost::detail::shadow_proxy<A1&,B1&,D1> x,
+ boost::detail::shadow_proxy<A2&,B2&,D2> y)
+ {
+ std::swap(x.a, y.a);
+ std::swap(x.b, y.b);
+ }
+}
+
+#endif // BOOST_SHADOW_ITERATOR_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/detail/sparse_ordering.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/detail/sparse_ordering.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,198 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2004, 2005 Trustees of Indiana University
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek,
+// Doug Gregor, D. Kevin McGrath
+//
+// 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)
+//=======================================================================//
+#ifndef BOOST_GRAPH_DETAIL_SPARSE_ORDERING_HPP
+#define BOOST_GRAPH_DETAIL_SPARSE_ORDERING_HPP
+
+#include <boost/config.hpp>
+#include <vector>
+#include <queue>
+#include <boost/pending/queue.hpp>
+#include <boost/pending/mutable_queue.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/pending/indirect_cmp.hpp>
+#include <boost/property_map.hpp>
+#include <boost/bind.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/depth_first_search.hpp>
+
+namespace boost {
+
+ namespace sparse {
+
+ // rcm_queue
+ //
+ // This is a custom queue type used in the
+ // *_ordering algorithms.
+ // In addition to the normal queue operations, the
+ // rcm_queue provides:
+ //
+ // int eccentricity() const;
+ // value_type spouse() const;
+ //
+
+ // yes, it's a bad name...but it works, so use it
+ template < class Vertex, class DegreeMap,
+ class Container = std::deque<Vertex> >
+ class rcm_queue : public std::queue<Vertex, Container> {
+ typedef std::queue<Vertex> base;
+ public:
+ typedef typename base::value_type value_type;
+ typedef typename base::size_type size_type;
+
+ /* SGI queue has not had a contructor queue(const Container&) */
+ inline rcm_queue(DegreeMap deg)
+ : _size(0), Qsize(1), eccen(-1), degree(deg) { }
+
+ inline void pop() {
+ if ( !_size )
+ Qsize = base::size();
+
+ base::pop();
+ if ( _size == Qsize-1 ) {
+ _size = 0;
+ ++eccen;
+ } else
+ ++_size;
+
+ }
+
+ inline value_type& front() {
+ value_type& u = base::front();
+ if ( _size == 0 )
+ w = u;
+ else if (get(degree,u) < get(degree,w) )
+ w = u;
+ return u;
+ }
+
+ inline const value_type& front() const {
+ const value_type& u = base::front();
+ if ( _size == 0 )
+ w = u;
+ else if (get(degree,u) < get(degree,w) )
+ w = u;
+ return u;
+ }
+
+ inline value_type& top() { return front(); }
+ inline const value_type& top() const { return front(); }
+
+ inline size_type size() const { return base::size(); }
+
+ inline size_type eccentricity() const { return eccen; }
+ inline value_type spouse() const { return w; }
+
+ protected:
+ size_type _size;
+ size_type Qsize;
+ int eccen;
+ mutable value_type w;
+ DegreeMap degree;
+ };
+
+
+ template <typename Tp, typename Sequence = std::deque<Tp> >
+ class sparse_ordering_queue : public boost::queue<Tp, Sequence>{
+ public:
+ typedef typename Sequence::iterator iterator;
+ typedef typename Sequence::reverse_iterator reverse_iterator;
+ typedef queue<Tp,Sequence> base;
+ typedef typename Sequence::size_type size_type;
+
+ inline iterator begin() { return this->c.begin(); }
+ inline reverse_iterator rbegin() { return this->c.rbegin(); }
+ inline iterator end() { return this->c.end(); }
+ inline reverse_iterator rend() { return this->c.rend(); }
+ inline Tp &operator[](int n) { return this->c[n]; }
+ inline size_type size() {return this->c.size(); }
+ protected:
+ //nothing
+ };
+
+ } // namespace sparse
+
+ // Compute Pseudo peripheral
+ //
+ // To compute an approximated peripheral for a given vertex.
+ // Used in <tt>king_ordering</tt> algorithm.
+ //
+ template <class Graph, class Vertex, class ColorMap, class DegreeMap>
+ Vertex
+ pseudo_peripheral_pair(Graph& G, const Vertex& u, int& ecc,
+ ColorMap color, DegreeMap degree)
+ {
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+
+ sparse::rcm_queue<Vertex, DegreeMap> Q(degree);
+
+ typename boost::graph_traits<Graph>::vertex_iterator ui, ui_end;
+ for (tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
+ if (get(color, *ui) != Color::red()) put(color, *ui, Color::white());
+ breadth_first_visit(G, u, buffer(Q).color_map(color));
+
+ ecc = Q.eccentricity();
+ return Q.spouse();
+ }
+
+ // Find a good starting node
+ //
+ // This is to find a good starting node for the
+ // king_ordering algorithm. "good" is in the sense
+ // of the ordering generated by RCM.
+ //
+ template <class Graph, class Vertex, class Color, class Degree>
+ Vertex find_starting_node(Graph& G, Vertex r, Color color, Degree degree)
+ {
+ Vertex x, y;
+ int eccen_r, eccen_x;
+
+ x = pseudo_peripheral_pair(G, r, eccen_r, color, degree);
+ y = pseudo_peripheral_pair(G, x, eccen_x, color, degree);
+
+ while (eccen_x > eccen_r) {
+ r = x;
+ eccen_r = eccen_x;
+ x = y;
+ y = pseudo_peripheral_pair(G, x, eccen_x, color, degree);
+ }
+ return x;
+ }
+
+template <typename Graph>
+class out_degree_property_map
+ : public put_get_helper<typename graph_traits<Graph>::degree_size_type,
+ out_degree_property_map<Graph> >
+{
+public:
+ typedef typename graph_traits<Graph>::vertex_descriptor key_type;
+ typedef typename graph_traits<Graph>::degree_size_type value_type;
+ typedef value_type reference;
+ typedef readable_property_map_tag category;
+ out_degree_property_map(const Graph& g) : m_g(g) { }
+ value_type operator[](const key_type& v) const {
+ return out_degree(v, m_g);
+ }
+private:
+ const Graph& m_g;
+};
+template <typename Graph>
+inline out_degree_property_map<Graph>
+make_out_degree_map(const Graph& g) {
+ return out_degree_property_map<Graph>(g);
+}
+
+} // namespace boost
+
+
+#endif // BOOST_GRAPH_KING_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/dijkstra_shortest_paths.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/dijkstra_shortest_paths.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,347 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_GRAPH_DIJKSTRA_HPP
+#define BOOST_GRAPH_DIJKSTRA_HPP
+
+#include <functional>
+#include <boost/limits.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/relax.hpp>
+#include <boost/pending/indirect_cmp.hpp>
+#include <boost/graph/exception.hpp>
+#include <boost/pending/relaxed_heap.hpp>
+
+#ifdef BOOST_GRAPH_DIJKSTRA_TESTING
+# include <boost/pending/mutable_queue.hpp>
+#endif // BOOST_GRAPH_DIJKSTRA_TESTING
+
+namespace boost {
+
+#ifdef BOOST_GRAPH_DIJKSTRA_TESTING
+ static bool dijkstra_relaxed_heap = true;
+#endif
+
+ template <class Visitor, class Graph>
+ struct DijkstraVisitorConcept {
+ void constraints() {
+ function_requires< CopyConstructibleConcept<Visitor> >();
+ vis.initialize_vertex(u, g);
+ vis.discover_vertex(u, g);
+ vis.examine_vertex(u, g);
+ vis.examine_edge(e, g);
+ vis.edge_relaxed(e, g);
+ vis.edge_not_relaxed(e, g);
+ vis.finish_vertex(u, g);
+ }
+ Visitor vis;
+ Graph g;
+ typename graph_traits<Graph>::vertex_descriptor u;
+ typename graph_traits<Graph>::edge_descriptor e;
+ };
+
+ template <class Visitors = null_visitor>
+ class dijkstra_visitor : public bfs_visitor<Visitors> {
+ public:
+ dijkstra_visitor() { }
+ dijkstra_visitor(Visitors vis)
+ : bfs_visitor<Visitors>(vis) { }
+
+ template <class Edge, class Graph>
+ void edge_relaxed(Edge e, Graph& g) {
+ invoke_visitors(this->m_vis, e, g, on_edge_relaxed());
+ }
+ template <class Edge, class Graph>
+ void edge_not_relaxed(Edge e, Graph& g) {
+ invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed());
+ }
+ private:
+ template <class Edge, class Graph>
+ void tree_edge(Edge u, Graph& g) { }
+ };
+ template <class Visitors>
+ dijkstra_visitor<Visitors>
+ make_dijkstra_visitor(Visitors vis) {
+ return dijkstra_visitor<Visitors>(vis);
+ }
+ typedef dijkstra_visitor<> default_dijkstra_visitor;
+
+ namespace detail {
+
+ template <class UniformCostVisitor, class UpdatableQueue,
+ class WeightMap, class PredecessorMap, class DistanceMap,
+ class BinaryFunction, class BinaryPredicate>
+ struct dijkstra_bfs_visitor
+ {
+ typedef typename property_traits<DistanceMap>::value_type D;
+
+ dijkstra_bfs_visitor(UniformCostVisitor vis, UpdatableQueue& Q,
+ WeightMap w, PredecessorMap p, DistanceMap d,
+ BinaryFunction combine, BinaryPredicate compare,
+ D zero)
+ : m_vis(vis), m_Q(Q), m_weight(w), m_predecessor(p), m_distance(d),
+ m_combine(combine), m_compare(compare), m_zero(zero) { }
+
+ template <class Edge, class Graph>
+ void tree_edge(Edge e, Graph& g) {
+ m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
+ m_combine, m_compare);
+ if (m_decreased)
+ m_vis.edge_relaxed(e, g);
+ else
+ m_vis.edge_not_relaxed(e, g);
+ }
+ template <class Edge, class Graph>
+ void gray_target(Edge e, Graph& g) {
+ m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
+ m_combine, m_compare);
+ if (m_decreased) {
+ m_Q.update(target(e, g));
+ m_vis.edge_relaxed(e, g);
+ } else
+ m_vis.edge_not_relaxed(e, g);
+ }
+
+ template <class Vertex, class Graph>
+ void initialize_vertex(Vertex /*u*/, Graph& /*g*/) { }
+ template <class Edge, class Graph>
+ void non_tree_edge(Edge, Graph&) { }
+ template <class Vertex, class Graph>
+ void discover_vertex(Vertex u, Graph& g) { m_vis.discover_vertex(u, g); }
+ template <class Vertex, class Graph>
+ void examine_vertex(Vertex u, Graph& g) { m_vis.examine_vertex(u, g); }
+ template <class Edge, class Graph>
+ void examine_edge(Edge e, Graph& g) {
+ if (m_compare(get(m_weight, e), m_zero))
+ throw negative_edge();
+ m_vis.examine_edge(e, g);
+ }
+ template <class Edge, class Graph>
+ void black_target(Edge, Graph&) { }
+ template <class Vertex, class Graph>
+ void finish_vertex(Vertex u, Graph& g) { m_vis.finish_vertex(u, g); }
+
+ UniformCostVisitor m_vis;
+ UpdatableQueue& m_Q;
+ WeightMap m_weight;
+ PredecessorMap m_predecessor;
+ DistanceMap m_distance;
+ BinaryFunction m_combine;
+ BinaryPredicate m_compare;
+ bool m_decreased;
+ D m_zero;
+ };
+
+ } // namespace detail
+
+ // Call breadth first search with default color map.
+ template <class VertexListGraph, class DijkstraVisitor,
+ class PredecessorMap, class DistanceMap,
+ class WeightMap, class IndexMap, class Compare, class Combine,
+ class DistZero>
+ inline void
+ dijkstra_shortest_paths_no_init
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
+ IndexMap index_map,
+ Compare compare, Combine combine, DistZero zero,
+ DijkstraVisitor vis)
+ {
+ std::vector<default_color_type> color(num_vertices(g));
+ default_color_type c = white_color;
+ dijkstra_shortest_paths_no_init( g, s, predecessor, distance, weight,
+ index_map, compare, combine, zero, vis,
+ make_iterator_property_map(&color[0], index_map, c));
+ }
+
+ // Call breadth first search
+ template <class VertexListGraph, class DijkstraVisitor,
+ class PredecessorMap, class DistanceMap,
+ class WeightMap, class IndexMap, class Compare, class Combine,
+ class DistZero, class ColorMap>
+ inline void
+ dijkstra_shortest_paths_no_init
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
+ IndexMap index_map,
+ Compare compare, Combine combine, DistZero zero,
+ DijkstraVisitor vis, ColorMap color)
+ {
+ typedef indirect_cmp<DistanceMap, Compare> IndirectCmp;
+ IndirectCmp icmp(distance, compare);
+
+ typedef typename graph_traits<VertexListGraph>::vertex_descriptor Vertex;
+
+#ifdef BOOST_GRAPH_DIJKSTRA_TESTING
+ if (!dijkstra_relaxed_heap) {
+ typedef mutable_queue<Vertex, std::vector<Vertex>, IndirectCmp, IndexMap>
+ MutableQueue;
+
+ MutableQueue Q(num_vertices(g), icmp, index_map);
+
+ detail::dijkstra_bfs_visitor<DijkstraVisitor, MutableQueue, WeightMap,
+ PredecessorMap, DistanceMap, Combine, Compare>
+ bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero);
+
+ breadth_first_visit(g, s, Q, bfs_vis, color);
+ return;
+ }
+#endif // BOOST_GRAPH_DIJKSTRA_TESTING
+
+ typedef relaxed_heap<Vertex, IndirectCmp, IndexMap> MutableQueue;
+
+ MutableQueue Q(num_vertices(g), icmp, index_map);
+
+ detail::dijkstra_bfs_visitor<DijkstraVisitor, MutableQueue, WeightMap,
+ PredecessorMap, DistanceMap, Combine, Compare>
+ bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero);
+
+ breadth_first_visit(g, s, Q, bfs_vis, color);
+ }
+
+ // Initialize distances and call breadth first search with default color map
+ template <class VertexListGraph, class DijkstraVisitor,
+ class PredecessorMap, class DistanceMap,
+ class WeightMap, class IndexMap, class Compare, class Combine,
+ class DistInf, class DistZero>
+ inline void
+ dijkstra_shortest_paths
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
+ IndexMap index_map,
+ Compare compare, Combine combine, DistInf inf, DistZero zero,
+ DijkstraVisitor vis)
+ {
+ std::vector<default_color_type> color(num_vertices(g));
+ default_color_type c = white_color;
+ dijkstra_shortest_paths(g, s, predecessor, distance, weight, index_map,
+ compare, combine, inf, zero, vis,
+ make_iterator_property_map(&color[0], index_map,
+ c));
+ }
+
+ // Initialize distances and call breadth first search
+ template <class VertexListGraph, class DijkstraVisitor,
+ class PredecessorMap, class DistanceMap,
+ class WeightMap, class IndexMap, class Compare, class Combine,
+ class DistInf, class DistZero, class ColorMap>
+ inline void
+ dijkstra_shortest_paths
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
+ IndexMap index_map,
+ Compare compare, Combine combine, DistInf inf, DistZero zero,
+ DijkstraVisitor vis, ColorMap color)
+ {
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+ typename graph_traits<VertexListGraph>::vertex_iterator ui, ui_end;
+ for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
+ vis.initialize_vertex(*ui, g);
+ put(distance, *ui, inf);
+ put(predecessor, *ui, *ui);
+ put(color, *ui, Color::white());
+ }
+ put(distance, s, zero);
+
+ dijkstra_shortest_paths_no_init(g, s, predecessor, distance, weight,
+ index_map, compare, combine, zero, vis, color);
+ }
+
+ namespace detail {
+
+ // Handle defaults for PredecessorMap and
+ // Distance Compare, Combine, Inf and Zero
+ template <class VertexListGraph, class DistanceMap, class WeightMap,
+ class IndexMap, class Params, class ColorMap>
+ inline void
+ dijkstra_dispatch2
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ DistanceMap distance, WeightMap weight, IndexMap index_map,
+ const Params& params, ColorMap color)
+ {
+ // Default for predecessor map
+ dummy_property_map p_map;
+
+ typedef typename property_traits<DistanceMap>::value_type D;
+ dijkstra_shortest_paths
+ (g, s,
+ choose_param(get_param(params, vertex_predecessor), p_map),
+ distance, weight, index_map,
+ choose_param(get_param(params, distance_compare_t()),
+ std::less<D>()),
+ choose_param(get_param(params, distance_combine_t()),
+ closed_plus<D>()),
+ choose_param(get_param(params, distance_inf_t()),
+ (std::numeric_limits<D>::max)()),
+ choose_param(get_param(params, distance_zero_t()),
+ D()),
+ choose_param(get_param(params, graph_visitor),
+ make_dijkstra_visitor(null_visitor())),
+ color);
+ }
+
+ template <class VertexListGraph, class DistanceMap, class WeightMap,
+ class IndexMap, class Params, class ColorMap>
+ inline void
+ dijkstra_dispatch1
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ DistanceMap distance, WeightMap weight, IndexMap index_map,
+ const Params& params, ColorMap color)
+ {
+ // Default for distance map
+ typedef typename property_traits<WeightMap>::value_type D;
+ typename std::vector<D>::size_type
+ n = is_default_param(distance) ? num_vertices(g) : 1;
+ std::vector<D> distance_map(n);
+
+ // Default for color map
+ typename std::vector<default_color_type>::size_type
+ m = is_default_param(color) ? num_vertices(g) : 1;
+ std::vector<default_color_type> color_map(m);
+
+ detail::dijkstra_dispatch2
+ (g, s, choose_param(distance, make_iterator_property_map
+ (distance_map.begin(), index_map,
+ distance_map[0])),
+ weight, index_map, params,
+ choose_param(color, make_iterator_property_map
+ (color_map.begin(), index_map,
+ color_map[0])));
+ }
+ } // namespace detail
+
+ // Named Parameter Variant
+ template <class VertexListGraph, class Param, class Tag, class Rest>
+ inline void
+ dijkstra_shortest_paths
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ const bgl_named_params<Param,Tag,Rest>& params)
+ {
+ // Default for edge weight and vertex index map is to ask for them
+ // from the graph. Default for the visitor is null_visitor.
+ detail::dijkstra_dispatch1
+ (g, s,
+ get_param(params, vertex_distance),
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
+ params,
+ get_param(params, vertex_color));
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_DIJKSTRA_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/dominator_tree.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/dominator_tree.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,488 @@
+//=======================================================================
+// Copyright (C) 2005 Jong Soo Park <jongsoo.park -at- gmail.com>
+//
+// 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)
+//=======================================================================
+// Dominator tree computation
+#ifndef BOOST_GRAPH_DOMINATOR_HPP
+#define BOOST_GRAPH_DOMINATOR_HPP
+
+#include <boost/config.hpp>
+#include <deque>
+#include <set>
+#include <boost/graph/depth_first_search.hpp>
+
+namespace boost {
+ namespace detail {
+ /**
+ * An extended time_stamper which also records vertices for each dfs number
+ */
+ template<class TimeMap, class VertexVector, class TimeT, class Tag>
+ class time_stamper_with_vertex_vector
+ : public base_visitor<
+ time_stamper_with_vertex_vector<TimeMap, VertexVector, TimeT, Tag> >
+ {
+ public :
+ typedef Tag event_filter;
+ time_stamper_with_vertex_vector(TimeMap timeMap, VertexVector& v,
+ TimeT& t)
+ : timeStamper_(timeMap, t), v_(v) { }
+
+ template<class Graph>
+ void
+ operator()(const typename property_traits<TimeMap>::key_type& v,
+ const Graph& g)
+ {
+ timeStamper_(v, g);
+ v_[timeStamper_.m_time] = v;
+ }
+
+ private :
+ time_stamper<TimeMap, TimeT, Tag> timeStamper_;
+ VertexVector& v_;
+ };
+
+ /**
+ * A convenient way to create a time_stamper_with_vertex_vector
+ */
+ template<class TimeMap, class VertexVector, class TimeT, class Tag>
+ time_stamper_with_vertex_vector<TimeMap, VertexVector, TimeT, Tag>
+ stamp_times_with_vertex_vector(TimeMap timeMap, VertexVector& v, TimeT& t,
+ Tag)
+ {
+ return time_stamper_with_vertex_vector<TimeMap, VertexVector, TimeT,
+ Tag>(timeMap, v, t);
+ }
+
+ template<class Graph, class IndexMap, class TimeMap, class PredMap,
+ class DomTreePredMap>
+ class dominator_visitor
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;
+
+ public :
+ /**
+ * @param g [in] the target graph of the dominator tree
+ * @param entry [in] the entry node of g
+ * @param domTreePredMap [out] the immediate dominator map
+ * (parent map in dominator tree)
+ */
+ dominator_visitor(const Graph& g, const Vertex& entry,
+ DomTreePredMap domTreePredMap)
+ : semi_(num_vertices(g)),
+ ancestor_(num_vertices(g), graph_traits<Graph>::null_vertex()),
+ samedom_(ancestor_),
+ best_(semi_),
+ semiMap_(make_iterator_property_map(semi_.begin(),
+ get(vertex_index, g))),
+ ancestorMap_(make_iterator_property_map(ancestor_.begin(),
+ get(vertex_index, g))),
+ bestMap_(make_iterator_property_map(best_.begin(),
+ get(vertex_index, g))),
+ buckets_(num_vertices(g)),
+ bucketMap_(make_iterator_property_map(buckets_.begin(),
+ get(vertex_index, g))),
+ entry_(entry),
+ domTreePredMap_(domTreePredMap),
+ samedomMap(make_iterator_property_map(samedom_.begin(),
+ get(vertex_index, g)))
+ {
+ }
+
+ void
+ operator()(const Vertex& n, const TimeMap& dfnumMap,
+ const PredMap& parentMap, const Graph& g)
+ {
+ if (n == entry_) return;
+
+ const VerticesSizeType numOfVertices = num_vertices(g);
+ const Vertex p(get(parentMap, n));
+ Vertex s(p);
+
+ // 1. Calculate the semidominator of n,
+ // based on the semidominator thm.
+ // * Semidominator thm. : To find the semidominator of a node n,
+ // consider all predecessors v of n in the CFG (Control Flow Graph).
+ // - If v is a proper ancestor of n in the spanning tree
+ // (so dfnum(v) < dfnum(n)), then v is a candidate for semi(n)
+ // - If v is a non-ancestor of n (so dfnum(v) > dfnum(n))
+ // then for each u that is an ancestor of v (or u = v),
+ // Let semi(u) be a candidate for semi(n)
+ // of all these candidates, the one with lowest dfnum is
+ // the semidominator of n.
+
+ // For each predecessor of n
+ typename graph_traits<Graph>::in_edge_iterator inItr, inEnd;
+ for (tie(inItr, inEnd) = in_edges(n, g); inItr != inEnd; ++inItr)
+ {
+ const Vertex v = source(*inItr, g);
+ // To deal with unreachable nodes
+ if (get(dfnumMap, v) < 0 || get(dfnumMap, v) >= numOfVertices)
+ continue;
+
+ Vertex s2;
+ if (get(dfnumMap, v) <= get(dfnumMap, n))
+ s2 = v;
+ else
+ s2 = get(semiMap_, ancestor_with_lowest_semi_(v, dfnumMap));
+
+ if (get(dfnumMap, s2) < get(dfnumMap, s))
+ s = s2;
+ }
+ put(semiMap_, n, s);
+
+ // 2. Calculation of n's dominator is deferred until
+ // the path from s to n has been linked into the forest
+ get(bucketMap_, s).push_back(n);
+ get(ancestorMap_, n) = p;
+ get(bestMap_, n) = n;
+
+ // 3. Now that the path from p to v has been linked into
+ // the spanning forest, these lines calculate the dominator of v,
+ // based on the dominator thm., or else defer the calculation
+ // until y's dominator is known
+ // * Dominator thm. : On the spanning-tree path below semi(n) and
+ // above or including n, let y be the node
+ // with the smallest-numbered semidominator. Then,
+ //
+ // idom(n) = semi(n) if semi(y)=semi(n) or
+ // idom(y) if semi(y) != semi(n)
+ typename std::deque<Vertex>::iterator buckItr;
+ for (buckItr = get(bucketMap_, p).begin();
+ buckItr != get(bucketMap_, p).end();
+ ++buckItr)
+ {
+ const Vertex v(*buckItr);
+ const Vertex y(ancestor_with_lowest_semi_(v, dfnumMap));
+ if (get(semiMap_, y) == get(semiMap_, v))
+ put(domTreePredMap_, v, p);
+ else
+ put(samedomMap, v, y);
+ }
+
+ get(bucketMap_, p).clear();
+ }
+
+ protected :
+
+ /**
+ * Evaluate function in Tarjan's path compression
+ */
+ const Vertex
+ ancestor_with_lowest_semi_(const Vertex& v, const TimeMap& dfnumMap)
+ {
+ const Vertex a(get(ancestorMap_, v));
+
+ if (get(ancestorMap_, a) != graph_traits<Graph>::null_vertex())
+ {
+ const Vertex b(ancestor_with_lowest_semi_(a, dfnumMap));
+
+ put(ancestorMap_, v, get(ancestorMap_, a));
+
+ if (get(dfnumMap, get(semiMap_, b)) <
+ get(dfnumMap, get(semiMap_, get(bestMap_, v))))
+ put(bestMap_, v, b);
+ }
+
+ return get(bestMap_, v);
+ }
+
+ std::vector<Vertex> semi_, ancestor_, samedom_, best_;
+ PredMap semiMap_, ancestorMap_, bestMap_;
+ std::vector< std::deque<Vertex> > buckets_;
+
+ iterator_property_map<typename std::vector<std::deque<Vertex> >::iterator,
+ IndexMap> bucketMap_;
+
+ const Vertex& entry_;
+ DomTreePredMap domTreePredMap_;
+
+ public :
+
+ PredMap samedomMap;
+ };
+
+ } // namespace detail
+
+ /**
+ * @brief Build dominator tree using Lengauer-Tarjan algorithm.
+ * It takes O((V+E)log(V+E)) time.
+ *
+ * @pre dfnumMap, parentMap and verticesByDFNum have dfs results corresponding
+ * indexMap.
+ * If dfs has already run before,
+ * this function would be good for saving computations.
+ * @pre Unreachable nodes must be masked as
+ * graph_traits<Graph>::null_vertex in parentMap.
+ * @pre Unreachable nodes must be masked as
+ * (std::numeric_limits<VerticesSizeType>::max)() in dfnumMap.
+ *
+ * @param domTreePredMap [out] : immediate dominator map (parent map
+ * in dom. tree)
+ *
+ * @note reference Appel. p. 452~453. algorithm 19.9, 19.10.
+ *
+ * @todo : Optimization in Finding Dominators in Practice, Loukas Georgiadis
+ */
+ template<class Graph, class IndexMap, class TimeMap, class PredMap,
+ class VertexVector, class DomTreePredMap>
+ void
+ lengauer_tarjan_dominator_tree_without_dfs
+ (const Graph& g,
+ const typename graph_traits<Graph>::vertex_descriptor& entry,
+ const IndexMap& indexMap,
+ TimeMap dfnumMap, PredMap parentMap, VertexVector& verticesByDFNum,
+ DomTreePredMap domTreePredMap)
+ {
+ // Typedefs and concept check
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;
+
+ function_requires< BidirectionalGraphConcept<Graph> >();
+
+ const VerticesSizeType numOfVertices = num_vertices(g);
+ if (numOfVertices == 0) return;
+
+ // 1. Visit each vertex in reverse post order and calculate sdom.
+ detail::dominator_visitor<Graph, IndexMap, TimeMap, PredMap, DomTreePredMap>
+ visitor(g, entry, domTreePredMap);
+
+ VerticesSizeType i;
+ for (i = 0; i < numOfVertices; ++i)
+ {
+ const Vertex u(verticesByDFNum[numOfVertices - 1 - i]);
+ if (u != graph_traits<Graph>::null_vertex())
+ visitor(u, dfnumMap, parentMap, g);
+ }
+
+ // 2. Now all the deferred dominator calculations,
+ // based on the second clause of the dominator thm., are performed
+ for (i = 0; i < numOfVertices; ++i)
+ {
+ const Vertex n(verticesByDFNum[i]);
+
+ if (n == entry || n == graph_traits<Graph>::null_vertex())
+ continue;
+
+ Vertex u = get(visitor.samedomMap, n);
+ if (u != graph_traits<Graph>::null_vertex())
+ {
+ put(domTreePredMap, n, get(domTreePredMap, u));
+ }
+ }
+ }
+
+ /**
+ * Unlike lengauer_tarjan_dominator_tree_without_dfs,
+ * dfs is run in this function and
+ * the result is written to dfnumMap, parentMap, vertices.
+ *
+ * If the result of dfs required after this algorithm,
+ * this function can eliminate the need of rerunning dfs.
+ */
+ template<class Graph, class IndexMap, class TimeMap, class PredMap,
+ class VertexVector, class DomTreePredMap>
+ void
+ lengauer_tarjan_dominator_tree
+ (const Graph& g,
+ const typename graph_traits<Graph>::vertex_descriptor& entry,
+ const IndexMap& indexMap,
+ TimeMap dfnumMap, PredMap parentMap, VertexVector& verticesByDFNum,
+ DomTreePredMap domTreePredMap)
+ {
+ // Typedefs and concept check
+ typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;
+
+ function_requires< BidirectionalGraphConcept<Graph> >();
+
+ // 1. Depth first visit
+ const VerticesSizeType numOfVertices = num_vertices(g);
+ if (numOfVertices == 0) return;
+
+ VerticesSizeType time =
+ (std::numeric_limits<VerticesSizeType>::max)();
+ std::vector<default_color_type>
+ colors(numOfVertices, color_traits<default_color_type>::white());
+ depth_first_visit
+ (g, entry,
+ make_dfs_visitor
+ (make_pair(record_predecessors(parentMap, on_tree_edge()),
+ detail::stamp_times_with_vertex_vector
+ (dfnumMap, verticesByDFNum, time, on_discover_vertex()))),
+ make_iterator_property_map(colors.begin(), indexMap));
+
+ // 2. Run main algorithm.
+ lengauer_tarjan_dominator_tree_without_dfs(g, entry, indexMap, dfnumMap,
+ parentMap, verticesByDFNum,
+ domTreePredMap);
+ }
+
+ /**
+ * Use vertex_index as IndexMap and make dfnumMap, parentMap, verticesByDFNum
+ * internally.
+ * If we don't need the result of dfs (dfnumMap, parentMap, verticesByDFNum),
+ * this function would be more convenient one.
+ */
+ template<class Graph, class DomTreePredMap>
+ void
+ lengauer_tarjan_dominator_tree
+ (const Graph& g,
+ const typename graph_traits<Graph>::vertex_descriptor& entry,
+ DomTreePredMap domTreePredMap)
+ {
+ // typedefs
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;
+ typedef typename property_map<Graph, vertex_index_t>::const_type IndexMap;
+ typedef
+ iterator_property_map<typename std::vector<VerticesSizeType>::iterator,
+ IndexMap> TimeMap;
+ typedef
+ iterator_property_map<typename std::vector<Vertex>::iterator, IndexMap>
+ PredMap;
+
+ // Make property maps
+ const VerticesSizeType numOfVertices = num_vertices(g);
+ if (numOfVertices == 0) return;
+
+ const IndexMap indexMap = get(vertex_index, g);
+
+ std::vector<VerticesSizeType> dfnum(numOfVertices, 0);
+ TimeMap dfnumMap(make_iterator_property_map(dfnum.begin(), indexMap));
+
+ std::vector<Vertex> parent(numOfVertices,
+ graph_traits<Graph>::null_vertex());
+ PredMap parentMap(make_iterator_property_map(parent.begin(), indexMap));
+
+ std::vector<Vertex> verticesByDFNum(parent);
+
+ // Run main algorithm
+ lengauer_tarjan_dominator_tree(g, entry,
+ indexMap, dfnumMap, parentMap,
+ verticesByDFNum, domTreePredMap);
+ }
+
+ /**
+ * Muchnick. p. 182, 184
+ *
+ * using iterative bit vector analysis
+ */
+ template<class Graph, class IndexMap, class DomTreePredMap>
+ void
+ iterative_bit_vector_dominator_tree
+ (const Graph& g,
+ const typename graph_traits<Graph>::vertex_descriptor& entry,
+ const IndexMap& indexMap,
+ DomTreePredMap domTreePredMap)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename graph_traits<Graph>::vertex_iterator vertexItr;
+ typedef typename graph_traits<Graph>::vertices_size_type VerticesSizeType;
+ typedef
+ iterator_property_map<typename std::vector< std::set<Vertex> >::iterator,
+ IndexMap> vertexSetMap;
+
+ function_requires<BidirectionalGraphConcept<Graph> >();
+
+ // 1. Finding dominator
+ // 1.1. Initialize
+ const VerticesSizeType numOfVertices = num_vertices(g);
+ if (numOfVertices == 0) return;
+
+ vertexItr vi, viend;
+ tie(vi, viend) = vertices(g);
+ const std::set<Vertex> N(vi, viend);
+
+ bool change = true;
+
+ std::vector< std::set<Vertex> > dom(numOfVertices, N);
+ vertexSetMap domMap(make_iterator_property_map(dom.begin(), indexMap));
+ get(domMap, entry).clear();
+ get(domMap, entry).insert(entry);
+
+ while (change)
+ {
+ change = false;
+ for (tie(vi, viend) = vertices(g); vi != viend; ++vi)
+ {
+ if (*vi == entry) continue;
+
+ std::set<Vertex> T(N);
+
+ typename graph_traits<Graph>::in_edge_iterator inItr, inEnd;
+ for (tie(inItr, inEnd) = in_edges(*vi, g); inItr != inEnd; ++inItr)
+ {
+ const Vertex p = source(*inItr, g);
+
+ std::set<Vertex> tempSet;
+ std::set_intersection(T.begin(), T.end(),
+ get(domMap, p).begin(),
+ get(domMap, p).end(),
+ std::inserter(tempSet, tempSet.begin()));
+ T.swap(tempSet);
+ }
+
+ T.insert(*vi);
+ if (T != get(domMap, *vi))
+ {
+ change = true;
+ get(domMap, *vi).swap(T);
+ }
+ } // end of for (tie(vi, viend) = vertices(g)
+ } // end of while(change)
+
+ // 2. Build dominator tree
+ for (tie(vi, viend) = vertices(g); vi != viend; ++vi)
+ get(domMap, *vi).erase(*vi);
+
+ Graph domTree(numOfVertices);
+
+ for (tie(vi, viend) = vertices(g); vi != viend; ++vi)
+ {
+ if (*vi == entry) continue;
+
+ // We have to iterate through copied dominator set
+ const std::set<Vertex> tempSet(get(domMap, *vi));
+ typename std::set<Vertex>::const_iterator s;
+ for (s = tempSet.begin(); s != tempSet.end(); ++s)
+ {
+ typename std::set<Vertex>::iterator t;
+ for (t = get(domMap, *vi).begin(); t != get(domMap, *vi).end(); )
+ {
+ typename std::set<Vertex>::iterator old_t = t;
+ ++t; // Done early because t may become invalid
+ if (*old_t == *s) continue;
+ if (get(domMap, *s).find(*old_t) != get(domMap, *s).end())
+ get(domMap, *vi).erase(old_t);
+ }
+ }
+ }
+
+ for (tie(vi, viend) = vertices(g); vi != viend; ++vi)
+ {
+ if (*vi != entry && get(domMap, *vi).size() == 1)
+ {
+ Vertex temp = *get(domMap, *vi).begin();
+ put(domTreePredMap, *vi, temp);
+ }
+ }
+ }
+
+ template<class Graph, class DomTreePredMap>
+ void
+ iterative_bit_vector_dominator_tree
+ (const Graph& g,
+ const typename graph_traits<Graph>::vertex_descriptor& entry,
+ DomTreePredMap domTreePredMap)
+ {
+ typename property_map<Graph, vertex_index_t>::const_type
+ indexMap = get(vertex_index, g);
+
+ iterative_bit_vector_dominator_tree(g, entry, indexMap, domTreePredMap);
+ }
+} // namespace boost
+
+#endif // BOOST_GRAPH_DOMINATOR_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/edge_connectivity.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/edge_connectivity.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,181 @@
+//=======================================================================
+// Copyright 2000 University of Notre Dame.
+// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_EDGE_CONNECTIVITY
+#define BOOST_EDGE_CONNECTIVITY
+
+// WARNING: not-yet fully tested!
+
+#include <boost/config.hpp>
+#include <vector>
+#include <set>
+#include <algorithm>
+#include <boost/graph/edmunds_karp_max_flow.hpp>
+
+namespace boost {
+
+ namespace detail {
+
+ template <class Graph>
+ inline
+ std::pair<typename graph_traits<Graph>::vertex_descriptor,
+ typename graph_traits<Graph>::degree_size_type>
+ min_degree_vertex(Graph& g)
+ {
+ typedef graph_traits<Graph> Traits;
+ typename Traits::vertex_descriptor p;
+ typedef typename Traits::degree_size_type size_type;
+ size_type delta = (std::numeric_limits<size_type>::max)();
+
+ typename Traits::vertex_iterator i, iend;
+ for (tie(i, iend) = vertices(g); i != iend; ++i)
+ if (degree(*i, g) < delta) {
+ delta = degree(*i, g);
+ p = *i;
+ }
+ return std::make_pair(p, delta);
+ }
+
+ template <class Graph, class OutputIterator>
+ void neighbors(const Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor u,
+ OutputIterator result)
+ {
+ typename graph_traits<Graph>::adjacency_iterator ai, aend;
+ for (tie(ai, aend) = adjacent_vertices(u, g); ai != aend; ++ai)
+ *result++ = *ai;
+ }
+
+ template <class Graph, class VertexIterator, class OutputIterator>
+ void neighbors(const Graph& g,
+ VertexIterator first, VertexIterator last,
+ OutputIterator result)
+ {
+ for (; first != last; ++first)
+ neighbors(g, *first, result);
+ }
+
+ } // namespace detail
+
+ // O(m n)
+ template <class VertexListGraph, class OutputIterator>
+ typename graph_traits<VertexListGraph>::degree_size_type
+ edge_connectivity(VertexListGraph& g, OutputIterator disconnecting_set)
+ {
+ //-------------------------------------------------------------------------
+ // Type Definitions
+ typedef graph_traits<VertexListGraph> Traits;
+ typedef typename Traits::vertex_iterator vertex_iterator;
+ typedef typename Traits::edge_iterator edge_iterator;
+ typedef typename Traits::out_edge_iterator out_edge_iterator;
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+ typedef typename Traits::degree_size_type degree_size_type;
+ typedef color_traits<default_color_type> Color;
+
+ typedef adjacency_list_traits<vecS, vecS, directedS> Tr;
+ typedef typename Tr::edge_descriptor Tr_edge_desc;
+ typedef adjacency_list<vecS, vecS, directedS, no_property,
+ property<edge_capacity_t, degree_size_type,
+ property<edge_residual_capacity_t, degree_size_type,
+ property<edge_reverse_t, Tr_edge_desc> > > >
+ FlowGraph;
+ typedef typename graph_traits<FlowGraph>::edge_descriptor edge_descriptor;
+
+ //-------------------------------------------------------------------------
+ // Variable Declarations
+ vertex_descriptor u, v, p, k;
+ edge_descriptor e1, e2;
+ bool inserted;
+ vertex_iterator vi, vi_end;
+ edge_iterator ei, ei_end;
+ degree_size_type delta, alpha_star, alpha_S_k;
+ std::set<vertex_descriptor> S, neighbor_S;
+ std::vector<vertex_descriptor> S_star, non_neighbor_S;
+ std::vector<default_color_type> color(num_vertices(g));
+ std::vector<edge_descriptor> pred(num_vertices(g));
+
+ //-------------------------------------------------------------------------
+ // Create a network flow graph out of the undirected graph
+ FlowGraph flow_g(num_vertices(g));
+
+ typename property_map<FlowGraph, edge_capacity_t>::type
+ cap = get(edge_capacity, flow_g);
+ typename property_map<FlowGraph, edge_residual_capacity_t>::type
+ res_cap = get(edge_residual_capacity, flow_g);
+ typename property_map<FlowGraph, edge_reverse_t>::type
+ rev_edge = get(edge_reverse, flow_g);
+
+ for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
+ u = source(*ei, g), v = target(*ei, g);
+ tie(e1, inserted) = add_edge(u, v, flow_g);
+ cap[e1] = 1;
+ tie(e2, inserted) = add_edge(v, u, flow_g);
+ cap[e2] = 1; // not sure about this
+ rev_edge[e1] = e2;
+ rev_edge[e2] = e1;
+ }
+
+ //-------------------------------------------------------------------------
+ // The Algorithm
+
+ tie(p, delta) = detail::min_degree_vertex(g);
+ S_star.push_back(p);
+ alpha_star = delta;
+ S.insert(p);
+ neighbor_S.insert(p);
+ detail::neighbors(g, S.begin(), S.end(),
+ std::inserter(neighbor_S, neighbor_S.begin()));
+
+ std::set_difference(vertices(g).first, vertices(g).second,
+ neighbor_S.begin(), neighbor_S.end(),
+ std::back_inserter(non_neighbor_S));
+
+ while (!non_neighbor_S.empty()) { // at most n - 1 times
+ k = non_neighbor_S.front();
+
+ alpha_S_k = edmunds_karp_max_flow
+ (flow_g, p, k, cap, res_cap, rev_edge, &color[0], &pred[0]);
+
+ if (alpha_S_k < alpha_star) {
+ alpha_star = alpha_S_k;
+ S_star.clear();
+ for (tie(vi, vi_end) = vertices(flow_g); vi != vi_end; ++vi)
+ if (color[*vi] != Color::white())
+ S_star.push_back(*vi);
+ }
+ S.insert(k);
+ neighbor_S.insert(k);
+ detail::neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin()));
+ non_neighbor_S.clear();
+ std::set_difference(vertices(g).first, vertices(g).second,
+ neighbor_S.begin(), neighbor_S.end(),
+ std::back_inserter(non_neighbor_S));
+ }
+ //-------------------------------------------------------------------------
+ // Compute edges of the cut [S*, ~S*]
+ std::vector<bool> in_S_star(num_vertices(g), false);
+ typename std::vector<vertex_descriptor>::iterator si;
+ for (si = S_star.begin(); si != S_star.end(); ++si)
+ in_S_star[*si] = true;
+
+ degree_size_type c = 0;
+ for (si = S_star.begin(); si != S_star.end(); ++si) {
+ out_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = out_edges(*si, g); ei != ei_end; ++ei)
+ if (!in_S_star[target(*ei, g)]) {
+ *disconnecting_set++ = *ei;
+ ++c;
+ }
+ }
+ return c;
+ }
+
+} // namespace boost
+
+#endif // BOOST_EDGE_CONNECTIVITY
Added: branches/CMake/release/libs/graph/include/boost/graph/edge_list.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/edge_list.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,304 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+
+#ifndef BOOST_GRAPH_EDGE_LIST_HPP
+#define BOOST_GRAPH_EDGE_LIST_HPP
+
+#include <iterator>
+#include <boost/config.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/pending/integer_range.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+
+namespace boost {
+
+ //
+ // The edge_list class is an EdgeListGraph module that is constructed
+ // from a pair of iterators whose value type is a pair of vertex
+ // descriptors.
+ //
+ // For example:
+ //
+ // typedef std::pair<int,int> E;
+ // list<E> elist;
+ // ...
+ // typedef edge_list<list<E>::iterator> Graph;
+ // Graph g(elist.begin(), elist.end());
+ //
+ // If the iterators are random access, then Graph::edge_descriptor
+ // is of Integral type, otherwise it is a struct, though it is
+ // convertible to an Integral type.
+ //
+
+ struct edge_list_tag { };
+
+ // The implementation class for edge_list.
+ template <class G, class EdgeIter, class T, class D>
+ class edge_list_impl
+ {
+ public:
+ typedef D edge_id;
+ typedef T Vpair;
+ typedef typename Vpair::first_type V;
+ typedef V vertex_descriptor;
+ typedef edge_list_tag graph_tag;
+ typedef void edge_property_type;
+
+ struct edge_descriptor
+ {
+ edge_descriptor() { }
+ edge_descriptor(EdgeIter p, edge_id id) : _ptr(p), _id(id) { }
+ operator edge_id() { return _id; }
+ EdgeIter _ptr;
+ edge_id _id;
+ };
+ typedef edge_descriptor E;
+
+ struct edge_iterator
+ {
+ typedef edge_iterator self;
+ typedef E value_type;
+ typedef E& reference;
+ typedef E* pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::input_iterator_tag iterator_category;
+ edge_iterator() { }
+ edge_iterator(EdgeIter iter) : _iter(iter), _i(0) { }
+ E operator*() { return E(_iter, _i); }
+ self& operator++() { ++_iter; ++_i; return *this; }
+ self operator++(int) { self t = *this; ++(*this); return t; }
+ bool operator==(const self& x) { return _iter == x._iter; }
+ bool operator!=(const self& x) { return _iter != x._iter; }
+ EdgeIter _iter;
+ edge_id _i;
+ };
+ typedef void out_edge_iterator;
+ typedef void in_edge_iterator;
+ typedef void adjacency_iterator;
+ typedef void vertex_iterator;
+ };
+
+ template <class G, class EI, class T, class D>
+ std::pair<typename edge_list_impl<G,EI,T,D>::edge_iterator,
+ typename edge_list_impl<G,EI,T,D>::edge_iterator>
+ edges(const edge_list_impl<G,EI,T,D>& g_) {
+ const G& g = static_cast<const G&>(g_);
+ typedef typename edge_list_impl<G,EI,T,D>::edge_iterator edge_iterator;
+ return std::make_pair(edge_iterator(g._first), edge_iterator(g._last));
+ }
+ template <class G, class EI, class T, class D>
+ typename edge_list_impl<G,EI,T,D>::vertex_descriptor
+ source(typename edge_list_impl<G,EI,T,D>::edge_descriptor e,
+ const edge_list_impl<G,EI,T,D>&) {
+ return (*e._ptr).first;
+ }
+ template <class G, class EI, class T, class D>
+ typename edge_list_impl<G,EI,T,D>::vertex_descriptor
+ target(typename edge_list_impl<G,EI,T,D>::edge_descriptor e,
+ const edge_list_impl<G,EI,T,D>&) {
+ return (*e._ptr).second;
+ }
+
+ template <class D, class E>
+ class el_edge_property_map
+ : public put_get_helper<D, el_edge_property_map<D,E> >{
+ public:
+ typedef E key_type;
+ typedef D value_type;
+ typedef D reference;
+ typedef readable_property_map_tag category;
+
+ value_type operator[](key_type e) const {
+ return e._i;
+ }
+ };
+ struct edge_list_edge_property_selector {
+ template <class Graph, class Property, class Tag>
+ struct bind_ {
+ typedef el_edge_property_map<typename Graph::edge_id,
+ typename Graph::edge_descriptor> type;
+ typedef type const_type;
+ };
+ };
+ template <>
+ struct edge_property_selector<edge_list_tag> {
+ typedef edge_list_edge_property_selector type;
+ };
+
+ template <class G, class EI, class T, class D>
+ typename property_map< edge_list_impl<G,EI,T,D>, edge_index_t>::type
+ get(edge_index_t, const edge_list_impl<G,EI,T,D>&) {
+ typedef typename property_map< edge_list_impl<G,EI,T,D>,
+ edge_index_t>::type EdgeIndexMap;
+ return EdgeIndexMap();
+ }
+
+ template <class G, class EI, class T, class D>
+ inline D
+ get(edge_index_t, const edge_list_impl<G,EI,T,D>&,
+ typename edge_list_impl<G,EI,T,D>::edge_descriptor e) {
+ return e._i;
+ }
+
+ // A specialized implementation for when the iterators are random access.
+
+ struct edge_list_ra_tag { };
+
+ template <class G, class EdgeIter, class T, class D>
+ class edge_list_impl_ra
+ {
+ public:
+ typedef D edge_id;
+ typedef T Vpair;
+ typedef typename Vpair::first_type V;
+ typedef edge_list_ra_tag graph_tag;
+ typedef void edge_property_type;
+
+ typedef edge_id edge_descriptor;
+ typedef V vertex_descriptor;
+ typedef typename boost::integer_range<edge_id>::iterator edge_iterator;
+ typedef void out_edge_iterator;
+ typedef void in_edge_iterator;
+ typedef void adjacency_iterator;
+ typedef void vertex_iterator;
+ };
+
+ template <class G, class EI, class T, class D>
+ std::pair<typename edge_list_impl_ra<G,EI,T,D>::edge_iterator,
+ typename edge_list_impl_ra<G,EI,T,D>::edge_iterator>
+ edges(const edge_list_impl_ra<G,EI,T,D>& g_)
+ {
+ const G& g = static_cast<const G&>(g_);
+ typedef typename edge_list_impl_ra<G,EI,T,D>::edge_iterator edge_iterator;
+ return std::make_pair(edge_iterator(0), edge_iterator(g._last - g._first));
+ }
+ template <class G, class EI, class T, class D>
+ typename edge_list_impl_ra<G,EI,T,D>::vertex_descriptor
+ source(typename edge_list_impl_ra<G,EI,T,D>::edge_descriptor e,
+ const edge_list_impl_ra<G,EI,T,D>& g_)
+ {
+ const G& g = static_cast<const G&>(g_);
+ return g._first[e].first;
+ }
+ template <class G, class EI, class T, class D>
+ typename edge_list_impl_ra<G,EI,T,D>::vertex_descriptor
+ target(typename edge_list_impl_ra<G,EI,T,D>::edge_descriptor e,
+ const edge_list_impl_ra<G,EI,T,D>& g_)
+ {
+ const G& g = static_cast<const G&>(g_);
+ return g._first[e].second;
+ }
+ template <class E>
+ class el_ra_edge_property_map
+ : public put_get_helper<E, el_ra_edge_property_map<E> >{
+ public:
+ typedef E key_type;
+ typedef E value_type;
+ typedef E reference;
+ typedef readable_property_map_tag category;
+
+ value_type operator[](key_type e) const {
+ return e;
+ }
+ };
+ struct edge_list_ra_edge_property_selector {
+ template <class Graph, class Property, class Tag>
+ struct bind_ {
+ typedef el_ra_edge_property_map<typename Graph::edge_descriptor> type;
+ typedef type const_type;
+ };
+ };
+ template <>
+ struct edge_property_selector<edge_list_ra_tag> {
+ typedef edge_list_ra_edge_property_selector type;
+ };
+ template <class G, class EI, class T, class D>
+ inline
+ typename property_map< edge_list_impl_ra<G,EI,T,D>, edge_index_t>::type
+ get(edge_index_t, const edge_list_impl_ra<G,EI,T,D>&) {
+ typedef typename property_map< edge_list_impl_ra<G,EI,T,D>,
+ edge_index_t>::type EdgeIndexMap;
+ return EdgeIndexMap();
+ }
+
+ template <class G, class EI, class T, class D>
+ inline D
+ get(edge_index_t, const edge_list_impl_ra<G,EI,T,D>&,
+ typename edge_list_impl_ra<G,EI,T,D>::edge_descriptor e) {
+ return e;
+ }
+
+
+ // Some helper classes for determining if the iterators are random access
+ template <class Cat>
+ struct is_random {
+ enum { RET = false };
+ typedef mpl::false_ type;
+ };
+ template <>
+ struct is_random<std::random_access_iterator_tag> {
+ enum { RET = true }; typedef mpl::true_ type;
+ };
+
+ // The edge_list class conditionally inherits from one of the
+ // above two classes.
+
+ template <class EdgeIter,
+#if !defined BOOST_NO_STD_ITERATOR_TRAITS
+ class T = typename std::iterator_traits<EdgeIter>::value_type,
+ class D = typename std::iterator_traits<EdgeIter>::difference_type,
+ class Cat = typename std::iterator_traits<EdgeIter>::iterator_category>
+#else
+ class T,
+ class D,
+ class Cat>
+#endif
+ class edge_list
+ : public mpl::if_< typename is_random<Cat>::type,
+ edge_list_impl_ra< edge_list<EdgeIter,T,D,Cat>, EdgeIter,T,D>,
+ edge_list_impl< edge_list<EdgeIter,T,D,Cat>, EdgeIter,T,D>
+ >::type
+ {
+ public:
+ typedef directed_tag directed_category;
+ typedef allow_parallel_edge_tag edge_parallel_category;
+ typedef edge_list_graph_tag traversal_category;
+ typedef std::size_t edges_size_type;
+ typedef std::size_t vertices_size_type;
+ typedef std::size_t degree_size_type;
+ edge_list(EdgeIter first, EdgeIter last) : _first(first), _last(last) {
+ m_num_edges = std::distance(first, last);
+ }
+ edge_list(EdgeIter first, EdgeIter last, edges_size_type E)
+ : _first(first), _last(last), m_num_edges(E) { }
+
+ EdgeIter _first, _last;
+ edges_size_type m_num_edges;
+ };
+
+ template <class EdgeIter, class T, class D, class Cat>
+ std::size_t num_edges(const edge_list<EdgeIter, T, D, Cat>& el) {
+ return el.m_num_edges;
+ }
+
+#ifndef BOOST_NO_STD_ITERATOR_TRAITS
+ template <class EdgeIter>
+ inline edge_list<EdgeIter>
+ make_edge_list(EdgeIter first, EdgeIter last)
+ {
+ return edge_list<EdgeIter>(first, last);
+ }
+#endif
+
+} /* namespace boost */
+
+#endif /* BOOST_GRAPH_EDGE_LIST_HPP */
Added: branches/CMake/release/libs/graph/include/boost/graph/edmunds_karp_max_flow.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/edmunds_karp_max_flow.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,250 @@
+//=======================================================================
+// Copyright 2000 University of Notre Dame.
+// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
+//
+// 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)
+//=======================================================================
+
+#ifndef EDMUNDS_KARP_MAX_FLOW_HPP
+#define EDMUNDS_KARP_MAX_FLOW_HPP
+
+#include <boost/config.hpp>
+#include <vector>
+#include <algorithm> // for std::min and std::max
+#include <boost/config.hpp>
+#include <boost/pending/queue.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/filtered_graph.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+
+namespace boost {
+
+ // The "labeling" algorithm from "Network Flows" by Ahuja, Magnanti,
+ // Orlin. I think this is the same as or very similar to the original
+ // Edmunds-Karp algorithm. This solves the maximum flow problem.
+
+ namespace detail {
+
+ template <class Graph, class ResCapMap>
+ filtered_graph<Graph, is_residual_edge<ResCapMap> >
+ residual_graph(Graph& g, ResCapMap residual_capacity) {
+ return filtered_graph<Graph, is_residual_edge<ResCapMap> >
+ (g, is_residual_edge<ResCapMap>(residual_capacity));
+ }
+
+ template <class Graph, class PredEdgeMap, class ResCapMap,
+ class RevEdgeMap>
+ inline void
+ augment(Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink,
+ PredEdgeMap p,
+ ResCapMap residual_capacity,
+ RevEdgeMap reverse_edge)
+ {
+ typename graph_traits<Graph>::edge_descriptor e;
+ typename graph_traits<Graph>::vertex_descriptor u;
+ typedef typename property_traits<ResCapMap>::value_type FlowValue;
+
+ // find minimum residual capacity along the augmenting path
+ FlowValue delta = (std::numeric_limits<FlowValue>::max)();
+ e = p[sink];
+ do {
+ BOOST_USING_STD_MIN();
+ delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, residual_capacity[e]);
+ u = source(e, g);
+ e = p[u];
+ } while (u != src);
+
+ // push delta units of flow along the augmenting path
+ e = p[sink];
+ do {
+ residual_capacity[e] -= delta;
+ residual_capacity[reverse_edge[e]] += delta;
+ u = source(e, g);
+ e = p[u];
+ } while (u != src);
+ }
+
+ } // namespace detail
+
+ template <class Graph,
+ class CapacityEdgeMap, class ResidualCapacityEdgeMap,
+ class ReverseEdgeMap, class ColorMap, class PredEdgeMap>
+ typename property_traits<CapacityEdgeMap>::value_type
+ edmunds_karp_max_flow
+ (Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink,
+ CapacityEdgeMap cap,
+ ResidualCapacityEdgeMap res,
+ ReverseEdgeMap rev,
+ ColorMap color,
+ PredEdgeMap pred)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+
+ typename graph_traits<Graph>::vertex_iterator u_iter, u_end;
+ typename graph_traits<Graph>::out_edge_iterator ei, e_end;
+ for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
+ for (tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
+ res[*ei] = cap[*ei];
+
+ color[sink] = Color::gray();
+ while (color[sink] != Color::white()) {
+ boost::queue<vertex_t> Q;
+ breadth_first_search
+ (detail::residual_graph(g, res), src, Q,
+ make_bfs_visitor(record_edge_predecessors(pred, on_tree_edge())),
+ color);
+ if (color[sink] != Color::white())
+ detail::augment(g, src, sink, pred, res, rev);
+ } // while
+
+ typename property_traits<CapacityEdgeMap>::value_type flow = 0;
+ for (tie(ei, e_end) = out_edges(src, g); ei != e_end; ++ei)
+ flow += (cap[*ei] - res[*ei]);
+ return flow;
+ } // edmunds_karp_max_flow()
+
+ namespace detail {
+ //-------------------------------------------------------------------------
+ // Handle default for color property map
+
+ // use of class here is a VC++ workaround
+ template <class ColorMap>
+ struct edmunds_karp_dispatch2 {
+ template <class Graph, class PredMap, class P, class T, class R>
+ static typename edge_capacity_value<Graph, P, T, R>::type
+ apply
+ (Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink,
+ PredMap pred,
+ const bgl_named_params<P, T, R>& params,
+ ColorMap color)
+ {
+ return edmunds_karp_max_flow
+ (g, src, sink,
+ choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
+ choose_pmap(get_param(params, edge_residual_capacity),
+ g, edge_residual_capacity),
+ choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
+ color, pred);
+ }
+ };
+ template<>
+ struct edmunds_karp_dispatch2<detail::error_property_not_found> {
+ template <class Graph, class PredMap, class P, class T, class R>
+ static typename edge_capacity_value<Graph, P, T, R>::type
+ apply
+ (Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink,
+ PredMap pred,
+ const bgl_named_params<P, T, R>& params,
+ detail::error_property_not_found)
+ {
+ typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
+ typedef typename graph_traits<Graph>::vertices_size_type size_type;
+ size_type n = is_default_param(get_param(params, vertex_color)) ?
+ num_vertices(g) : 1;
+ std::vector<default_color_type> color_vec(n);
+ return edmunds_karp_max_flow
+ (g, src, sink,
+ choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
+ choose_pmap(get_param(params, edge_residual_capacity),
+ g, edge_residual_capacity),
+ choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
+ make_iterator_property_map(color_vec.begin(), choose_const_pmap
+ (get_param(params, vertex_index),
+ g, vertex_index), color_vec[0]),
+ pred);
+ }
+ };
+
+ //-------------------------------------------------------------------------
+ // Handle default for predecessor property map
+
+ // use of class here is a VC++ workaround
+ template <class PredMap>
+ struct edmunds_karp_dispatch1 {
+ template <class Graph, class P, class T, class R>
+ static typename edge_capacity_value<Graph, P, T, R>::type
+ apply(Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink,
+ const bgl_named_params<P, T, R>& params,
+ PredMap pred)
+ {
+ typedef typename property_value< bgl_named_params<P,T,R>, vertex_color_t>::type C;
+ return edmunds_karp_dispatch2<C>::apply
+ (g, src, sink, pred, params, get_param(params, vertex_color));
+ }
+ };
+ template<>
+ struct edmunds_karp_dispatch1<detail::error_property_not_found> {
+
+ template <class Graph, class P, class T, class R>
+ static typename edge_capacity_value<Graph, P, T, R>::type
+ apply
+ (Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink,
+ const bgl_named_params<P, T, R>& params,
+ detail::error_property_not_found)
+ {
+ typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
+ typedef typename graph_traits<Graph>::vertices_size_type size_type;
+ size_type n = is_default_param(get_param(params, vertex_predecessor)) ?
+ num_vertices(g) : 1;
+ std::vector<edge_descriptor> pred_vec(n);
+
+ typedef typename property_value< bgl_named_params<P,T,R>, vertex_color_t>::type C;
+ return edmunds_karp_dispatch2<C>::apply
+ (g, src, sink,
+ make_iterator_property_map(pred_vec.begin(), choose_const_pmap
+ (get_param(params, vertex_index),
+ g, vertex_index), pred_vec[0]),
+ params,
+ get_param(params, vertex_color));
+ }
+ };
+
+ } // namespace detail
+
+ template <class Graph, class P, class T, class R>
+ typename detail::edge_capacity_value<Graph, P, T, R>::type
+ edmunds_karp_max_flow
+ (Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef typename property_value< bgl_named_params<P,T,R>, vertex_predecessor_t>::type Pred;
+ return detail::edmunds_karp_dispatch1<Pred>::apply
+ (g, src, sink, params, get_param(params, vertex_predecessor));
+ }
+
+ template <class Graph>
+ typename property_traits<
+ typename property_map<Graph, edge_capacity_t>::const_type
+ >::value_type
+ edmunds_karp_max_flow
+ (Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink)
+ {
+ bgl_named_params<int, buffer_param_t> params(0);
+ return edmunds_karp_max_flow(g, src, sink, params);
+ }
+
+} // namespace boost
+
+#endif // EDMUNDS_KARP_MAX_FLOW_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/erdos_renyi_generator.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/erdos_renyi_generator.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,228 @@
+// Copyright 2004, 2005 The Trustees of Indiana University.
+
+// 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)
+
+// Authors: Jeremiah Willcock
+// Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_ERDOS_RENYI_GENERATOR_HPP
+#define BOOST_GRAPH_ERDOS_RENYI_GENERATOR_HPP
+
+#include <cassert>
+#include <iterator>
+#include <utility>
+#include <boost/shared_ptr.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/random/geometric_distribution.hpp>
+#include <boost/type_traits/is_base_and_derived.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <cmath>
+
+namespace boost {
+
+ template<typename RandomGenerator, typename Graph>
+ class erdos_renyi_iterator
+ {
+ typedef typename graph_traits<Graph>::directed_category directed_category;
+ typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
+ typedef typename graph_traits<Graph>::edges_size_type edges_size_type;
+
+ BOOST_STATIC_CONSTANT
+ (bool,
+ is_undirected = (is_base_and_derived<undirected_tag,
+ directed_category>::value
+ || is_same<undirected_tag, directed_category>::value));
+
+ public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair<vertices_size_type, vertices_size_type> value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef void difference_type;
+
+ erdos_renyi_iterator() : gen(), n(0), edges(0), allow_self_loops(false) {}
+ erdos_renyi_iterator(RandomGenerator& gen, vertices_size_type n,
+ double fraction = 0.0, bool allow_self_loops = false)
+ : gen(&gen), n(n), edges(edges_size_type(fraction * n * n)),
+ allow_self_loops(allow_self_loops)
+ {
+ if (is_undirected) edges = edges / 2;
+ next();
+ }
+
+ erdos_renyi_iterator(RandomGenerator& gen, vertices_size_type n,
+ edges_size_type m, bool allow_self_loops = false)
+ : gen(&gen), n(n), edges(m),
+ allow_self_loops(allow_self_loops)
+ {
+ next();
+ }
+
+ reference operator*() const { return current; }
+ pointer operator->() const { return ¤t; }
+
+ erdos_renyi_iterator& operator++()
+ {
+ --edges;
+ next();
+ return *this;
+ }
+
+ erdos_renyi_iterator operator++(int)
+ {
+ erdos_renyi_iterator temp(*this);
+ ++(*this);
+ return temp;
+ }
+
+ bool operator==(const erdos_renyi_iterator& other) const
+ { return edges == other.edges; }
+
+ bool operator!=(const erdos_renyi_iterator& other) const
+ { return !(*this == other); }
+
+ private:
+ void next()
+ {
+ uniform_int<vertices_size_type> rand_vertex(0, n-1);
+ current.first = rand_vertex(*gen);
+ do {
+ current.second = rand_vertex(*gen);
+ } while (current.first == current.second && !allow_self_loops);
+ }
+
+ RandomGenerator* gen;
+ vertices_size_type n;
+ edges_size_type edges;
+ bool allow_self_loops;
+ value_type current;
+ };
+
+ template<typename RandomGenerator, typename Graph>
+ class sorted_erdos_renyi_iterator
+ {
+ typedef typename graph_traits<Graph>::directed_category directed_category;
+ typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
+ typedef typename graph_traits<Graph>::edges_size_type edges_size_type;
+
+ BOOST_STATIC_CONSTANT
+ (bool,
+ is_undirected = (is_base_and_derived<undirected_tag,
+ directed_category>::value
+ || is_same<undirected_tag, directed_category>::value));
+
+ public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair<vertices_size_type, vertices_size_type> value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef void difference_type;
+
+ sorted_erdos_renyi_iterator()
+ : gen(), rand_vertex(0.5), n(0), allow_self_loops(false),
+ src((std::numeric_limits<vertices_size_type>::max)()), tgt(0), prob(0) {}
+ sorted_erdos_renyi_iterator(RandomGenerator& gen, vertices_size_type n,
+ double prob = 0.0,
+ bool allow_self_loops = false)
+ : gen(),
+ // The "1.0 - prob" in the next line is to work around a Boost.Random
+ // (and TR1) bug in the specification of geometric_distribution. It
+ // should be replaced by "prob" when the issue is fixed.
+ rand_vertex(1.0 - prob),
+ n(n), allow_self_loops(allow_self_loops), src(0), tgt(0), prob(prob)
+ {
+ this->gen.reset(new uniform_01<RandomGenerator>(gen));
+
+ if (prob == 0.0) {src = (std::numeric_limits<vertices_size_type>::max)(); return;}
+ next();
+ }
+
+ reference operator*() const { return current; }
+ pointer operator->() const { return ¤t; }
+
+ sorted_erdos_renyi_iterator& operator++()
+ {
+ next();
+ return *this;
+ }
+
+ sorted_erdos_renyi_iterator operator++(int)
+ {
+ sorted_erdos_renyi_iterator temp(*this);
+ ++(*this);
+ return temp;
+ }
+
+ bool operator==(const sorted_erdos_renyi_iterator& other) const
+ { return src == other.src && tgt == other.tgt; }
+
+ bool operator!=(const sorted_erdos_renyi_iterator& other) const
+ { return !(*this == other); }
+
+ private:
+ void next()
+ {
+ using std::sqrt;
+ using std::floor;
+
+ // In order to get the edges from the generator in sorted order, one
+ // effective (but slow) procedure would be to use a
+ // bernoulli_distribution for each legal (src, tgt) pair. Because of the
+ // O(n^2) cost of that, a geometric distribution is used. The geometric
+ // distribution tells how many times the bernoulli_distribution would
+ // need to be run until it returns true. Thus, this distribution can be
+ // used to step through the edges which are actually present. Everything
+ // beyond "tgt += increment" is done to effectively convert linear
+ // indexing (the partial sums of the geometric distribution output) into
+ // graph edges.
+ assert (src != (std::numeric_limits<vertices_size_type>::max)());
+ vertices_size_type increment = rand_vertex(*gen);
+ tgt += increment;
+ if (is_undirected) {
+ // Update src and tgt based on position of tgt
+ // Basically, we want the greatest src_increment such that (in \bbQ):
+ // src_increment * (src + allow_self_loops + src_increment - 1/2) <= tgt
+ // The result of the LHS of this, evaluated with the computed
+ // src_increment, is then subtracted from tgt
+ double src_minus_half = (src + allow_self_loops) - 0.5;
+ double disc = src_minus_half * src_minus_half + 2 * tgt;
+ double src_increment_fp = floor(sqrt(disc) - src_minus_half);
+ vertices_size_type src_increment = vertices_size_type(src_increment_fp);
+ if (src + src_increment >= n) {
+ src = n;
+ } else {
+ tgt -= (src + allow_self_loops) * src_increment +
+ src_increment * (src_increment - 1) / 2;
+ src += src_increment;
+ }
+ } else {
+ // Number of out edge positions possible from each vertex in this graph
+ vertices_size_type possible_out_edges = n - (allow_self_loops ? 0 : 1);
+ src += (std::min)(n - src, tgt / possible_out_edges);
+ tgt %= possible_out_edges;
+ }
+ // Set end of graph code so (src, tgt) will be the same as for the end
+ // sorted_erdos_renyi_iterator
+ if (src >= n) {src = (std::numeric_limits<vertices_size_type>::max)(); tgt = 0;}
+ // Copy (src, tgt) into current
+ current.first = src;
+ current.second = tgt;
+ // Adjust for (src, src) edge being forbidden
+ if (!allow_self_loops && tgt >= src) ++current.second;
+ }
+
+ shared_ptr<uniform_01<RandomGenerator> > gen;
+ geometric_distribution<vertices_size_type> rand_vertex;
+ vertices_size_type n;
+ bool allow_self_loops;
+ vertices_size_type src, tgt;
+ value_type current;
+ double prob;
+ };
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_ERDOS_RENYI_GENERATOR_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/exception.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/exception.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,44 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_EXCEPTION_HPP
+#define BOOST_GRAPH_EXCEPTION_HPP
+
+#include <stdexcept>
+#include <string>
+
+namespace boost {
+
+ struct bad_graph : public std::invalid_argument {
+ bad_graph(const std::string& what_arg)
+ : std::invalid_argument(what_arg) { }
+ };
+
+ struct not_a_dag : public bad_graph {
+ not_a_dag()
+ : bad_graph("The graph must be a DAG.") { }
+ };
+
+ struct negative_edge : public bad_graph {
+ negative_edge()
+ : bad_graph("The graph may not contain an edge with negative weight."){ }
+ };
+
+ struct negative_cycle : public bad_graph {
+ negative_cycle()
+ : bad_graph("The graph may not contain negative cycles.") { }
+ };
+ struct not_connected : public bad_graph {
+ not_connected()
+ : bad_graph("The graph must be connected.") { }
+ };
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_EXCEPTION_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/filtered_graph.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/filtered_graph.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,507 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_FILTERED_GRAPH_HPP
+#define BOOST_FILTERED_GRAPH_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/adjacency_iterator.hpp>
+#include <boost/iterator/filter_iterator.hpp>
+
+namespace boost {
+
+ //=========================================================================
+ // Some predicate classes.
+
+ struct keep_all {
+ template <typename T>
+ bool operator()(const T&) const { return true; }
+ };
+
+ // Keep residual edges (used in maximum-flow algorithms).
+ template <typename ResidualCapacityEdgeMap>
+ struct is_residual_edge {
+ is_residual_edge() { }
+ is_residual_edge(ResidualCapacityEdgeMap rcap) : m_rcap(rcap) { }
+ template <typename Edge>
+ bool operator()(const Edge& e) const {
+ return 0 < get(m_rcap, e);
+ }
+ ResidualCapacityEdgeMap m_rcap;
+ };
+
+ template <typename Set>
+ struct is_in_subset {
+ is_in_subset() : m_s(0) { }
+ is_in_subset(const Set& s) : m_s(&s) { }
+
+ template <typename Elt>
+ bool operator()(const Elt& x) const {
+ return set_contains(*m_s, x);
+ }
+ const Set* m_s;
+ };
+
+ template <typename Set>
+ struct is_not_in_subset {
+ is_not_in_subset() : m_s(0) { }
+ is_not_in_subset(const Set& s) : m_s(&s) { }
+
+ template <typename Elt>
+ bool operator()(const Elt& x) const {
+ return !set_contains(*m_s, x);
+ }
+ const Set* m_s;
+ };
+
+ namespace detail {
+
+ template <typename EdgePredicate, typename VertexPredicate, typename Graph>
+ struct out_edge_predicate {
+ out_edge_predicate() { }
+ out_edge_predicate(EdgePredicate ep, VertexPredicate vp,
+ const Graph& g)
+ : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) { }
+
+ template <typename Edge>
+ bool operator()(const Edge& e) const {
+ return m_edge_pred(e) && m_vertex_pred(target(e, *m_g));
+ }
+ EdgePredicate m_edge_pred;
+ VertexPredicate m_vertex_pred;
+ const Graph* m_g;
+ };
+
+ template <typename EdgePredicate, typename VertexPredicate, typename Graph>
+ struct in_edge_predicate {
+ in_edge_predicate() { }
+ in_edge_predicate(EdgePredicate ep, VertexPredicate vp,
+ const Graph& g)
+ : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) { }
+
+ template <typename Edge>
+ bool operator()(const Edge& e) const {
+ return m_edge_pred(e) && m_vertex_pred(source(e, *m_g));
+ }
+ EdgePredicate m_edge_pred;
+ VertexPredicate m_vertex_pred;
+ const Graph* m_g;
+ };
+
+ template <typename EdgePredicate, typename VertexPredicate, typename Graph>
+ struct edge_predicate {
+ edge_predicate() { }
+ edge_predicate(EdgePredicate ep, VertexPredicate vp,
+ const Graph& g)
+ : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) { }
+
+ template <typename Edge>
+ bool operator()(const Edge& e) const {
+ return m_edge_pred(e)
+ && m_vertex_pred(source(e, *m_g)) && m_vertex_pred(target(e, *m_g));
+ }
+ EdgePredicate m_edge_pred;
+ VertexPredicate m_vertex_pred;
+ const Graph* m_g;
+ };
+
+ } // namespace detail
+
+
+ //===========================================================================
+ // Filtered Graph
+
+ struct filtered_graph_tag { };
+
+ // This base class is a stupid hack to change overload resolution
+ // rules for the source and target functions so that they are a
+ // worse match than the source and target functions defined for
+ // pairs in graph_traits.hpp. I feel dirty. -JGS
+ template <class G>
+ struct filtered_graph_base {
+ typedef graph_traits<G> Traits;
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+ typedef typename Traits::edge_descriptor edge_descriptor;
+ filtered_graph_base(const G& g) : m_g(g) { }
+ //protected:
+ const G& m_g;
+ };
+
+ template <typename Graph,
+ typename EdgePredicate,
+ typename VertexPredicate = keep_all>
+ class filtered_graph : public filtered_graph_base<Graph> {
+ typedef filtered_graph_base<Graph> Base;
+ typedef graph_traits<Graph> Traits;
+ typedef filtered_graph self;
+ public:
+ typedef Graph graph_type;
+ typedef detail::out_edge_predicate<EdgePredicate,
+ VertexPredicate, self> OutEdgePred;
+ typedef detail::in_edge_predicate<EdgePredicate,
+ VertexPredicate, self> InEdgePred;
+ typedef detail::edge_predicate<EdgePredicate,
+ VertexPredicate, self> EdgePred;
+
+ // Constructors
+ filtered_graph(const Graph& g, EdgePredicate ep)
+ : Base(g), m_edge_pred(ep) { }
+
+ filtered_graph(const Graph& g, EdgePredicate ep, VertexPredicate vp)
+ : Base(g), m_edge_pred(ep), m_vertex_pred(vp) { }
+
+ // Graph requirements
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+ typedef typename Traits::edge_descriptor edge_descriptor;
+ typedef typename Traits::directed_category directed_category;
+ typedef typename Traits::edge_parallel_category edge_parallel_category;
+ typedef typename Traits::traversal_category traversal_category;
+
+ // IncidenceGraph requirements
+ typedef filter_iterator<
+ OutEdgePred, typename Traits::out_edge_iterator
+ > out_edge_iterator;
+
+ typedef typename Traits::degree_size_type degree_size_type;
+
+ // AdjacencyGraph requirements
+ typedef typename adjacency_iterator_generator<self,
+ vertex_descriptor, out_edge_iterator>::type adjacency_iterator;
+
+ // BidirectionalGraph requirements
+ typedef filter_iterator<
+ InEdgePred, typename Traits::in_edge_iterator
+ > in_edge_iterator;
+
+ // VertexListGraph requirements
+ typedef filter_iterator<
+ VertexPredicate, typename Traits::vertex_iterator
+ > vertex_iterator;
+ typedef typename Traits::vertices_size_type vertices_size_type;
+
+ // EdgeListGraph requirements
+ typedef filter_iterator<
+ EdgePred, typename Traits::edge_iterator
+ > edge_iterator;
+ typedef typename Traits::edges_size_type edges_size_type;
+
+ typedef typename ::boost::edge_property_type<Graph>::type edge_property_type;
+ typedef typename ::boost::vertex_property_type<Graph>::type vertex_property_type;
+ typedef filtered_graph_tag graph_tag;
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ // Bundled properties support
+ template<typename Descriptor>
+ typename graph::detail::bundled_result<Graph, Descriptor>::type&
+ operator[](Descriptor x)
+ { return const_cast<Graph&>(this->m_g)[x]; }
+
+ template<typename Descriptor>
+ typename graph::detail::bundled_result<Graph, Descriptor>::type const&
+ operator[](Descriptor x) const
+ { return this->m_g[x]; }
+#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+
+ static vertex_descriptor null_vertex()
+ {
+ return Graph::null_vertex();
+ }
+
+ //private:
+ EdgePredicate m_edge_pred;
+ VertexPredicate m_vertex_pred;
+ };
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ template<typename Graph, typename EdgePredicate, typename VertexPredicate>
+ struct vertex_bundle_type<filtered_graph<Graph, EdgePredicate,
+ VertexPredicate> >
+ : vertex_bundle_type<Graph> { };
+
+ template<typename Graph, typename EdgePredicate, typename VertexPredicate>
+ struct edge_bundle_type<filtered_graph<Graph, EdgePredicate,
+ VertexPredicate> >
+ : edge_bundle_type<Graph> { };
+#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+
+ //===========================================================================
+ // Non-member functions for the Filtered Edge Graph
+
+ // Helper functions
+ template <typename Graph, typename EdgePredicate>
+ inline filtered_graph<Graph, EdgePredicate>
+ make_filtered_graph(Graph& g, EdgePredicate ep) {
+ return filtered_graph<Graph, EdgePredicate>(g, ep);
+ }
+ template <typename Graph, typename EdgePredicate, typename VertexPredicate>
+ inline filtered_graph<Graph, EdgePredicate, VertexPredicate>
+ make_filtered_graph(Graph& g, EdgePredicate ep, VertexPredicate vp) {
+ return filtered_graph<Graph, EdgePredicate, VertexPredicate>(g, ep, vp);
+ }
+
+ template <typename Graph, typename EdgePredicate>
+ inline filtered_graph<const Graph, EdgePredicate>
+ make_filtered_graph(const Graph& g, EdgePredicate ep) {
+ return filtered_graph<const Graph, EdgePredicate>(g, ep);
+ }
+ template <typename Graph, typename EdgePredicate, typename VertexPredicate>
+ inline filtered_graph<const Graph, EdgePredicate, VertexPredicate>
+ make_filtered_graph(const Graph& g, EdgePredicate ep, VertexPredicate vp) {
+ return filtered_graph<const Graph, EdgePredicate, VertexPredicate>(g, ep, vp);
+ }
+
+ template <typename G, typename EP, typename VP>
+ std::pair<typename filtered_graph<G, EP, VP>::vertex_iterator,
+ typename filtered_graph<G, EP, VP>::vertex_iterator>
+ vertices(const filtered_graph<G, EP, VP>& g)
+ {
+ typedef filtered_graph<G, EP, VP> Graph;
+ typename graph_traits<G>::vertex_iterator f, l;
+ tie(f, l) = vertices(g.m_g);
+ typedef typename Graph::vertex_iterator iter;
+ return std::make_pair(iter(g.m_vertex_pred, f, l),
+ iter(g.m_vertex_pred, l, l));
+ }
+
+ template <typename G, typename EP, typename VP>
+ std::pair<typename filtered_graph<G, EP, VP>::edge_iterator,
+ typename filtered_graph<G, EP, VP>::edge_iterator>
+ edges(const filtered_graph<G, EP, VP>& g)
+ {
+ typedef filtered_graph<G, EP, VP> Graph;
+ typename Graph::EdgePred pred(g.m_edge_pred, g.m_vertex_pred, g);
+ typename graph_traits<G>::edge_iterator f, l;
+ tie(f, l) = edges(g.m_g);
+ typedef typename Graph::edge_iterator iter;
+ return std::make_pair(iter(pred, f, l), iter(pred, l, l));
+ }
+
+ // An alternative for num_vertices() and num_edges() would be to
+ // count the number in the filtered graph. This is problematic
+ // because of the interaction with the vertex indices... they would
+ // no longer go from 0 to num_vertices(), which would cause trouble
+ // for algorithms allocating property storage in an array. We could
+ // try to create a mapping to new recalibrated indices, but I don't
+ // see an efficient way to do this.
+ //
+ // However, the current solution is still unsatisfactory because
+ // the following semantic constraints no longer hold:
+ // tie(vi, viend) = vertices(g);
+ // assert(std::distance(vi, viend) == num_vertices(g));
+
+ template <typename G, typename EP, typename VP>
+ typename filtered_graph<G, EP, VP>::vertices_size_type
+ num_vertices(const filtered_graph<G, EP, VP>& g) {
+ return num_vertices(g.m_g);
+ }
+
+ template <typename G, typename EP, typename VP>
+ typename filtered_graph<G, EP, VP>::edges_size_type
+ num_edges(const filtered_graph<G, EP, VP>& g) {
+ return num_edges(g.m_g);
+ }
+
+ template <typename G>
+ typename filtered_graph_base<G>::vertex_descriptor
+ source(typename filtered_graph_base<G>::edge_descriptor e,
+ const filtered_graph_base<G>& g)
+ {
+ return source(e, g.m_g);
+ }
+
+ template <typename G>
+ typename filtered_graph_base<G>::vertex_descriptor
+ target(typename filtered_graph_base<G>::edge_descriptor e,
+ const filtered_graph_base<G>& g)
+ {
+ return target(e, g.m_g);
+ }
+
+ template <typename G, typename EP, typename VP>
+ std::pair<typename filtered_graph<G, EP, VP>::out_edge_iterator,
+ typename filtered_graph<G, EP, VP>::out_edge_iterator>
+ out_edges(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
+ const filtered_graph<G, EP, VP>& g)
+ {
+ typedef filtered_graph<G, EP, VP> Graph;
+ typename Graph::OutEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g);
+ typedef typename Graph::out_edge_iterator iter;
+ typename graph_traits<G>::out_edge_iterator f, l;
+ tie(f, l) = out_edges(u, g.m_g);
+ return std::make_pair(iter(pred, f, l), iter(pred, l, l));
+ }
+
+ template <typename G, typename EP, typename VP>
+ typename filtered_graph<G, EP, VP>::degree_size_type
+ out_degree(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
+ const filtered_graph<G, EP, VP>& g)
+ {
+ typename filtered_graph<G, EP, VP>::degree_size_type n = 0;
+ typename filtered_graph<G, EP, VP>::out_edge_iterator f, l;
+ for (tie(f, l) = out_edges(u, g); f != l; ++f)
+ ++n;
+ return n;
+ }
+
+ template <typename G, typename EP, typename VP>
+ std::pair<typename filtered_graph<G, EP, VP>::adjacency_iterator,
+ typename filtered_graph<G, EP, VP>::adjacency_iterator>
+ adjacent_vertices(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
+ const filtered_graph<G, EP, VP>& g)
+ {
+ typedef filtered_graph<G, EP, VP> Graph;
+ typedef typename Graph::adjacency_iterator adjacency_iterator;
+ typename Graph::out_edge_iterator f, l;
+ tie(f, l) = out_edges(u, g);
+ return std::make_pair(adjacency_iterator(f, const_cast<Graph*>(&g)),
+ adjacency_iterator(l, const_cast<Graph*>(&g)));
+ }
+
+ template <typename G, typename EP, typename VP>
+ std::pair<typename filtered_graph<G, EP, VP>::in_edge_iterator,
+ typename filtered_graph<G, EP, VP>::in_edge_iterator>
+ in_edges(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
+ const filtered_graph<G, EP, VP>& g)
+ {
+ typedef filtered_graph<G, EP, VP> Graph;
+ typename Graph::InEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g);
+ typedef typename Graph::in_edge_iterator iter;
+ typename graph_traits<G>::in_edge_iterator f, l;
+ tie(f, l) = in_edges(u, g.m_g);
+ return std::make_pair(iter(pred, f, l), iter(pred, l, l));
+ }
+
+ template <typename G, typename EP, typename VP>
+ typename filtered_graph<G, EP, VP>::degree_size_type
+ in_degree(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
+ const filtered_graph<G, EP, VP>& g)
+ {
+ typename filtered_graph<G, EP, VP>::degree_size_type n = 0;
+ typename filtered_graph<G, EP, VP>::in_edge_iterator f, l;
+ for (tie(f, l) = in_edges(u, g); f != l; ++f)
+ ++n;
+ return n;
+ }
+
+ template <typename G, typename EP, typename VP>
+ std::pair<typename filtered_graph<G, EP, VP>::edge_descriptor, bool>
+ edge(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
+ typename filtered_graph<G, EP, VP>::vertex_descriptor v,
+ const filtered_graph<G, EP, VP>& g)
+ {
+ typename graph_traits<G>::edge_descriptor e;
+ bool exists;
+ tie(e, exists) = edge(u, v, g.m_g);
+ return std::make_pair(e, exists && g.m_edge_pred(e));
+ }
+
+ template <typename G, typename EP, typename VP>
+ std::pair<typename filtered_graph<G, EP, VP>::out_edge_iterator,
+ typename filtered_graph<G, EP, VP>::out_edge_iterator>
+ edge_range(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
+ typename filtered_graph<G, EP, VP>::vertex_descriptor v,
+ const filtered_graph<G, EP, VP>& g)
+ {
+ typedef filtered_graph<G, EP, VP> Graph;
+ typename Graph::OutEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g);
+ typedef typename Graph::out_edge_iterator iter;
+ typename graph_traits<G>::out_edge_iterator f, l;
+ tie(f, l) = edge_range(u, v, g.m_g);
+ return std::make_pair(iter(pred, f, l), iter(pred, l, l));
+ }
+
+
+ //===========================================================================
+ // Property map
+
+ namespace detail {
+ struct filtered_graph_property_selector {
+ template <class FilteredGraph, class Property, class Tag>
+ struct bind_ {
+ typedef typename FilteredGraph::graph_type Graph;
+ typedef property_map<Graph, Tag> Map;
+ typedef typename Map::type type;
+ typedef typename Map::const_type const_type;
+ };
+ };
+ } // namespace detail
+
+ template <>
+ struct vertex_property_selector<filtered_graph_tag> {
+ typedef detail::filtered_graph_property_selector type;
+ };
+ template <>
+ struct edge_property_selector<filtered_graph_tag> {
+ typedef detail::filtered_graph_property_selector type;
+ };
+
+ template <typename G, typename EP, typename VP, typename Property>
+ typename property_map<G, Property>::type
+ get(Property p, filtered_graph<G, EP, VP>& g)
+ {
+ return get(p, const_cast<G&>(g.m_g));
+ }
+
+ template <typename G, typename EP, typename VP,typename Property>
+ typename property_map<G, Property>::const_type
+ get(Property p, const filtered_graph<G, EP, VP>& g)
+ {
+ return get(p, (const G&)g.m_g);
+ }
+
+ template <typename G, typename EP, typename VP, typename Property,
+ typename Key>
+ typename property_map_value<G, Property>::type
+ get(Property p, const filtered_graph<G, EP, VP>& g, const Key& k)
+ {
+ return get(p, (const G&)g.m_g, k);
+ }
+
+ template <typename G, typename EP, typename VP, typename Property,
+ typename Key, typename Value>
+ void
+ put(Property p, const filtered_graph<G, EP, VP>& g, const Key& k,
+ const Value& val)
+ {
+ put(p, const_cast<G&>(g.m_g), k, val);
+ }
+
+ //===========================================================================
+ // Some filtered subgraph specializations
+
+ template <typename Graph, typename Set>
+ struct vertex_subset_filter {
+ typedef filtered_graph<Graph, keep_all, is_in_subset<Set> > type;
+ };
+ template <typename Graph, typename Set>
+ inline typename vertex_subset_filter<Graph, Set>::type
+ make_vertex_subset_filter(Graph& g, const Set& s) {
+ typedef typename vertex_subset_filter<Graph, Set>::type Filter;
+ is_in_subset<Set> p(s);
+ return Filter(g, keep_all(), p);
+ }
+
+ template <typename Graph, typename Set>
+ struct vertex_subset_compliment_filter {
+ typedef filtered_graph<Graph, keep_all, is_not_in_subset<Set> > type;
+ };
+ template <typename Graph, typename Set>
+ inline typename vertex_subset_compliment_filter<Graph, Set>::type
+ make_vertex_subset_compliment_filter(Graph& g, const Set& s) {
+ typedef typename vertex_subset_compliment_filter<Graph, Set>::type Filter;
+ is_not_in_subset<Set> p(s);
+ return Filter(g, keep_all(), p);
+ }
+
+
+} // namespace boost
+
+
+#endif // BOOST_FILTERED_GRAPH_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/floyd_warshall_shortest.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/floyd_warshall_shortest.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,251 @@
+// Copyright 2002 Rensselaer Polytechnic Institute
+
+// 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)
+
+// Authors: Lauren Foutz
+// Scott Hill
+
+/*
+ This file implements the functions
+
+ template <class VertexListGraph, class DistanceMatrix,
+ class P, class T, class R>
+ bool floyd_warshall_initialized_all_pairs_shortest_paths(
+ const VertexListGraph& g, DistanceMatrix& d,
+ const bgl_named_params<P, T, R>& params)
+
+ AND
+
+ template <class VertexAndEdgeListGraph, class DistanceMatrix,
+ class P, class T, class R>
+ bool floyd_warshall_all_pairs_shortest_paths(
+ const VertexAndEdgeListGraph& g, DistanceMatrix& d,
+ const bgl_named_params<P, T, R>& params)
+*/
+
+
+#ifndef BOOST_GRAPH_FLOYD_WARSHALL_HPP
+#define BOOST_GRAPH_FLOYD_WARSHALL_HPP
+
+#include <boost/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/relax.hpp>
+
+namespace boost
+{
+ namespace detail {
+ template<typename T, typename BinaryPredicate>
+ T min_with_compare(const T& x, const T& y, const BinaryPredicate& compare)
+ {
+ if (compare(x, y)) return x;
+ else return y;
+ }
+
+ template<typename VertexListGraph, typename DistanceMatrix,
+ typename BinaryPredicate, typename BinaryFunction,
+ typename Infinity, typename Zero>
+ bool floyd_warshall_dispatch(const VertexListGraph& g,
+ DistanceMatrix& d, const BinaryPredicate &compare,
+ const BinaryFunction &combine, const Infinity& inf,
+ const Zero& zero)
+ {
+ typename graph_traits<VertexListGraph>::vertex_iterator
+ i, lasti, j, lastj, k, lastk;
+
+
+ for (tie(k, lastk) = vertices(g); k != lastk; k++)
+ for (tie(i, lasti) = vertices(g); i != lasti; i++)
+ for (tie(j, lastj) = vertices(g); j != lastj; j++)
+ {
+ d[*i][*j] =
+ detail::min_with_compare(d[*i][*j],
+ combine(d[*i][*k], d[*k][*j]),
+ compare);
+ }
+
+
+ for (tie(i, lasti) = vertices(g); i != lasti; i++)
+ if (compare(d[*i][*i], zero))
+ return false;
+ return true;
+ }
+ }
+
+ template <typename VertexListGraph, typename DistanceMatrix,
+ typename BinaryPredicate, typename BinaryFunction,
+ typename Infinity, typename Zero>
+ bool floyd_warshall_initialized_all_pairs_shortest_paths(
+ const VertexListGraph& g, DistanceMatrix& d,
+ const BinaryPredicate& compare,
+ const BinaryFunction& combine, const Infinity& inf,
+ const Zero& zero)
+ {
+ function_requires<VertexListGraphConcept<VertexListGraph> >();
+
+ return detail::floyd_warshall_dispatch(g, d, compare, combine,
+ inf, zero);
+ }
+
+
+
+ template <typename VertexAndEdgeListGraph, typename DistanceMatrix,
+ typename WeightMap, typename BinaryPredicate,
+ typename BinaryFunction, typename Infinity, typename Zero>
+ bool floyd_warshall_all_pairs_shortest_paths(
+ const VertexAndEdgeListGraph& g,
+ DistanceMatrix& d, const WeightMap& w,
+ const BinaryPredicate& compare, const BinaryFunction& combine,
+ const Infinity& inf, const Zero& zero)
+ {
+ function_requires<VertexListGraphConcept<VertexAndEdgeListGraph> >();
+ function_requires<EdgeListGraphConcept<VertexAndEdgeListGraph> >();
+ function_requires<IncidenceGraphConcept<VertexAndEdgeListGraph> >();
+
+ typename graph_traits<VertexAndEdgeListGraph>::vertex_iterator
+ firstv, lastv, firstv2, lastv2;
+ typename graph_traits<VertexAndEdgeListGraph>::edge_iterator first, last;
+
+
+ for(tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++)
+ for(tie(firstv2, lastv2) = vertices(g); firstv2 != lastv2; firstv2++)
+ d[*firstv][*firstv2] = inf;
+
+
+ for(tie(firstv, lastv) = vertices(g); firstv != lastv; firstv++)
+ d[*firstv][*firstv] = zero;
+
+
+ for(tie(first, last) = edges(g); first != last; first++)
+ {
+ if (d[source(*first, g)][target(*first, g)] != inf) {
+ d[source(*first, g)][target(*first, g)] =
+ detail::min_with_compare(
+ get(w, *first),
+ d[source(*first, g)][target(*first, g)],
+ compare);
+ } else
+ d[source(*first, g)][target(*first, g)] = get(w, *first);
+ }
+
+ bool is_undirected = is_same<typename
+ graph_traits<VertexAndEdgeListGraph>::directed_category,
+ undirected_tag>::value;
+ if (is_undirected)
+ {
+ for(tie(first, last) = edges(g); first != last; first++)
+ {
+ if (d[target(*first, g)][source(*first, g)] != inf)
+ d[target(*first, g)][source(*first, g)] =
+ detail::min_with_compare(
+ get(w, *first),
+ d[target(*first, g)][source(*first, g)],
+ compare);
+ else
+ d[target(*first, g)][source(*first, g)] = get(w, *first);
+ }
+ }
+
+
+ return detail::floyd_warshall_dispatch(g, d, compare, combine,
+ inf, zero);
+ }
+
+
+ namespace detail {
+ template <class VertexListGraph, class DistanceMatrix,
+ class WeightMap, class P, class T, class R>
+ bool floyd_warshall_init_dispatch(const VertexListGraph& g,
+ DistanceMatrix& d, WeightMap w,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef typename property_traits<WeightMap>::value_type WM;
+
+ return floyd_warshall_initialized_all_pairs_shortest_paths(g, d,
+ choose_param(get_param(params, distance_compare_t()),
+ std::less<WM>()),
+ choose_param(get_param(params, distance_combine_t()),
+ closed_plus<WM>()),
+ choose_param(get_param(params, distance_inf_t()),
+ std::numeric_limits<WM>::max BOOST_PREVENT_MACRO_SUBSTITUTION()),
+ choose_param(get_param(params, distance_zero_t()),
+ WM()));
+ }
+
+
+
+ template <class VertexAndEdgeListGraph, class DistanceMatrix,
+ class WeightMap, class P, class T, class R>
+ bool floyd_warshall_noninit_dispatch(const VertexAndEdgeListGraph& g,
+ DistanceMatrix& d, WeightMap w,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef typename property_traits<WeightMap>::value_type WM;
+
+ return floyd_warshall_all_pairs_shortest_paths(g, d, w,
+ choose_param(get_param(params, distance_compare_t()),
+ std::less<WM>()),
+ choose_param(get_param(params, distance_combine_t()),
+ closed_plus<WM>()),
+ choose_param(get_param(params, distance_inf_t()),
+ std::numeric_limits<WM>::max BOOST_PREVENT_MACRO_SUBSTITUTION()),
+ choose_param(get_param(params, distance_zero_t()),
+ WM()));
+ }
+
+
+ } // namespace detail
+
+
+
+ template <class VertexListGraph, class DistanceMatrix, class P,
+ class T, class R>
+ bool floyd_warshall_initialized_all_pairs_shortest_paths(
+ const VertexListGraph& g, DistanceMatrix& d,
+ const bgl_named_params<P, T, R>& params)
+ {
+ return detail::floyd_warshall_init_dispatch(g, d,
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ params);
+ }
+
+ template <class VertexListGraph, class DistanceMatrix>
+ bool floyd_warshall_initialized_all_pairs_shortest_paths(
+ const VertexListGraph& g, DistanceMatrix& d)
+ {
+ bgl_named_params<int,int> params(0);
+ return detail::floyd_warshall_init_dispatch(g, d,
+ get(edge_weight, g), params);
+ }
+
+
+
+
+ template <class VertexAndEdgeListGraph, class DistanceMatrix,
+ class P, class T, class R>
+ bool floyd_warshall_all_pairs_shortest_paths(
+ const VertexAndEdgeListGraph& g, DistanceMatrix& d,
+ const bgl_named_params<P, T, R>& params)
+ {
+ return detail::floyd_warshall_noninit_dispatch(g, d,
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ params);
+ }
+
+ template <class VertexAndEdgeListGraph, class DistanceMatrix>
+ bool floyd_warshall_all_pairs_shortest_paths(
+ const VertexAndEdgeListGraph& g, DistanceMatrix& d)
+ {
+ bgl_named_params<int,int> params(0);
+ return detail::floyd_warshall_noninit_dispatch(g, d,
+ get(edge_weight, g), params);
+ }
+
+
+} // namespace boost
+
+#endif
+
Added: branches/CMake/release/libs/graph/include/boost/graph/fruchterman_reingold.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/fruchterman_reingold.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,420 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// 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)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT_HPP
+#define BOOST_GRAPH_FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT_HPP
+
+#include <cmath>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/graph/simple_point.hpp>
+#include <vector>
+#include <list>
+#include <algorithm> // for std::min and std::max
+
+namespace boost {
+
+struct square_distance_attractive_force {
+ template<typename Graph, typename T>
+ T
+ operator()(typename graph_traits<Graph>::edge_descriptor,
+ T k,
+ T d,
+ const Graph&) const
+ {
+ return d * d / k;
+ }
+};
+
+struct square_distance_repulsive_force {
+ template<typename Graph, typename T>
+ T
+ operator()(typename graph_traits<Graph>::vertex_descriptor,
+ typename graph_traits<Graph>::vertex_descriptor,
+ T k,
+ T d,
+ const Graph&) const
+ {
+ return k * k / d;
+ }
+};
+
+template<typename T>
+struct linear_cooling {
+ typedef T result_type;
+
+ linear_cooling(std::size_t iterations)
+ : temp(T(iterations) / T(10)), step(0.1) { }
+
+ linear_cooling(std::size_t iterations, T temp)
+ : temp(temp), step(temp / T(iterations)) { }
+
+ T operator()()
+ {
+ T old_temp = temp;
+ temp -= step;
+ if (temp < T(0)) temp = T(0);
+ return old_temp;
+ }
+
+ private:
+ T temp;
+ T step;
+};
+
+struct all_force_pairs
+{
+ template<typename Graph, typename ApplyForce >
+ void operator()(const Graph& g, ApplyForce apply_force)
+ {
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
+ vertex_iterator v, end;
+ for (tie(v, end) = vertices(g); v != end; ++v) {
+ vertex_iterator u = v;
+ for (++u; u != end; ++u) {
+ apply_force(*u, *v);
+ apply_force(*v, *u);
+ }
+ }
+ }
+};
+
+template<typename Dim, typename PositionMap>
+struct grid_force_pairs
+{
+ template<typename Graph>
+ explicit
+ grid_force_pairs(Dim width, Dim height, PositionMap position, const Graph& g)
+ : width(width), height(height), position(position)
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif // BOOST_NO_STDC_NAMESPACE
+ two_k = Dim(2) * sqrt(width*height / num_vertices(g));
+ }
+
+ template<typename Graph, typename ApplyForce >
+ void operator()(const Graph& g, ApplyForce apply_force)
+ {
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+ typedef std::list<vertex_descriptor> bucket_t;
+ typedef std::vector<bucket_t> buckets_t;
+
+ std::size_t columns = std::size_t(width / two_k + Dim(1));
+ std::size_t rows = std::size_t(height / two_k + Dim(1));
+ buckets_t buckets(rows * columns);
+ vertex_iterator v, v_end;
+ for (tie(v, v_end) = vertices(g); v != v_end; ++v) {
+ std::size_t column = std::size_t((position[*v].x + width / 2) / two_k);
+ std::size_t row = std::size_t((position[*v].y + height / 2) / two_k);
+
+ if (column >= columns) column = columns - 1;
+ if (row >= rows) row = rows - 1;
+ buckets[row * columns + column].push_back(*v);
+ }
+
+ for (std::size_t row = 0; row < rows; ++row)
+ for (std::size_t column = 0; column < columns; ++column) {
+ bucket_t& bucket = buckets[row * columns + column];
+ typedef typename bucket_t::iterator bucket_iterator;
+ for (bucket_iterator u = bucket.begin(); u != bucket.end(); ++u) {
+ // Repulse vertices in this bucket
+ bucket_iterator v = u;
+ for (++v; v != bucket.end(); ++v) {
+ apply_force(*u, *v);
+ apply_force(*v, *u);
+ }
+
+ std::size_t adj_start_row = row == 0? 0 : row - 1;
+ std::size_t adj_end_row = row == rows - 1? row : row + 1;
+ std::size_t adj_start_column = column == 0? 0 : column - 1;
+ std::size_t adj_end_column = column == columns - 1? column : column + 1;
+ for (std::size_t other_row = adj_start_row; other_row <= adj_end_row;
+ ++other_row)
+ for (std::size_t other_column = adj_start_column;
+ other_column <= adj_end_column; ++other_column)
+ if (other_row != row || other_column != column) {
+ // Repulse vertices in this bucket
+ bucket_t& other_bucket
+ = buckets[other_row * columns + other_column];
+ for (v = other_bucket.begin(); v != other_bucket.end(); ++v)
+ apply_force(*u, *v);
+ }
+ }
+ }
+ }
+
+ private:
+ Dim width;
+ Dim height;
+ PositionMap position;
+ Dim two_k;
+};
+
+template<typename Dim, typename PositionMap, typename Graph>
+inline grid_force_pairs<Dim, PositionMap>
+make_grid_force_pairs(Dim width, Dim height, const PositionMap& position,
+ const Graph& g)
+{ return grid_force_pairs<Dim, PositionMap>(width, height, position, g); }
+
+template<typename Graph, typename PositionMap, typename Dim>
+void
+scale_graph(const Graph& g, PositionMap position,
+ Dim left, Dim top, Dim right, Dim bottom)
+{
+ if (num_vertices(g) == 0) return;
+
+ if (bottom > top) {
+ using std::swap;
+ swap(bottom, top);
+ }
+
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
+
+ // Find min/max ranges
+ Dim minX = position[*vertices(g).first].x, maxX = minX;
+ Dim minY = position[*vertices(g).first].y, maxY = minY;
+ vertex_iterator vi, vi_end;
+ for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ minX = min BOOST_PREVENT_MACRO_SUBSTITUTION (minX, position[*vi].x);
+ maxX = max BOOST_PREVENT_MACRO_SUBSTITUTION (maxX, position[*vi].x);
+ minY = min BOOST_PREVENT_MACRO_SUBSTITUTION (minY, position[*vi].y);
+ maxY = max BOOST_PREVENT_MACRO_SUBSTITUTION (maxY, position[*vi].y);
+ }
+
+ // Scale to bounding box provided
+ for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
+ position[*vi].x = ((position[*vi].x - minX) / (maxX - minX))
+ * (right - left) + left;
+ position[*vi].y = ((position[*vi].y - minY) / (maxY - minY))
+ * (top - bottom) + bottom;
+ }
+}
+
+namespace detail {
+ template<typename PositionMap, typename DisplacementMap,
+ typename RepulsiveForce, typename Dim, typename Graph>
+ struct fr_apply_force
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+
+ fr_apply_force(const PositionMap& position,
+ const DisplacementMap& displacement,
+ RepulsiveForce repulsive_force, Dim k, const Graph& g)
+ : position(position), displacement(displacement),
+ repulsive_force(repulsive_force), k(k), g(g)
+ { }
+
+ void operator()(vertex_descriptor u, vertex_descriptor v)
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif // BOOST_NO_STDC_NAMESPACE
+ if (u != v) {
+ Dim delta_x = position[v].x - position[u].x;
+ Dim delta_y = position[v].y - position[u].y;
+ Dim dist = sqrt(delta_x * delta_x + delta_y * delta_y);
+ Dim fr = repulsive_force(u, v, k, dist, g);
+ displacement[v].x += delta_x / dist * fr;
+ displacement[v].y += delta_y / dist * fr;
+ }
+ }
+
+ private:
+ PositionMap position;
+ DisplacementMap displacement;
+ RepulsiveForce repulsive_force;
+ Dim k;
+ const Graph& g;
+ };
+
+} // end namespace detail
+
+template<typename Graph, typename PositionMap, typename Dim,
+ typename AttractiveForce, typename RepulsiveForce,
+ typename ForcePairs, typename Cooling, typename DisplacementMap>
+void
+fruchterman_reingold_force_directed_layout
+ (const Graph& g,
+ PositionMap position,
+ Dim width,
+ Dim height,
+ AttractiveForce attractive_force,
+ RepulsiveForce repulsive_force,
+ ForcePairs force_pairs,
+ Cooling cool,
+ DisplacementMap displacement)
+{
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+ typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
+
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif // BOOST_NO_STDC_NAMESPACE
+
+ Dim area = width * height;
+ // assume positions are initialized randomly
+ Dim k = sqrt(area / num_vertices(g));
+
+ detail::fr_apply_force<PositionMap, DisplacementMap,
+ RepulsiveForce, Dim, Graph>
+ apply_force(position, displacement, repulsive_force, k, g);
+
+ Dim temp = cool();
+ if (temp) do {
+ // Calculate repulsive forces
+ vertex_iterator v, v_end;
+ for (tie(v, v_end) = vertices(g); v != v_end; ++v) {
+ displacement[*v].x = 0;
+ displacement[*v].y = 0;
+ }
+ force_pairs(g, apply_force);
+
+ // Calculate attractive forces
+ edge_iterator e, e_end;
+ for (tie(e, e_end) = edges(g); e != e_end; ++e) {
+ vertex_descriptor v = source(*e, g);
+ vertex_descriptor u = target(*e, g);
+ Dim delta_x = position[v].x - position[u].x;
+ Dim delta_y = position[v].y - position[u].y;
+ Dim dist = sqrt(delta_x * delta_x + delta_y * delta_y);
+ Dim fa = attractive_force(*e, k, dist, g);
+
+ displacement[v].x -= delta_x / dist * fa;
+ displacement[v].y -= delta_y / dist * fa;
+ displacement[u].x += delta_x / dist * fa;
+ displacement[u].y += delta_y / dist * fa;
+ }
+
+ // Update positions
+ for (tie(v, v_end) = vertices(g); v != v_end; ++v) {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ Dim disp_size = sqrt(displacement[*v].x * displacement[*v].x
+ + displacement[*v].y * displacement[*v].y);
+ position[*v].x += displacement[*v].x / disp_size
+ * min BOOST_PREVENT_MACRO_SUBSTITUTION (disp_size, temp);
+ position[*v].y += displacement[*v].y / disp_size
+ * min BOOST_PREVENT_MACRO_SUBSTITUTION (disp_size, temp);
+ position[*v].x = min BOOST_PREVENT_MACRO_SUBSTITUTION
+ (width / 2,
+ max BOOST_PREVENT_MACRO_SUBSTITUTION(-width / 2,
+ position[*v].x));
+ position[*v].y = min BOOST_PREVENT_MACRO_SUBSTITUTION
+ (height / 2,
+ max BOOST_PREVENT_MACRO_SUBSTITUTION(-height / 2,
+ position[*v].y));
+ }
+ } while (temp = cool());
+}
+
+namespace detail {
+ template<typename DisplacementMap>
+ struct fr_force_directed_layout
+ {
+ template<typename Graph, typename PositionMap, typename Dim,
+ typename AttractiveForce, typename RepulsiveForce,
+ typename ForcePairs, typename Cooling,
+ typename Param, typename Tag, typename Rest>
+ static void
+ run(const Graph& g,
+ PositionMap position,
+ Dim width,
+ Dim height,
+ AttractiveForce attractive_force,
+ RepulsiveForce repulsive_force,
+ ForcePairs force_pairs,
+ Cooling cool,
+ DisplacementMap displacement,
+ const bgl_named_params<Param, Tag, Rest>&)
+ {
+ fruchterman_reingold_force_directed_layout
+ (g, position, width, height, attractive_force, repulsive_force,
+ force_pairs, cool, displacement);
+ }
+ };
+
+ template<>
+ struct fr_force_directed_layout<error_property_not_found>
+ {
+ template<typename Graph, typename PositionMap, typename Dim,
+ typename AttractiveForce, typename RepulsiveForce,
+ typename ForcePairs, typename Cooling,
+ typename Param, typename Tag, typename Rest>
+ static void
+ run(const Graph& g,
+ PositionMap position,
+ Dim width,
+ Dim height,
+ AttractiveForce attractive_force,
+ RepulsiveForce repulsive_force,
+ ForcePairs force_pairs,
+ Cooling cool,
+ error_property_not_found,
+ const bgl_named_params<Param, Tag, Rest>& params)
+ {
+ std::vector<simple_point<Dim> > displacements(num_vertices(g));
+ fruchterman_reingold_force_directed_layout
+ (g, position, width, height, attractive_force, repulsive_force,
+ force_pairs, cool,
+ make_iterator_property_map
+ (displacements.begin(),
+ choose_const_pmap(get_param(params, vertex_index), g,
+ vertex_index),
+ simple_point<Dim>()));
+ }
+ };
+
+} // end namespace detail
+
+template<typename Graph, typename PositionMap, typename Dim, typename Param,
+ typename Tag, typename Rest>
+void
+fruchterman_reingold_force_directed_layout
+ (const Graph& g,
+ PositionMap position,
+ Dim width,
+ Dim height,
+ const bgl_named_params<Param, Tag, Rest>& params)
+{
+ typedef typename property_value<bgl_named_params<Param,Tag,Rest>,
+ vertex_displacement_t>::type D;
+
+ detail::fr_force_directed_layout<D>::run
+ (g, position, width, height,
+ choose_param(get_param(params, attractive_force_t()),
+ square_distance_attractive_force()),
+ choose_param(get_param(params, repulsive_force_t()),
+ square_distance_repulsive_force()),
+ choose_param(get_param(params, force_pairs_t()),
+ make_grid_force_pairs(width, height, position, g)),
+ choose_param(get_param(params, cooling_t()),
+ linear_cooling<Dim>(100)),
+ get_param(params, vertex_displacement_t()),
+ params);
+}
+
+template<typename Graph, typename PositionMap, typename Dim>
+void
+fruchterman_reingold_force_directed_layout(const Graph& g,
+ PositionMap position,
+ Dim width,
+ Dim height)
+{
+ fruchterman_reingold_force_directed_layout
+ (g, position, width, height,
+ attractive_force(square_distance_attractive_force()));
+}
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/graph_archetypes.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/graph_archetypes.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,290 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_ARCHETYPES_HPP
+#define BOOST_GRAPH_ARCHETYPES_HPP
+
+#include <boost/property_map.hpp>
+#include <boost/concept_archetype.hpp>
+
+namespace boost { // should use a different namespace for this
+
+ namespace detail {
+ struct null_graph_archetype : public null_archetype<> {
+ struct traversal_category { };
+ };
+ }
+
+ //===========================================================================
+ template <typename Vertex, typename Directed, typename ParallelCategory,
+ typename Base = detail::null_graph_archetype >
+ struct incidence_graph_archetype : public Base
+ {
+ typedef typename Base::traversal_category base_trav_cat;
+ struct traversal_category
+ : public incidence_graph_tag, public base_trav_cat { };
+#if 0
+ typedef immutable_graph_tag mutability_category;
+#endif
+ typedef Vertex vertex_descriptor;
+ typedef unsigned int degree_size_type;
+ typedef unsigned int vertices_size_type;
+ typedef unsigned int edges_size_type;
+ struct edge_descriptor {
+ edge_descriptor() { }
+ edge_descriptor(const detail::dummy_constructor&) { }
+ bool operator==(const edge_descriptor&) const { return false; }
+ bool operator!=(const edge_descriptor&) const { return false; }
+ };
+ typedef input_iterator_archetype<edge_descriptor> out_edge_iterator;
+
+ typedef Directed directed_category;
+ typedef ParallelCategory edge_parallel_category;
+
+ typedef void adjacency_iterator;
+ typedef void in_edge_iterator;
+ typedef void vertex_iterator;
+ typedef void edge_iterator;
+ };
+ template <typename V, typename D, typename P, typename B>
+ V source(const typename incidence_graph_archetype<V,D,P,B>::edge_descriptor&,
+ const incidence_graph_archetype<V,D,P,B>& )
+ {
+ return V(static_object<detail::dummy_constructor>::get());
+ }
+ template <typename V, typename D, typename P, typename B>
+ V target(const typename incidence_graph_archetype<V,D,P,B>::edge_descriptor&,
+ const incidence_graph_archetype<V,D,P,B>& )
+ {
+ return V(static_object<detail::dummy_constructor>::get());
+ }
+
+ template <typename V, typename D, typename P, typename B>
+ std::pair<typename incidence_graph_archetype<V,D,P,B>::out_edge_iterator,
+ typename incidence_graph_archetype<V,D,P,B>::out_edge_iterator>
+ out_edges(const V&, const incidence_graph_archetype<V,D,P,B>& )
+ {
+ typedef typename incidence_graph_archetype<V,D,P,B>::out_edge_iterator Iter;
+ return std::make_pair(Iter(), Iter());
+ }
+
+ template <typename V, typename D, typename P, typename B>
+ typename incidence_graph_archetype<V,D,P,B>::degree_size_type
+ out_degree(const V&, const incidence_graph_archetype<V,D,P,B>& )
+ {
+ return 0;
+ }
+
+ //===========================================================================
+ template <typename Vertex, typename Directed, typename ParallelCategory,
+ typename Base = detail::null_graph_archetype >
+ struct adjacency_graph_archetype : public Base
+ {
+ typedef typename Base::traversal_category base_trav_cat;
+ struct traversal_category
+ : public adjacency_graph_tag, public base_trav_cat { };
+ typedef Vertex vertex_descriptor;
+ typedef unsigned int degree_size_type;
+ typedef unsigned int vertices_size_type;
+ typedef unsigned int edges_size_type;
+ typedef void edge_descriptor;
+ typedef input_iterator_archetype<Vertex> adjacency_iterator;
+
+ typedef Directed directed_category;
+ typedef ParallelCategory edge_parallel_category;
+
+ typedef void in_edge_iterator;
+ typedef void out_edge_iterator;
+ typedef void vertex_iterator;
+ typedef void edge_iterator;
+ };
+
+ template <typename V, typename D, typename P, typename B>
+ std::pair<typename adjacency_graph_archetype<V,D,P,B>::adjacency_iterator,
+ typename adjacency_graph_archetype<V,D,P,B>::adjacency_iterator>
+ adjacent_vertices(const V&, const adjacency_graph_archetype<V,D,P,B>& )
+ {
+ typedef typename adjacency_graph_archetype<V,D,P,B>::adjacency_iterator Iter;
+ return std::make_pair(Iter(), Iter());
+ }
+
+ template <typename V, typename D, typename P, typename B>
+ typename adjacency_graph_archetype<V,D,P,B>::degree_size_type
+ out_degree(const V&, const adjacency_graph_archetype<V,D,P,B>& )
+ {
+ return 0;
+ }
+
+ //===========================================================================
+ template <typename Vertex, typename Directed, typename ParallelCategory,
+ typename Base = detail::null_graph_archetype >
+ struct vertex_list_graph_archetype : public Base
+ {
+ typedef incidence_graph_archetype<Vertex, Directed, ParallelCategory>
+ Incidence;
+ typedef adjacency_graph_archetype<Vertex, Directed, ParallelCategory>
+ Adjacency;
+
+ typedef typename Base::traversal_category base_trav_cat;
+ struct traversal_category
+ : public vertex_list_graph_tag, public base_trav_cat { };
+#if 0
+ typedef immutable_graph_tag mutability_category;
+#endif
+ typedef Vertex vertex_descriptor;
+ typedef unsigned int degree_size_type;
+ typedef typename Incidence::edge_descriptor edge_descriptor;
+ typedef typename Incidence::out_edge_iterator out_edge_iterator;
+ typedef typename Adjacency::adjacency_iterator adjacency_iterator;
+
+ typedef input_iterator_archetype<Vertex> vertex_iterator;
+ typedef unsigned int vertices_size_type;
+ typedef unsigned int edges_size_type;
+
+ typedef Directed directed_category;
+ typedef ParallelCategory edge_parallel_category;
+
+ typedef void in_edge_iterator;
+ typedef void edge_iterator;
+ };
+
+ template <typename V, typename D, typename P, typename B>
+ std::pair<typename vertex_list_graph_archetype<V,D,P,B>::vertex_iterator,
+ typename vertex_list_graph_archetype<V,D,P,B>::vertex_iterator>
+ vertices(const vertex_list_graph_archetype<V,D,P,B>& )
+ {
+ typedef typename vertex_list_graph_archetype<V,D,P,B>::vertex_iterator Iter;
+ return std::make_pair(Iter(), Iter());
+ }
+
+ template <typename V, typename D, typename P, typename B>
+ typename vertex_list_graph_archetype<V,D,P,B>::vertices_size_type
+ num_vertices(const vertex_list_graph_archetype<V,D,P,B>& )
+ {
+ return 0;
+ }
+
+ // ambiguously inherited from incidence graph and adjacency graph
+ template <typename V, typename D, typename P, typename B>
+ typename vertex_list_graph_archetype<V,D,P,B>::degree_size_type
+ out_degree(const V&, const vertex_list_graph_archetype<V,D,P,B>& )
+ {
+ return 0;
+ }
+
+ //===========================================================================
+
+ struct property_graph_archetype_tag { };
+
+ template <typename GraphArchetype, typename Property, typename ValueArch>
+ struct property_graph_archetype : public GraphArchetype
+ {
+ typedef property_graph_archetype_tag graph_tag;
+ typedef ValueArch vertex_property_type;
+ typedef ValueArch edge_property_type;
+ };
+
+ struct choose_edge_property_map_archetype {
+ template <typename Graph, typename Property, typename Tag>
+ struct bind_ {
+ typedef mutable_lvalue_property_map_archetype
+ <typename Graph::edge_descriptor, Property> type;
+ typedef lvalue_property_map_archetype
+ <typename Graph::edge_descriptor, Property> const_type;
+ };
+ };
+ template <>
+ struct edge_property_selector<property_graph_archetype_tag> {
+ typedef choose_edge_property_map_archetype type;
+ };
+
+ struct choose_vertex_property_map_archetype {
+ template <typename Graph, typename Property, typename Tag>
+ struct bind_ {
+ typedef mutable_lvalue_property_map_archetype
+ <typename Graph::vertex_descriptor, Property> type;
+ typedef lvalue_property_map_archetype
+ <typename Graph::vertex_descriptor, Property> const_type;
+ };
+ };
+
+ template <>
+ struct vertex_property_selector<property_graph_archetype_tag> {
+ typedef choose_vertex_property_map_archetype type;
+ };
+
+ template <typename G, typename P, typename V>
+ typename property_map<property_graph_archetype<G, P, V>, P>::type
+ get(P, property_graph_archetype<G, P, V>&) {
+ typename property_map<property_graph_archetype<G, P, V>, P>::type pmap;
+ return pmap;
+ }
+
+ template <typename G, typename P, typename V>
+ typename property_map<property_graph_archetype<G, P, V>, P>::const_type
+ get(P, const property_graph_archetype<G, P, V>&) {
+ typename property_map<property_graph_archetype<G, P, V>, P>::const_type pmap;
+ return pmap;
+ }
+
+ template <typename G, typename P, typename K, typename V>
+ typename property_traits<typename property_map<property_graph_archetype<G, P, V>, P>::const_type>::value_type
+ get(P p, const property_graph_archetype<G, P, V>& g, K k) {
+ return get( get(p, g), k);
+ }
+
+ template <typename G, typename P, typename V, typename Key>
+ void
+ put(P p, property_graph_archetype<G, P, V>& g,
+ const Key& key, const V& value)
+ {
+ typedef typename boost::property_map<property_graph_archetype<G, P, V>, P>::type Map;
+ Map pmap = get(p, g);
+ put(pmap, key, value);
+ }
+
+ struct color_value_archetype {
+ color_value_archetype() { }
+ color_value_archetype(detail::dummy_constructor) { }
+ bool operator==(const color_value_archetype& ) const { return true; }
+ bool operator!=(const color_value_archetype& ) const { return true; }
+ };
+ template <>
+ struct color_traits<color_value_archetype> {
+ static color_value_archetype white()
+ {
+ return color_value_archetype
+ (static_object<detail::dummy_constructor>::get());
+ }
+ static color_value_archetype gray()
+ {
+ return color_value_archetype
+ (static_object<detail::dummy_constructor>::get());
+ }
+ static color_value_archetype black()
+ {
+ return color_value_archetype
+ (static_object<detail::dummy_constructor>::get());
+ }
+ };
+
+ template <typename T>
+ class buffer_archetype {
+ public:
+ void push(const T&) {}
+ void pop() {}
+ T& top() { return static_object<T>::get(); }
+ const T& top() const { return static_object<T>::get(); }
+ bool empty() const { return true; }
+ };
+
+} // namespace boost
+
+
+#endif // BOOST_GRAPH_ARCHETYPES_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/graph_as_tree.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/graph_as_tree.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,154 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_GRAPH_AS_TREE_HPP
+#define BOOST_GRAPH_GRAPH_AS_TREE_HPP
+
+#include <vector>
+#include <boost/config.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/tree_traits.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/visitors.hpp>
+
+namespace boost {
+
+ template <class Graph, class Node, class ChIt, class Derived>
+ class graph_as_tree_base
+ {
+ typedef Derived Tree;
+ public:
+ typedef Node node_descriptor;
+ typedef ChIt children_iterator;
+
+ graph_as_tree_base(Graph& g, Node root) : _g(g), _root(root) { }
+
+ friend Node root(const Tree& t) { return t._root; }
+
+ template <class N>
+ friend std::pair<ChIt,ChIt>
+ children(N n, const Tree& t) { return adjacent_vertices(n, t._g); }
+
+ template<class N>
+ friend Node parent(N n, const Tree& t) {
+ return boost::get(t.parent_pa(), n);
+ }
+
+ Graph& _g;
+ Node _root;
+ };
+
+ struct graph_as_tree_tag { };
+
+ template <class Graph, class ParentMap
+ , class Node
+#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ = typename graph_traits<Graph>::vertex_descriptor
+#endif
+ , class ChIt
+#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ = typename graph_traits<Graph>::adjacency_iterator
+#endif
+ >
+ class graph_as_tree
+ : public graph_as_tree_base<Graph, Node, ChIt,
+ graph_as_tree<Graph,ParentMap,Node,ChIt> >
+ {
+ typedef graph_as_tree self;
+ typedef graph_as_tree_base<Graph, Node, ChIt, self> super;
+ public:
+ graph_as_tree(Graph& g, Node root) : super(g, root) { }
+
+ graph_as_tree(Graph& g, Node root, ParentMap p) : super(g, root), _p(p) {
+ breadth_first_search(g, root,
+ visitor(make_bfs_visitor
+ (record_predecessors(p, boost::on_tree_edge()))));
+ }
+ ParentMap parent_pa() const { return _p; }
+ typedef graph_as_tree_tag graph_tag; // for property_map
+ protected:
+ ParentMap _p;
+ };
+
+
+ namespace detail {
+
+ struct graph_as_tree_vertex_property_selector {
+ template <typename GraphAsTree, typename Property, typename Tag>
+ struct bind_ {
+ typedef typename GraphAsTree::base_type Graph;
+ typedef property_map<Graph, Tag> PMap;
+ typedef typename PMap::type type;
+ typedef typename PMap::const_type const_type;
+ };
+ };
+
+ struct graph_as_tree_edge_property_selector {
+ template <typename GraphAsTree, typename Property, typename Tag>
+ struct bind_ {
+ typedef typename GraphAsTree::base_type Graph;
+ typedef property_map<Graph, Tag> PMap;
+ typedef typename PMap::type type;
+ typedef typename PMap::const_type const_type;
+ };
+ };
+
+ } // namespace detail
+
+ template <>
+ struct vertex_property_selector<graph_as_tree_tag> {
+ typedef detail::graph_as_tree_vertex_property_selector type;
+ };
+
+ template <>
+ struct edge_property_selector<graph_as_tree_tag> {
+ typedef detail::graph_as_tree_edge_property_selector type;
+ };
+
+ template <typename Graph, typename P, typename N, typename C,
+ typename Property>
+ typename property_map<Graph, Property>::type
+ get(Property p, graph_as_tree<Graph,P,N,C>& g)
+ {
+ return get(p, g._g);
+ }
+
+ template <typename Graph, typename P, typename N, typename C,
+ typename Property>
+ typename property_map<Graph, Property>::const_type
+ get(Property p, const graph_as_tree<Graph,P,N,C>& g)
+ {
+ const Graph& gref = g._g; // in case GRef is non-const
+ return get(p, gref);
+ }
+
+ template <typename Graph, typename P, typename N, typename C,
+ typename Property, typename Key>
+ typename property_traits<
+ typename property_map<Graph, Property>::const_type
+ >::value_type
+ get(Property p, const graph_as_tree<Graph,P,N,C>& g, const Key& k)
+ {
+ return get(p, g._g, k);
+ }
+
+ template <typename Graph, typename P, typename N, typename C,
+ typename Property, typename Key, typename Value>
+ void
+ put(Property p, const graph_as_tree<Graph,P,N,C>& g, const Key& k,
+ const Value& val)
+ {
+ put(p, g._g, k, val);
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_GRAPH_AS_TREE_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/graph_concepts.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/graph_concepts.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,510 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_CONCEPTS_HPP
+#define BOOST_GRAPH_CONCEPTS_HPP
+
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/detail/workaround.hpp>
+
+#include <boost/concept/detail/concept_def.hpp>
+
+namespace boost
+{
+// dwa 2003/7/11 -- This clearly shouldn't be necessary, but if
+// you want to use vector_as_graph, it is! I'm sure the graph
+// library leaves these out all over the place. Probably a
+// redesign involving specializing a template with a static
+// member function is in order :(
+//
+// It is needed in order to allow us to write using boost::vertices as
+// needed for ADL when using vector_as_graph below.
+#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) \
+ && !BOOST_WORKAROUND(__GNUC__, <= 2) \
+ && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+# define BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK
+#endif
+
+#ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK
+template <class T>
+typename T::ThereReallyIsNoMemberByThisNameInT vertices(T const&);
+#endif
+
+ namespace concepts {
+ BOOST_concept(MultiPassInputIterator,(T)) {
+ BOOST_CONCEPT_USAGE(MultiPassInputIterator) {
+ BOOST_CONCEPT_ASSERT((InputIterator<T>));
+ }
+ };
+
+ BOOST_concept(Graph,(G))
+ {
+ typedef typename graph_traits<G>::vertex_descriptor vertex_descriptor;
+ typedef typename graph_traits<G>::directed_category directed_category;
+ typedef typename graph_traits<G>::edge_parallel_category
+ edge_parallel_category;
+
+ typedef typename graph_traits<G>::traversal_category
+ traversal_category;
+
+ BOOST_CONCEPT_USAGE(Graph)
+ {
+ BOOST_CONCEPT_ASSERT((DefaultConstructible<vertex_descriptor>));
+ BOOST_CONCEPT_ASSERT((EqualityComparable<vertex_descriptor>));
+ BOOST_CONCEPT_ASSERT((Assignable<vertex_descriptor>));
+ }
+ G g;
+ };
+
+ BOOST_concept(IncidenceGraph,(G))
+ : Graph<G>
+ {
+ typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
+ typedef typename graph_traits<G>::out_edge_iterator
+ out_edge_iterator;
+
+ typedef typename graph_traits<G>::traversal_category
+ traversal_category;
+
+ BOOST_CONCEPT_USAGE(IncidenceGraph) {
+ BOOST_CONCEPT_ASSERT((MultiPassInputIterator<out_edge_iterator>));
+ BOOST_CONCEPT_ASSERT((DefaultConstructible<edge_descriptor>));
+ BOOST_CONCEPT_ASSERT((EqualityComparable<edge_descriptor>));
+ BOOST_CONCEPT_ASSERT((Assignable<edge_descriptor>));
+ BOOST_CONCEPT_ASSERT((Convertible<traversal_category,
+ incidence_graph_tag>));
+
+ p = out_edges(u, g);
+ n = out_degree(u, g);
+ e = *p.first;
+ u = source(e, g);
+ v = target(e, g);
+ const_constraints(g);
+ }
+ void const_constraints(const G& cg) {
+ p = out_edges(u, cg);
+ n = out_degree(u, cg);
+ e = *p.first;
+ u = source(e, cg);
+ v = target(e, cg);
+ }
+ std::pair<out_edge_iterator, out_edge_iterator> p;
+ typename graph_traits<G>::vertex_descriptor u, v;
+ typename graph_traits<G>::edge_descriptor e;
+ typename graph_traits<G>::degree_size_type n;
+ G g;
+ };
+
+ BOOST_concept(BidirectionalGraph,(G))
+ : IncidenceGraph<G>
+ {
+ typedef typename graph_traits<G>::in_edge_iterator
+ in_edge_iterator;
+ typedef typename graph_traits<G>::traversal_category
+ traversal_category;
+
+ BOOST_CONCEPT_USAGE(BidirectionalGraph) {
+ BOOST_CONCEPT_ASSERT((MultiPassInputIterator<in_edge_iterator>));
+ BOOST_CONCEPT_ASSERT((Convertible<traversal_category,
+ bidirectional_graph_tag>));
+
+ p = in_edges(v, g);
+ n = in_degree(v, g);
+ e = *p.first;
+ const_constraints(g);
+ }
+ void const_constraints(const G& cg) {
+ p = in_edges(v, cg);
+ n = in_degree(v, cg);
+ e = *p.first;
+ }
+ std::pair<in_edge_iterator, in_edge_iterator> p;
+ typename graph_traits<G>::vertex_descriptor v;
+ typename graph_traits<G>::edge_descriptor e;
+ typename graph_traits<G>::degree_size_type n;
+ G g;
+ };
+
+ BOOST_concept(AdjacencyGraph,(G))
+ : Graph<G>
+ {
+ typedef typename graph_traits<G>::adjacency_iterator
+ adjacency_iterator;
+ typedef typename graph_traits<G>::traversal_category
+ traversal_category;
+
+ BOOST_CONCEPT_USAGE(AdjacencyGraph) {
+ BOOST_CONCEPT_ASSERT((MultiPassInputIterator<adjacency_iterator>));
+ BOOST_CONCEPT_ASSERT((Convertible<traversal_category,
+ adjacency_graph_tag>));
+
+ p = adjacent_vertices(v, g);
+ v = *p.first;
+ const_constraints(g);
+ }
+ void const_constraints(const G& cg) {
+ p = adjacent_vertices(v, cg);
+ }
+ std::pair<adjacency_iterator,adjacency_iterator> p;
+ typename graph_traits<G>::vertex_descriptor v;
+ G g;
+ };
+
+ BOOST_concept(VertexListGraph,(G))
+ : Graph<G>
+ {
+ typedef typename graph_traits<G>::vertex_iterator vertex_iterator;
+ typedef typename graph_traits<G>::vertices_size_type vertices_size_type;
+ typedef typename graph_traits<G>::traversal_category
+ traversal_category;
+
+ BOOST_CONCEPT_USAGE(VertexListGraph) {
+ BOOST_CONCEPT_ASSERT((MultiPassInputIterator<vertex_iterator>));
+ BOOST_CONCEPT_ASSERT((Convertible<traversal_category,
+ vertex_list_graph_tag>));
+
+#ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK
+ // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if
+ // you want to use vector_as_graph, it is! I'm sure the graph
+ // library leaves these out all over the place. Probably a
+ // redesign involving specializing a template with a static
+ // member function is in order :(
+ using boost::vertices;
+#endif
+ p = vertices(g);
+ v = *p.first;
+ const_constraints(g);
+ }
+ void const_constraints(const G& cg) {
+#ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK
+ // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if
+ // you want to use vector_as_graph, it is! I'm sure the graph
+ // library leaves these out all over the place. Probably a
+ // redesign involving specializing a template with a static
+ // member function is in order :(
+ using boost::vertices;
+#endif
+
+ p = vertices(cg);
+ v = *p.first;
+ V = num_vertices(cg);
+ }
+ std::pair<vertex_iterator,vertex_iterator> p;
+ typename graph_traits<G>::vertex_descriptor v;
+ G g;
+ vertices_size_type V;
+ };
+
+ BOOST_concept(EdgeListGraph,(G))
+ : Graph<G>
+ {
+ typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
+ typedef typename graph_traits<G>::edge_iterator edge_iterator;
+ typedef typename graph_traits<G>::edges_size_type edges_size_type;
+ typedef typename graph_traits<G>::traversal_category
+ traversal_category;
+
+ BOOST_CONCEPT_USAGE(EdgeListGraph) {
+ BOOST_CONCEPT_ASSERT((MultiPassInputIterator<edge_iterator>));
+ BOOST_CONCEPT_ASSERT((DefaultConstructible<edge_descriptor>));
+ BOOST_CONCEPT_ASSERT((EqualityComparable<edge_descriptor>));
+ BOOST_CONCEPT_ASSERT((Assignable<edge_descriptor>));
+ BOOST_CONCEPT_ASSERT((Convertible<traversal_category,
+ edge_list_graph_tag>));
+
+ p = edges(g);
+ e = *p.first;
+ u = source(e, g);
+ v = target(e, g);
+ const_constraints(g);
+ }
+ void const_constraints(const G& cg) {
+ p = edges(cg);
+ E = num_edges(cg);
+ e = *p.first;
+ u = source(e, cg);
+ v = target(e, cg);
+ }
+ std::pair<edge_iterator,edge_iterator> p;
+ typename graph_traits<G>::vertex_descriptor u, v;
+ typename graph_traits<G>::edge_descriptor e;
+ edges_size_type E;
+ G g;
+ };
+
+ BOOST_concept(VertexAndEdgeListGraph,(G))
+ : VertexListGraph<G>
+ , EdgeListGraph<G>
+ {
+ };
+
+ // Where to put the requirement for this constructor?
+ // G g(n_vertices);
+ // Not in mutable graph, then LEDA graph's can't be models of
+ // MutableGraph.
+
+ BOOST_concept(EdgeMutableGraph,(G))
+ {
+ typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
+
+ BOOST_CONCEPT_USAGE(EdgeMutableGraph) {
+ p = add_edge(u, v, g);
+ remove_edge(u, v, g);
+ remove_edge(e, g);
+ clear_vertex(v, g);
+ }
+ G g;
+ edge_descriptor e;
+ std::pair<edge_descriptor, bool> p;
+ typename graph_traits<G>::vertex_descriptor u, v;
+ };
+
+ BOOST_concept(VertexMutableGraph,(G))
+ {
+
+ BOOST_CONCEPT_USAGE(VertexMutableGraph) {
+ v = add_vertex(g);
+ remove_vertex(v, g);
+ }
+ G g;
+ typename graph_traits<G>::vertex_descriptor u, v;
+ };
+
+ BOOST_concept(MutableGraph,(G))
+ : EdgeMutableGraph<G>
+ , VertexMutableGraph<G>
+ {
+ };
+
+ template <class edge_descriptor>
+ struct dummy_edge_predicate {
+ bool operator()(const edge_descriptor&) const {
+ return false;
+ }
+ };
+
+ BOOST_concept(MutableIncidenceGraph,(G))
+ : MutableGraph<G>
+ {
+ BOOST_CONCEPT_USAGE(MutableIncidenceGraph) {
+ remove_edge(iter, g);
+ remove_out_edge_if(u, p, g);
+ }
+ G g;
+ typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
+ dummy_edge_predicate<edge_descriptor> p;
+ typename boost::graph_traits<G>::vertex_descriptor u;
+ typename boost::graph_traits<G>::out_edge_iterator iter;
+ };
+
+ BOOST_concept(MutableBidirectionalGraph,(G))
+ : MutableIncidenceGraph<G>
+ {
+ BOOST_CONCEPT_USAGE(MutableBidirectionalGraph)
+ {
+ remove_in_edge_if(u, p, g);
+ }
+ G g;
+ typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
+ dummy_edge_predicate<edge_descriptor> p;
+ typename boost::graph_traits<G>::vertex_descriptor u;
+ };
+
+ BOOST_concept(MutableEdgeListGraph,(G))
+ : EdgeMutableGraph<G>
+ {
+ BOOST_CONCEPT_USAGE(MutableEdgeListGraph) {
+ remove_edge_if(p, g);
+ }
+ G g;
+ typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
+ dummy_edge_predicate<edge_descriptor> p;
+ };
+
+ BOOST_concept(VertexMutablePropertyGraph,(G))
+ : VertexMutableGraph<G>
+ {
+ BOOST_CONCEPT_USAGE(VertexMutablePropertyGraph) {
+ v = add_vertex(vp, g);
+ }
+ G g;
+ typename graph_traits<G>::vertex_descriptor v;
+ typename vertex_property<G>::type vp;
+ };
+
+ BOOST_concept(EdgeMutablePropertyGraph,(G))
+ : EdgeMutableGraph<G>
+ {
+ typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
+
+ BOOST_CONCEPT_USAGE(EdgeMutablePropertyGraph) {
+ p = add_edge(u, v, ep, g);
+ }
+ G g;
+ std::pair<edge_descriptor, bool> p;
+ typename graph_traits<G>::vertex_descriptor u, v;
+ typename edge_property<G>::type ep;
+ };
+
+ BOOST_concept(AdjacencyMatrix,(G))
+ : Graph<G>
+ {
+ typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
+
+ BOOST_CONCEPT_USAGE(AdjacencyMatrix) {
+ p = edge(u, v, g);
+ const_constraints(g);
+ }
+ void const_constraints(const G& cg) {
+ p = edge(u, v, cg);
+ }
+ typename graph_traits<G>::vertex_descriptor u, v;
+ std::pair<edge_descriptor, bool> p;
+ G g;
+ };
+
+ BOOST_concept(ReadablePropertyGraph,(G)(X)(Property))
+ : Graph<G>
+ {
+ typedef typename property_map<G, Property>::const_type const_Map;
+
+ BOOST_CONCEPT_USAGE(ReadablePropertyGraph)
+ {
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept<const_Map, X>));
+
+ const_constraints(g);
+ }
+ void const_constraints(const G& cg) {
+ const_Map pmap = get(Property(), cg);
+ pval = get(Property(), cg, x);
+ ignore_unused_variable_warning(pmap);
+ }
+ G g;
+ X x;
+ typename property_traits<const_Map>::value_type pval;
+ };
+
+ BOOST_concept(PropertyGraph,(G)(X)(Property))
+ : ReadablePropertyGraph<G, X, Property>
+ {
+ typedef typename property_map<G, Property>::type Map;
+ BOOST_CONCEPT_USAGE(PropertyGraph) {
+ BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept<Map, X>));
+
+ Map pmap = get(Property(), g);
+ pval = get(Property(), g, x);
+ put(Property(), g, x, pval);
+ ignore_unused_variable_warning(pmap);
+ }
+ G g;
+ X x;
+ typename property_traits<Map>::value_type pval;
+ };
+
+ BOOST_concept(LvaluePropertyGraph,(G)(X)(Property))
+ : ReadablePropertyGraph<G, X, Property>
+ {
+ typedef typename property_map<G, Property>::type Map;
+ typedef typename property_map<G, Property>::const_type const_Map;
+
+ BOOST_CONCEPT_USAGE(LvaluePropertyGraph) {
+ BOOST_CONCEPT_ASSERT((LvaluePropertyMapConcept<const_Map, X>));
+
+ pval = get(Property(), g, x);
+ put(Property(), g, x, pval);
+ }
+ G g;
+ X x;
+ typename property_traits<Map>::value_type pval;
+ };
+
+ // This needs to move out of the graph library
+ BOOST_concept(Buffer,(B))
+ {
+ BOOST_CONCEPT_USAGE(Buffer) {
+ b.push(t);
+ b.pop();
+ typename B::value_type& v = b.top();
+ const_constraints(b);
+ ignore_unused_variable_warning(v);
+ }
+ void const_constraints(const B& cb) {
+ const typename B::value_type& v = cb.top();
+ n = cb.size();
+ bool e = cb.empty();
+ ignore_unused_variable_warning(v);
+ ignore_unused_variable_warning(e);
+ }
+ typename B::size_type n;
+ typename B::value_type t;
+ B b;
+ };
+
+ BOOST_concept(ColorValue,(C))
+ : EqualityComparable<C>
+ , DefaultConstructible<C>
+ {
+ BOOST_CONCEPT_USAGE(ColorValue) {
+ c = color_traits<C>::white();
+ c = color_traits<C>::gray();
+ c = color_traits<C>::black();
+ }
+ C c;
+ };
+
+ BOOST_concept(BasicMatrix,(M)(I)(V))
+ {
+ BOOST_CONCEPT_USAGE(BasicMatrix) {
+ V& elt = A[i][j];
+ const_constraints(A);
+ ignore_unused_variable_warning(elt);
+ }
+ void const_constraints(const M& cA) {
+ const V& elt = cA[i][j];
+ ignore_unused_variable_warning(elt);
+ }
+ M A;
+ I i, j;
+ };
+
+ } // end namespace concepts
+
+ using boost::concepts::MultiPassInputIteratorConcept;
+ using boost::concepts::GraphConcept;
+ using boost::concepts::IncidenceGraphConcept;
+ using boost::concepts::BidirectionalGraphConcept;
+ using boost::concepts::AdjacencyGraphConcept;
+ using boost::concepts::VertexListGraphConcept;
+ using boost::concepts::EdgeListGraphConcept;
+ using boost::concepts::VertexAndEdgeListGraphConcept;
+ using boost::concepts::EdgeMutableGraphConcept;
+ using boost::concepts::VertexMutableGraphConcept;
+ using boost::concepts::MutableGraphConcept;
+ using boost::concepts::MutableIncidenceGraphConcept;
+ using boost::concepts::MutableBidirectionalGraphConcept;
+ using boost::concepts::MutableEdgeListGraphConcept;
+ using boost::concepts::VertexMutablePropertyGraphConcept;
+ using boost::concepts::EdgeMutablePropertyGraphConcept;
+ using boost::concepts::AdjacencyMatrixConcept;
+ using boost::concepts::ReadablePropertyGraphConcept;
+ using boost::concepts::PropertyGraphConcept;
+ using boost::concepts::LvaluePropertyGraphConcept;
+ using boost::concepts::BufferConcept;
+ using boost::concepts::ColorValueConcept;
+ using boost::concepts::BasicMatrixConcept;
+} // namespace boost
+
+#include <boost/concept/detail/concept_undef.hpp>
+
+#endif /* BOOST_GRAPH_CONCEPTS_H */
Added: branches/CMake/release/libs/graph/include/boost/graph/graph_selectors.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/graph_selectors.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,38 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_SELECTORS_HPP
+#define BOOST_GRAPH_SELECTORS_HPP
+
+#include <boost/mpl/bool.hpp>
+
+namespace boost {
+
+ //===========================================================================
+ // Selectors for the Directed template parameter of adjacency_list
+ // and adjacency_matrix.
+
+ struct directedS { enum { is_directed = true, is_bidir = false };
+ typedef mpl::true_ is_directed_t;
+ typedef mpl::false_ is_bidir_t;
+ };
+ struct undirectedS {
+ enum { is_directed = false, is_bidir = false };
+ typedef mpl::false_ is_directed_t;
+ typedef mpl::false_ is_bidir_t;
+ };
+ struct bidirectionalS {
+ enum { is_directed = true, is_bidir = true };
+ typedef mpl::true_ is_directed_t;
+ typedef mpl::true_ is_bidir_t;
+ };
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_SELECTORS_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/graph_test.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/graph_test.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,382 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_TEST_HPP
+#define BOOST_GRAPH_TEST_HPP
+
+#include <vector>
+#include <boost/test/minimal.hpp>
+#include <boost/graph/filtered_graph.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/isomorphism.hpp>
+#include <boost/graph/copy.hpp>
+#include <boost/graph/graph_utility.hpp> // for connects
+
+
+// UNDER CONSTRUCTION
+
+namespace boost {
+
+ template <typename Graph>
+ struct graph_test
+ {
+
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
+ typedef typename graph_traits<Graph>::degree_size_type deg_size_t;
+ typedef typename graph_traits<Graph>::edges_size_type e_size_t;
+ typedef typename graph_traits<Graph>::out_edge_iterator out_edge_iter;
+ typedef typename property_map<Graph, vertex_index_t>::type index_map_t;
+ typedef iterator_property_map<typename std::vector<vertex_t>::iterator,
+ index_map_t,vertex_t,vertex_t&> IsoMap;
+
+ struct ignore_vertex {
+ ignore_vertex() { }
+ ignore_vertex(vertex_t v) : v(v) { }
+ bool operator()(vertex_t x) const { return x != v; }
+ vertex_t v;
+ };
+ struct ignore_edge {
+ ignore_edge() { }
+ ignore_edge(edge_t e) : e(e) { }
+ bool operator()(edge_t x) const { return x != e; }
+ edge_t e;
+ };
+ struct ignore_edges {
+ ignore_edges(vertex_t s, vertex_t t, const Graph& g)
+ : s(s), t(t), g(g) { }
+ bool operator()(edge_t x) const {
+ return !(source(x, g) == s && target(x, g) == t);
+ }
+ vertex_t s; vertex_t t; const Graph& g;
+ };
+
+ //=========================================================================
+ // Traversal Operations
+
+ void test_incidence_graph
+ (const std::vector<vertex_t>& vertex_set,
+ const std::vector< std::pair<vertex_t, vertex_t> >& edge_set,
+ const Graph& g)
+ {
+ typedef typename std::vector<vertex_t>::const_iterator vertex_iter;
+ typedef typename std::vector< std::pair<vertex_t, vertex_t> >
+ ::const_iterator edge_iter;
+ typedef typename graph_traits<Graph>::out_edge_iterator out_edge_iter;
+
+ for (vertex_iter ui = vertex_set.begin(); ui != vertex_set.end(); ++ui) {
+ vertex_t u = *ui;
+ std::vector<vertex_t> adj;
+ for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e)
+ if (e->first == u)
+ adj.push_back(e->second);
+
+ std::pair<out_edge_iter, out_edge_iter> p = out_edges(u, g);
+ BOOST_CHECK(out_degree(u, g) == adj.size());
+ BOOST_CHECK(deg_size_t(std::distance(p.first, p.second))
+ == out_degree(u, g));
+ for (; p.first != p.second; ++p.first) {
+ edge_t e = *p.first;
+ BOOST_CHECK(source(e, g) == u);
+ BOOST_CHECK(container_contains(adj, target(e, g)) == true);
+ }
+ }
+ }
+
+ void test_bidirectional_graph
+ (const std::vector<vertex_t>& vertex_set,
+ const std::vector< std::pair<vertex_t, vertex_t> >& edge_set,
+ const Graph& g)
+ {
+ typedef typename std::vector<vertex_t>::const_iterator vertex_iter;
+ typedef typename std::vector< std::pair<vertex_t, vertex_t> >
+ ::const_iterator edge_iter;
+ typedef typename graph_traits<Graph>::in_edge_iterator in_edge_iter;
+
+ for (vertex_iter vi = vertex_set.begin(); vi != vertex_set.end(); ++vi) {
+ vertex_t v = *vi;
+ std::vector<vertex_t> inv_adj;
+ for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e)
+ if (e->second == v)
+ inv_adj.push_back(e->first);
+
+ std::pair<in_edge_iter, in_edge_iter> p = in_edges(v, g);
+ BOOST_CHECK(in_degree(v, g) == inv_adj.size());
+ BOOST_CHECK(deg_size_t(std::distance(p.first, p.second))
+ == in_degree(v, g));
+ for (; p.first != p.second; ++p.first) {
+ edge_t e = *p.first;
+ BOOST_CHECK(target(e, g) == v);
+ BOOST_CHECK(container_contains(inv_adj, source(e, g)) == true);
+ }
+ }
+ }
+
+ void test_adjacency_graph
+ (const std::vector<vertex_t>& vertex_set,
+ const std::vector< std::pair<vertex_t,vertex_t> >& edge_set,
+ const Graph& g)
+ {
+ typedef typename std::vector<vertex_t>::const_iterator vertex_iter;
+ typedef typename std::vector<std::pair<vertex_t,vertex_t> >
+ ::const_iterator edge_iter;
+ typedef typename graph_traits<Graph>::adjacency_iterator adj_iter;
+
+ for (vertex_iter ui = vertex_set.begin(); ui != vertex_set.end(); ++ui) {
+ vertex_t u = *ui;
+ std::vector<vertex_t> adj;
+ for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e)
+ if (e->first == u)
+ adj.push_back(e->second);
+
+ std::pair<adj_iter, adj_iter> p = adjacent_vertices(u, g);
+ BOOST_CHECK(deg_size_t(std::distance(p.first, p.second)) == adj.size());
+ for (; p.first != p.second; ++p.first) {
+ vertex_t v = *p.first;
+ BOOST_CHECK(container_contains(adj, v) == true);
+ }
+ }
+ }
+
+ void test_vertex_list_graph
+ (const std::vector<vertex_t>& vertex_set, const Graph& g)
+ {
+ typedef typename graph_traits<Graph>::vertex_iterator v_iter;
+ std::pair<v_iter, v_iter> p = vertices(g);
+ BOOST_CHECK(num_vertices(g) == vertex_set.size());
+ v_size_t n = std::distance(p.first, p.second);
+ BOOST_CHECK(n == num_vertices(g));
+ for (; p.first != p.second; ++p.first) {
+ vertex_t v = *p.first;
+ BOOST_CHECK(container_contains(vertex_set, v) == true);
+ }
+ }
+
+ void test_edge_list_graph
+ (const std::vector<vertex_t>& vertex_set,
+ const std::vector< std::pair<vertex_t, vertex_t> >& edge_set,
+ const Graph& g)
+ {
+ typedef typename graph_traits<Graph>::edge_iterator e_iter;
+ std::pair<e_iter, e_iter> p = edges(g);
+ BOOST_CHECK(num_edges(g) == edge_set.size());
+ e_size_t m = std::distance(p.first, p.second);
+ BOOST_CHECK(m == num_edges(g));
+ for (; p.first != p.second; ++p.first) {
+ edge_t e = *p.first;
+ BOOST_CHECK(any_if(edge_set, connects(source(e, g), target(e, g), g)));
+ BOOST_CHECK(container_contains(vertex_set, source(e, g)) == true);
+ BOOST_CHECK(container_contains(vertex_set, target(e, g)) == true);
+ }
+ }
+
+ void test_adjacency_matrix
+ (const std::vector<vertex_t>& vertex_set,
+ const std::vector< std::pair<vertex_t, vertex_t> >& edge_set,
+ const Graph& g)
+ {
+ std::pair<edge_t, bool> p;
+ for (typename std::vector<std::pair<vertex_t, vertex_t> >
+ ::const_iterator i = edge_set.begin();
+ i != edge_set.end(); ++i) {
+ p = edge(i->first, i->second, g);
+ BOOST_CHECK(p.second == true);
+ BOOST_CHECK(source(p.first, g) == i->first);
+ BOOST_CHECK(target(p.first, g) == i->second);
+ }
+ typename std::vector<vertex_t>::const_iterator j, k;
+ for (j = vertex_set.begin(); j != vertex_set.end(); ++j)
+ for (k = vertex_set.begin(); k != vertex_set.end(); ++k) {
+ p = edge(*j, *k, g);
+ if (p.second == true)
+ BOOST_CHECK(any_if(edge_set,
+ connects(source(p.first, g), target(p.first, g), g)) == true);
+ }
+ }
+
+ //=========================================================================
+ // Mutating Operations
+
+ void test_add_vertex(Graph& g)
+ {
+ Graph cpy;
+ std::vector<vertex_t> iso_vec(num_vertices(g));
+ IsoMap iso_map(iso_vec.begin(), get(vertex_index, g));
+ copy_graph(g, cpy, orig_to_copy(iso_map));
+
+ assert((verify_isomorphism(g, cpy, iso_map)));
+
+ vertex_t v = add_vertex(g);
+
+ BOOST_CHECK(num_vertices(g) == num_vertices(cpy) + 1);
+
+ BOOST_CHECK(out_degree(v, g) == 0);
+
+ // Make sure the rest of the graph stayed the same
+ BOOST_CHECK((verify_isomorphism
+ (make_filtered_graph(g, keep_all(), ignore_vertex(v)), cpy,
+ iso_map)));
+ }
+
+ void test_add_edge(vertex_t u, vertex_t v, Graph& g)
+ {
+ Graph cpy;
+ std::vector<vertex_t> iso_vec(num_vertices(g));
+ IsoMap iso_map(iso_vec.begin(), get(vertex_index, g));
+ copy_graph(g, cpy, orig_to_copy(iso_map));
+
+ bool parallel_edge_exists = container_contains(adjacent_vertices(u, g), v);
+
+ std::pair<edge_t, bool> p = add_edge(u, v, g);
+ edge_t e = p.first;
+ bool added = p.second;
+
+ if (is_undirected(g) && u == v) // self edge
+ BOOST_CHECK(added == false);
+ else if (parallel_edge_exists)
+ BOOST_CHECK(allows_parallel_edges(g) && added == true
+ || !allows_parallel_edges(g) && added == false);
+ else
+ BOOST_CHECK(added == true);
+
+ if (p.second == true) { // edge added
+ BOOST_CHECK(num_edges(g) == num_edges(cpy) + 1);
+
+ BOOST_CHECK(container_contains(out_edges(u, g), e) == true);
+
+ BOOST_CHECK((verify_isomorphism
+ (make_filtered_graph(g, ignore_edge(e)), cpy, iso_map)));
+ }
+ else { // edge not added
+ if (! (is_undirected(g) && u == v)) {
+ // e should be a parallel edge
+ BOOST_CHECK(source(e, g) == u);
+ BOOST_CHECK(target(e, g) == v);
+ }
+ // The graph should not be changed.
+ BOOST_CHECK((verify_isomorphism(g, cpy, iso_map)));
+ }
+ } // test_add_edge()
+
+
+ void test_remove_edge(vertex_t u, vertex_t v, Graph& g)
+ {
+ Graph cpy;
+ std::vector<vertex_t> iso_vec(num_vertices(g));
+ IsoMap iso_map(iso_vec.begin(), get(vertex_index, g));
+ copy_graph(g, cpy, orig_to_copy(iso_map));
+
+ deg_size_t occurances = count(adjacent_vertices(u, g), v);
+
+ remove_edge(u, v, g);
+
+ BOOST_CHECK(num_edges(g) + occurances == num_edges(cpy));
+ BOOST_CHECK((verify_isomorphism
+ (g, make_filtered_graph(cpy, ignore_edges(u,v,cpy)),
+ iso_map)));
+ }
+
+ void test_remove_edge(edge_t e, Graph& g)
+ {
+ Graph cpy;
+ std::vector<vertex_t> iso_vec(num_vertices(g));
+ IsoMap iso_map(iso_vec.begin(), get(vertex_index, g));
+ copy_graph(g, cpy, orig_to_copy(iso_map));
+
+ vertex_t u = source(e, g), v = target(e, g);
+ deg_size_t occurances = count(adjacent_vertices(u, g), v);
+
+ remove_edge(e, g);
+
+ BOOST_CHECK(num_edges(g) + 1 == num_edges(cpy));
+ BOOST_CHECK(count(adjacent_vertices(u, g), v) + 1 == occurances);
+ BOOST_CHECK((verify_isomorphism
+ (g, make_filtered_graph(cpy, ignore_edge(e)),
+ iso_map)));
+ }
+
+ void test_clear_vertex(vertex_t v, Graph& g)
+ {
+ Graph cpy;
+ std::vector<vertex_t> iso_vec(num_vertices(g));
+ IsoMap iso_map(iso_vec.begin(), get(vertex_index, g));
+ copy_graph(g, cpy, orig_to_copy(iso_map));
+
+ clear_vertex(v, g);
+
+ BOOST_CHECK(out_degree(v, g) == 0);
+ BOOST_CHECK(num_vertices(g) == num_vertices(cpy));
+ BOOST_CHECK((verify_isomorphism
+ (g, make_filtered_graph(cpy, keep_all(), ignore_vertex(v)),
+ iso_map)));
+ }
+
+ //=========================================================================
+ // Property Map
+
+ template <typename PropVal, typename PropertyTag>
+ void test_readable_vertex_property_graph
+ (const std::vector<PropVal>& vertex_prop, PropertyTag, const Graph& g)
+ {
+ typedef typename property_map<Graph, PropertyTag>::const_type const_Map;
+ const_Map pmap = get(PropertyTag(), g);
+ typename std::vector<PropVal>::const_iterator i = vertex_prop.begin();
+
+ for (typename boost::graph_traits<Graph>::vertex_iterator
+ bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second;
+ bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9)
+ for (typename boost::graph_traits<Graph>::vertex_descriptor v;
+ bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false;
+ ++bgl_first_9) {
+ //BGL_FORALL_VERTICES_T(v, g, Graph) {
+ typename property_traits<const_Map>::value_type
+ pval1 = get(pmap, v), pval2 = get(PropertyTag(), g, v);
+ BOOST_CHECK(pval1 == pval2);
+ BOOST_CHECK(pval1 == *i++);
+ }
+ }
+
+ template <typename PropVal, typename PropertyTag>
+ void test_vertex_property_graph
+ (const std::vector<PropVal>& vertex_prop, PropertyTag tag, Graph& g)
+ {
+ typedef typename property_map<Graph, PropertyTag>::type PMap;
+ PMap pmap = get(PropertyTag(), g);
+ typename std::vector<PropVal>::const_iterator i = vertex_prop.begin();
+ for (typename boost::graph_traits<Graph>::vertex_iterator
+ bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second;
+ bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9)
+ for (typename boost::graph_traits<Graph>::vertex_descriptor v;
+ bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false;
+ ++bgl_first_9)
+ // BGL_FORALL_VERTICES_T(v, g, Graph)
+ put(pmap, v, *i++);
+
+ test_readable_vertex_property_graph(vertex_prop, tag, g);
+
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ put(pmap, v, vertex_prop[0]);
+
+ typename std::vector<PropVal>::const_iterator j = vertex_prop.begin();
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ put(PropertyTag(), g, v, *j++);
+
+ test_readable_vertex_property_graph(vertex_prop, tag, g);
+ }
+
+
+ };
+
+
+} // namespace boost
+
+#include <boost/graph/iteration_macros_undef.hpp>
+
+#endif // BOOST_GRAPH_TEST_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/graph_traits.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/graph_traits.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,168 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_TRAITS_HPP
+#define BOOST_GRAPH_TRAITS_HPP
+
+#include <boost/config.hpp>
+#include <iterator>
+#include <boost/tuple/tuple.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/detail/workaround.hpp>
+
+namespace boost {
+
+ template <typename G>
+ struct graph_traits {
+ typedef typename G::vertex_descriptor vertex_descriptor;
+ typedef typename G::edge_descriptor edge_descriptor;
+ typedef typename G::adjacency_iterator adjacency_iterator;
+ typedef typename G::out_edge_iterator out_edge_iterator;
+ typedef typename G::in_edge_iterator in_edge_iterator;
+ typedef typename G::vertex_iterator vertex_iterator;
+ typedef typename G::edge_iterator edge_iterator;
+
+ typedef typename G::directed_category directed_category;
+ typedef typename G::edge_parallel_category edge_parallel_category;
+ typedef typename G::traversal_category traversal_category;
+
+ typedef typename G::vertices_size_type vertices_size_type;
+ typedef typename G::edges_size_type edges_size_type;
+ typedef typename G::degree_size_type degree_size_type;
+
+ static inline vertex_descriptor null_vertex();
+ };
+
+ template <typename G>
+ inline typename graph_traits<G>::vertex_descriptor
+ graph_traits<G>::null_vertex()
+ {
+ return G::null_vertex();
+ }
+
+ // directed_category tags
+ struct directed_tag { };
+ struct undirected_tag { };
+ struct bidirectional_tag : public directed_tag { };
+
+ namespace detail {
+ inline bool is_directed(directed_tag) { return true; }
+ inline bool is_directed(undirected_tag) { return false; }
+ }
+
+ template <typename Graph>
+ bool is_directed(const Graph&) {
+ typedef typename graph_traits<Graph>::directed_category Cat;
+ return detail::is_directed(Cat());
+ }
+ template <typename Graph>
+ bool is_undirected(const Graph& g) {
+ return ! is_directed(g);
+ }
+
+ // edge_parallel_category tags
+ struct allow_parallel_edge_tag {};
+ struct disallow_parallel_edge_tag {};
+
+ namespace detail {
+ inline bool allows_parallel(allow_parallel_edge_tag) { return true; }
+ inline bool allows_parallel(disallow_parallel_edge_tag) { return false; }
+ }
+
+ template <typename Graph>
+ bool allows_parallel_edges(const Graph&) {
+ typedef typename graph_traits<Graph>::edge_parallel_category Cat;
+ return detail::allows_parallel(Cat());
+ }
+
+ // traversal_category tags
+ struct incidence_graph_tag { };
+ struct adjacency_graph_tag { };
+ struct bidirectional_graph_tag :
+ public virtual incidence_graph_tag { };
+ struct vertex_list_graph_tag { };
+ struct edge_list_graph_tag { };
+ struct adjacency_matrix_tag { };
+
+ //?? not the right place ?? Lee
+ typedef boost::forward_traversal_tag multi_pass_input_iterator_tag;
+
+ template <typename G>
+ struct edge_property_type {
+ typedef typename G::edge_property_type type;
+ };
+ template <typename G>
+ struct vertex_property_type {
+ typedef typename G::vertex_property_type type;
+ };
+ template <typename G>
+ struct graph_property_type {
+ typedef typename G::graph_property_type type;
+ };
+
+ struct no_vertex_bundle {};
+ struct no_edge_bundle {};
+
+ template<typename G>
+ struct vertex_bundle_type
+ {
+ typedef typename G::vertex_bundled type;
+ };
+
+ template<typename G>
+ struct edge_bundle_type
+ {
+ typedef typename G::edge_bundled type;
+ };
+
+ namespace graph { namespace detail {
+ template<typename Graph, typename Descriptor>
+ class bundled_result
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename mpl::if_c<(is_same<Descriptor, Vertex>::value),
+ vertex_bundle_type<Graph>,
+ edge_bundle_type<Graph> >::type bundler;
+
+ public:
+ typedef typename bundler::type type;
+ };
+ } } // end namespace graph::detail
+} // namespace boost
+
+// Since pair is in namespace std, Koenig lookup will find source and
+// target if they are also defined in namespace std. This is illegal,
+// but the alternative is to put source and target in the global
+// namespace which causes name conflicts with other libraries (like
+// SUIF).
+namespace std {
+
+ /* Some helper functions for dealing with pairs as edges */
+ template <class T, class G>
+ T source(pair<T,T> p, const G&) { return p.first; }
+
+ template <class T, class G>
+ T target(pair<T,T> p, const G&) { return p.second; }
+
+}
+
+#if defined(__GNUC__) && defined(__SGI_STL_PORT)
+// For some reason g++ with STLport does not see the above definition
+// of source() and target() unless we bring them into the boost
+// namespace.
+namespace boost {
+ using std::source;
+ using std::target;
+}
+#endif
+
+#endif // BOOST_GRAPH_TRAITS_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/graph_utility.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/graph_utility.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,425 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_UTILITY_HPP
+#define BOOST_GRAPH_UTILITY_HPP
+
+#include <stdlib.h>
+#include <iostream>
+#include <algorithm>
+#include <assert.h>
+#include <boost/config.hpp>
+#include <boost/tuple/tuple.hpp>
+
+#if !defined BOOST_NO_SLIST
+# ifdef BOOST_SLIST_HEADER
+# include BOOST_SLIST_HEADER
+# else
+# include <slist>
+# endif
+#endif
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/pending/container_traits.hpp>
+#include <boost/graph/depth_first_search.hpp>
+// iota moved to detail/algorithm.hpp
+#include <boost/detail/algorithm.hpp>
+
+namespace boost {
+
+ // Provide an undirected graph interface alternative to the
+ // the source() and target() edge functions.
+ template <class UndirectedGraph>
+ inline
+ std::pair<typename graph_traits<UndirectedGraph>::vertex_descriptor,
+ typename graph_traits<UndirectedGraph>::vertex_descriptor>
+ incident(typename graph_traits<UndirectedGraph>::edge_descriptor e,
+ UndirectedGraph& g)
+ {
+ return std::make_pair(source(e,g), target(e,g));
+ }
+
+ // Provide an undirected graph interface alternative
+ // to the out_edges() function.
+ template <class Graph>
+ inline
+ std::pair<typename graph_traits<Graph>::out_edge_iterator,
+ typename graph_traits<Graph>::out_edge_iterator>
+ incident_edges(typename graph_traits<Graph>::vertex_descriptor u,
+ Graph& g)
+ {
+ return out_edges(u, g);
+ }
+
+ template <class Graph>
+ inline typename graph_traits<Graph>::vertex_descriptor
+ opposite(typename graph_traits<Graph>::edge_descriptor e,
+ typename graph_traits<Graph>::vertex_descriptor v,
+ const Graph& g)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+ if (v == source(e, g))
+ return target(e, g);
+ else if (v == target(e, g))
+ return source(e, g);
+ else
+ return vertex_descriptor();
+ }
+
+ //===========================================================================
+ // Some handy predicates
+
+ template <typename Vertex, typename Graph>
+ struct incident_from_predicate {
+ incident_from_predicate(Vertex u, const Graph& g)
+ : m_u(u), m_g(g) { }
+ template <class Edge>
+ bool operator()(const Edge& e) const {
+ return source(e, m_g) == m_u;
+ }
+ Vertex m_u;
+ const Graph& m_g;
+ };
+ template <typename Vertex, typename Graph>
+ inline incident_from_predicate<Vertex, Graph>
+ incident_from(Vertex u, const Graph& g) {
+ return incident_from_predicate<Vertex, Graph>(u, g);
+ }
+
+ template <typename Vertex, typename Graph>
+ struct incident_to_predicate {
+ incident_to_predicate(Vertex u, const Graph& g)
+ : m_u(u), m_g(g) { }
+ template <class Edge>
+ bool operator()(const Edge& e) const {
+ return target(e, m_g) == m_u;
+ }
+ Vertex m_u;
+ const Graph& m_g;
+ };
+ template <typename Vertex, typename Graph>
+ inline incident_to_predicate<Vertex, Graph>
+ incident_to(Vertex u, const Graph& g) {
+ return incident_to_predicate<Vertex, Graph>(u, g);
+ }
+
+ template <typename Vertex, typename Graph>
+ struct incident_on_predicate {
+ incident_on_predicate(Vertex u, const Graph& g)
+ : m_u(u), m_g(g) { }
+ template <class Edge>
+ bool operator()(const Edge& e) const {
+ return source(e, m_g) == m_u || target(e, m_g) == m_u;
+ }
+ Vertex m_u;
+ const Graph& m_g;
+ };
+ template <typename Vertex, typename Graph>
+ inline incident_on_predicate<Vertex, Graph>
+ incident_on(Vertex u, const Graph& g) {
+ return incident_on_predicate<Vertex, Graph>(u, g);
+ }
+
+ template <typename Vertex, typename Graph>
+ struct connects_predicate {
+ connects_predicate(Vertex u, Vertex v, const Graph& g)
+ : m_u(u), m_v(v), m_g(g) { }
+ template <class Edge>
+ bool operator()(const Edge& e) const {
+ if (is_directed(m_g))
+ return source(e, m_g) == m_u && target(e, m_g) == m_v;
+ else
+ return (source(e, m_g) == m_u && target(e, m_g) == m_v)
+ || (source(e, m_g) == m_v && target(e, m_g) == m_u);
+ }
+ Vertex m_u, m_v;
+ const Graph& m_g;
+ };
+ template <typename Vertex, typename Graph>
+ inline connects_predicate<Vertex, Graph>
+ connects(Vertex u, Vertex v, const Graph& g) {
+ return connects_predicate<Vertex, Graph>(u, v, g);
+ }
+
+
+ // Need to convert all of these printing functions to take an ostream object
+ // -JGS
+
+ template <class IncidenceGraph, class Name>
+ void print_in_edges(const IncidenceGraph& G, Name name)
+ {
+ typename graph_traits<IncidenceGraph>::vertex_iterator ui,ui_end;
+ for (tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) {
+ std::cout << get(name,*ui) << " <-- ";
+ typename graph_traits<IncidenceGraph>
+ ::in_edge_iterator ei, ei_end;
+ for(tie(ei,ei_end) = in_edges(*ui,G); ei != ei_end; ++ei)
+ std::cout << get(name,source(*ei,G)) << " ";
+ std::cout << std::endl;
+ }
+ }
+
+ template <class IncidenceGraph, class Name>
+ void print_graph_dispatch(const IncidenceGraph& G, Name name, directed_tag)
+ {
+ typename graph_traits<IncidenceGraph>::vertex_iterator ui,ui_end;
+ for (tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) {
+ std::cout << get(name,*ui) << " --> ";
+ typename graph_traits<IncidenceGraph>
+ ::out_edge_iterator ei, ei_end;
+ for(tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei)
+ std::cout << get(name,target(*ei,G)) << " ";
+ std::cout << std::endl;
+ }
+ }
+ template <class IncidenceGraph, class Name>
+ void print_graph_dispatch(const IncidenceGraph& G, Name name, undirected_tag)
+ {
+ typename graph_traits<IncidenceGraph>::vertex_iterator ui,ui_end;
+ for (tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) {
+ std::cout << get(name,*ui) << " <--> ";
+ typename graph_traits<IncidenceGraph>
+ ::out_edge_iterator ei, ei_end;
+ for(tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei)
+ std::cout << get(name,target(*ei,G)) << " ";
+ std::cout << std::endl;
+ }
+ }
+ template <class IncidenceGraph, class Name>
+ void print_graph(const IncidenceGraph& G, Name name)
+ {
+ typedef typename graph_traits<IncidenceGraph>
+ ::directed_category Cat;
+ print_graph_dispatch(G, name, Cat());
+ }
+ template <class IncidenceGraph>
+ void print_graph(const IncidenceGraph& G) {
+ print_graph(G, get(vertex_index, G));
+ }
+
+ template <class EdgeListGraph, class Name>
+ void print_edges(const EdgeListGraph& G, Name name)
+ {
+ typename graph_traits<EdgeListGraph>::edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = edges(G); ei != ei_end; ++ei)
+ std::cout << "(" << get(name, source(*ei, G))
+ << "," << get(name, target(*ei, G)) << ") ";
+ std::cout << std::endl;
+ }
+
+ template <class EdgeListGraph, class VertexName, class EdgeName>
+ void print_edges2(const EdgeListGraph& G, VertexName vname, EdgeName ename)
+ {
+ typename graph_traits<EdgeListGraph>::edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = edges(G); ei != ei_end; ++ei)
+ std::cout << get(ename, *ei) << "(" << get(vname, source(*ei, G))
+ << "," << get(vname, target(*ei, G)) << ") ";
+ std::cout << std::endl;
+ }
+
+ template <class VertexListGraph, class Name>
+ void print_vertices(const VertexListGraph& G, Name name)
+ {
+ typename graph_traits<VertexListGraph>::vertex_iterator vi,vi_end;
+ for (tie(vi,vi_end) = vertices(G); vi != vi_end; ++vi)
+ std::cout << get(name,*vi) << " ";
+ std::cout << std::endl;
+ }
+
+ template <class Graph, class Vertex>
+ bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, bidirectional_tag)
+ {
+ typedef typename graph_traits<Graph>::edge_descriptor
+ edge_descriptor;
+ typename graph_traits<Graph>::adjacency_iterator vi, viend,
+ adj_found;
+ tie(vi, viend) = adjacent_vertices(a, g);
+ adj_found = std::find(vi, viend, b);
+ if (adj_found == viend)
+ return false;
+
+ typename graph_traits<Graph>::out_edge_iterator oi, oiend,
+ out_found;
+ tie(oi, oiend) = out_edges(a, g);
+ out_found = std::find_if(oi, oiend, incident_to(b, g));
+ if (out_found == oiend)
+ return false;
+
+ typename graph_traits<Graph>::in_edge_iterator ii, iiend,
+ in_found;
+ tie(ii, iiend) = in_edges(b, g);
+ in_found = std::find_if(ii, iiend, incident_from(a, g));
+ if (in_found == iiend)
+ return false;
+
+ return true;
+ }
+ template <class Graph, class Vertex>
+ bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, directed_tag)
+ {
+ typedef typename graph_traits<Graph>::edge_descriptor
+ edge_descriptor;
+ typename graph_traits<Graph>::adjacency_iterator vi, viend, found;
+ tie(vi, viend) = adjacent_vertices(a, g);
+#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 && defined(__SGI_STL_PORT)
+ // Getting internal compiler error with std::find()
+ found = viend;
+ for (; vi != viend; ++vi)
+ if (*vi == b) {
+ found = vi;
+ break;
+ }
+#else
+ found = std::find(vi, viend, b);
+#endif
+ if ( found == viend )
+ return false;
+
+ typename graph_traits<Graph>::out_edge_iterator oi, oiend,
+ out_found;
+ tie(oi, oiend) = out_edges(a, g);
+
+#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 && defined(__SGI_STL_PORT)
+ // Getting internal compiler error with std::find()
+ out_found = oiend;
+ for (; oi != oiend; ++oi)
+ if (target(*oi, g) == b) {
+ out_found = oi;
+ break;
+ }
+#else
+ out_found = std::find_if(oi, oiend, incident_to(b, g));
+#endif
+ if (out_found == oiend)
+ return false;
+ return true;
+ }
+ template <class Graph, class Vertex>
+ bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, undirected_tag)
+ {
+ return is_adj_dispatch(g, a, b, directed_tag());
+ }
+
+ template <class Graph, class Vertex>
+ bool is_adjacent(Graph& g, Vertex a, Vertex b) {
+ typedef typename graph_traits<Graph>::directed_category Cat;
+ return is_adj_dispatch(g, a, b, Cat());
+ }
+
+ template <class Graph, class Edge>
+ bool in_edge_set(Graph& g, Edge e)
+ {
+ typename Graph::edge_iterator ei, ei_end, found;
+ tie(ei, ei_end) = edges(g);
+ found = std::find(ei, ei_end, e);
+ return found != ei_end;
+ }
+
+ template <class Graph, class Vertex>
+ bool in_vertex_set(Graph& g, Vertex v)
+ {
+ typename Graph::vertex_iterator vi, vi_end, found;
+ tie(vi, vi_end) = vertices(g);
+ found = std::find(vi, vi_end, v);
+ return found != vi_end;
+ }
+
+ template <class Graph, class Vertex>
+ bool in_edge_set(Graph& g, Vertex u, Vertex v)
+ {
+ typename Graph::edge_iterator ei, ei_end;
+ for (tie(ei,ei_end) = edges(g); ei != ei_end; ++ei)
+ if (source(*ei,g) == u && target(*ei,g) == v)
+ return true;
+ return false;
+ }
+
+ // is x a descendant of y?
+ template <typename ParentMap>
+ inline bool is_descendant
+ (typename property_traits<ParentMap>::value_type x,
+ typename property_traits<ParentMap>::value_type y,
+ ParentMap parent)
+ {
+ if (get(parent, x) == x) // x is the root of the tree
+ return false;
+ else if (get(parent, x) == y)
+ return true;
+ else
+ return is_descendant(get(parent, x), y, parent);
+ }
+
+ // is y reachable from x?
+ template <typename IncidenceGraph, typename VertexColorMap>
+ inline bool is_reachable
+ (typename graph_traits<IncidenceGraph>::vertex_descriptor x,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor y,
+ const IncidenceGraph& g,
+ VertexColorMap color) // should start out white for every vertex
+ {
+ typedef typename property_traits<VertexColorMap>::value_type ColorValue;
+ dfs_visitor<> vis;
+ depth_first_visit(g, x, vis, color);
+ return get(color, y) != color_traits<ColorValue>::white();
+ }
+
+ // Is the undirected graph connected?
+ // Is the directed graph strongly connected?
+ template <typename VertexListGraph, typename VertexColorMap>
+ inline bool is_connected(const VertexListGraph& g, VertexColorMap color)
+ {
+ typedef typename property_traits<VertexColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+ typename graph_traits<VertexListGraph>::vertex_iterator
+ ui, ui_end, vi, vi_end, ci, ci_end;
+ for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
+ for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ if (*ui != *vi) {
+ for (tie(ci, ci_end) = vertices(g); ci != ci_end; ++ci)
+ put(color, *ci, Color::white());
+ if (! is_reachable(*ui, *vi, g, color))
+ return false;
+ }
+ return true;
+ }
+
+ template <typename Graph>
+ bool is_self_loop
+ (typename graph_traits<Graph>::edge_descriptor e,
+ const Graph& g)
+ {
+ return source(e, g) == target(e, g);
+ }
+
+
+ template <class T1, class T2>
+ std::pair<T1,T2>
+ make_list(const T1& t1, const T2& t2)
+ { return std::make_pair(t1, t2); }
+
+ template <class T1, class T2, class T3>
+ std::pair<T1,std::pair<T2,T3> >
+ make_list(const T1& t1, const T2& t2, const T3& t3)
+ { return std::make_pair(t1, std::make_pair(t2, t3)); }
+
+ template <class T1, class T2, class T3, class T4>
+ std::pair<T1,std::pair<T2,std::pair<T3,T4> > >
+ make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
+ { return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, t4))); }
+
+ template <class T1, class T2, class T3, class T4, class T5>
+ std::pair<T1,std::pair<T2,std::pair<T3,std::pair<T4,T5> > > >
+ make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
+ { return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, std::make_pair(t4, t5)))); }
+
+} /* namespace boost */
+
+#endif /* BOOST_GRAPH_UTILITY_HPP*/
Added: branches/CMake/release/libs/graph/include/boost/graph/graphml.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/graphml.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,332 @@
+// Copyright (C) 2006 Tiago de Paula Peixoto <tiago_at_[hidden]>
+// Copyright (C) 2004 The Trustees of Indiana University.
+//
+// Use, modification and distribution is subject to 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)
+//
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+// Tiago de Paula Peixoto
+
+#ifndef BOOST_GRAPH_GRAPHML_HPP
+#define BOOST_GRAPH_GRAPHML_HPP
+
+#include <boost/config.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/any.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/graph/graphviz.hpp> // for exceptions
+#include <typeinfo>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/find.hpp>
+#include <boost/mpl/for_each.hpp>
+#include <exception>
+#include <sstream>
+
+namespace boost
+{
+
+/////////////////////////////////////////////////////////////////////////////
+// Graph reader exceptions
+/////////////////////////////////////////////////////////////////////////////
+struct parse_error: public graph_exception
+{
+ parse_error(const std::string& error) {statement = "parse error: " + error;}
+ virtual ~parse_error() throw() {}
+ virtual const char* what() const throw() {return statement.c_str();}
+ std::string statement;
+};
+
+
+class mutate_graph
+{
+public:
+ virtual ~mutate_graph() {}
+ virtual bool is_directed() const = 0;
+
+ virtual boost::any do_add_vertex() = 0;
+ virtual std::pair<boost::any,bool> do_add_edge(boost::any source, boost::any target) = 0;
+
+ virtual void
+ set_graph_property(const std::string& name, const std::string& value, const std::string& value_type) = 0;
+
+ virtual void
+ set_vertex_property(const std::string& name, boost::any vertex, const std::string& value, const std::string& value_type) = 0;
+
+ virtual void
+ set_edge_property(const std::string& name, boost::any edge, const std::string& value, const std::string& value_type) = 0;
+};
+
+template<typename MutableGraph>
+class mutate_graph_impl : public mutate_graph
+{
+ typedef typename graph_traits<MutableGraph>::vertex_descriptor vertex_descriptor;
+ typedef typename graph_traits<MutableGraph>::edge_descriptor edge_descriptor;
+
+ public:
+ mutate_graph_impl(MutableGraph& g, dynamic_properties& dp)
+ : m_g(g), m_dp(dp) { }
+
+ bool is_directed() const
+ {
+ return is_convertible<typename graph_traits<MutableGraph>::directed_category,
+ directed_tag>::value;
+ }
+
+ virtual any do_add_vertex()
+ {
+ return any(add_vertex(m_g));
+ }
+
+ virtual std::pair<any,bool> do_add_edge(any source, any target)
+ {
+ std::pair<edge_descriptor,bool> retval = add_edge(any_cast<vertex_descriptor>(source),
+ any_cast<vertex_descriptor>(target), m_g);
+ return std::make_pair(any(retval.first), retval.second);
+ }
+
+ virtual void
+ set_graph_property(const std::string& name, const std::string& value, const std::string& value_type)
+ {
+ bool type_found = false;
+ try
+ {
+ mpl::for_each<value_types>(put_property<MutableGraph,value_types>
+ (name, m_dp, m_g, value, value_type, m_type_names, type_found));
+ }
+ catch (bad_lexical_cast)
+ {
+ throw parse_error("invalid value \"" + value + "\" for key " +
+ name + " of type " + value_type);
+ }
+ if (!type_found)
+ throw parse_error("unrecognized type \"" + value_type +
+ "\" for key " + name);
+
+ }
+
+ virtual void
+ set_vertex_property(const std::string& name, any vertex, const std::string& value, const std::string& value_type)
+ {
+ bool type_found = false;
+ try
+ {
+ mpl::for_each<value_types>(put_property<vertex_descriptor,value_types>
+ (name, m_dp, any_cast<vertex_descriptor>(vertex),
+ value, value_type, m_type_names, type_found));
+ }
+ catch (bad_lexical_cast)
+ {
+ throw parse_error("invalid value \"" + value + "\" for key " +
+ name + " of type " + value_type);
+ }
+ if (!type_found)
+ throw parse_error("unrecognized type \"" + value_type +
+ "\" for key " + name);
+
+ }
+
+ virtual void
+ set_edge_property(const std::string& name, any edge, const std::string& value, const std::string& value_type)
+ {
+ bool type_found = false;
+ try
+ {
+ mpl::for_each<value_types>(put_property<edge_descriptor,value_types>
+ (name, m_dp, any_cast<edge_descriptor>(edge),
+ value, value_type, m_type_names, type_found));
+ }
+ catch (bad_lexical_cast)
+ {
+ throw parse_error("invalid value \"" + value + "\" for key " +
+ name + " of type " + value_type);
+ }
+ if (!type_found)
+ throw parse_error("unrecognized type \"" + value_type +
+ "\" for key " + name);
+ }
+
+ template <typename Key, typename ValueVector>
+ class put_property
+ {
+ public:
+ put_property(const std::string& name, dynamic_properties& dp, const Key& key,
+ const std::string& value, const std::string& value_type,
+ char** type_names, bool& type_found)
+ : m_name(name), m_dp(dp), m_key(key), m_value(value),
+ m_value_type(value_type), m_type_names(type_names),
+ m_type_found(type_found) {}
+ template <class Value>
+ void operator()(Value)
+ {
+ if (m_value_type == m_type_names[mpl::find<ValueVector,Value>::type::pos::value])
+ {
+ put(m_name, m_dp, m_key, lexical_cast<Value>(m_value));
+ m_type_found = true;
+ }
+ }
+ private:
+ const std::string& m_name;
+ dynamic_properties& m_dp;
+ const Key& m_key;
+ const std::string& m_value;
+ const std::string& m_value_type;
+ char** m_type_names;
+ bool& m_type_found;
+ };
+
+protected:
+ MutableGraph& m_g;
+ dynamic_properties& m_dp;
+ typedef mpl::vector<bool, int, long, float, double, std::string> value_types;
+ static char* m_type_names[];
+};
+
+template<typename MutableGraph>
+char* mutate_graph_impl<MutableGraph>::m_type_names[] = {"boolean", "int", "long", "float", "double", "string"};
+
+void
+read_graphml(std::istream& in, mutate_graph& g);
+
+template<typename MutableGraph>
+void
+read_graphml(std::istream& in, MutableGraph& g, dynamic_properties& dp)
+{
+ mutate_graph_impl<MutableGraph> mg(g,dp);
+ read_graphml(in, mg);
+}
+
+template <typename Types>
+class get_type_name
+{
+public:
+ get_type_name(const std::type_info& type, char** type_names, std::string& type_name)
+ : m_type(type), m_type_names(type_names), m_type_name(type_name) {}
+ template <typename Type>
+ void operator()(Type)
+ {
+ if (typeid(Type) == m_type)
+ m_type_name = m_type_names[mpl::find<Types,Type>::type::pos::value];
+ }
+private:
+ const std::type_info &m_type;
+ char** m_type_names;
+ std::string &m_type_name;
+};
+
+
+template <typename Graph, typename VertexIndexMap>
+void
+write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index,
+ const dynamic_properties& dp, bool ordered_vertices=false)
+{
+ typedef typename graph_traits<Graph>::directed_category directed_category;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+
+ BOOST_STATIC_CONSTANT(bool,
+ graph_is_directed =
+ (is_convertible<directed_category*, directed_tag*>::value));
+
+ out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ << "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\n";
+
+ typedef mpl::vector<bool, short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long, float, double, long double, std::string> value_types;
+ char* type_names[] = {"boolean", "int", "int", "int", "int", "long", "long", "long", "long", "float", "double", "double", "string"};
+ std::map<std::string, std::string> graph_key_ids;
+ std::map<std::string, std::string> vertex_key_ids;
+ std::map<std::string, std::string> edge_key_ids;
+ int key_count = 0;
+
+ // Output keys
+ for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
+ {
+ std::string key_id = "key" + lexical_cast<std::string>(key_count++);
+ if (i->second->key() == typeid(Graph))
+ vertex_key_ids[i->first] = key_id;
+ else if (i->second->key() == typeid(vertex_descriptor))
+ vertex_key_ids[i->first] = key_id;
+ else if (i->second->key() == typeid(edge_descriptor))
+ edge_key_ids[i->first] = key_id;
+ else
+ continue;
+ std::string type_name = "string";
+ mpl::for_each<value_types>(get_type_name<value_types>(i->second->value(), type_names, type_name));
+ out << " <key id=\"" << key_id << "\" for=\""
+ << (i->second->key() == typeid(Graph) ? "graph" : (i->second->key() == typeid(vertex_descriptor) ? "node" : "edge")) << "\""
+ << " attr.name=\"" << i->first << "\""
+ << " attr.type=\"" << type_name << "\""
+ << " />\n";
+ }
+
+ out << " <graph id=\"G\" edgedefault=\""
+ << (graph_is_directed ? "directed" : "undirected") << "\""
+ << " parse.nodeids=\"" << (ordered_vertices ? "canonical" : "free") << "\""
+ << " parse.edgeids=\"canonical\" parse.order=\"nodesfirst\">\n";
+
+ // Output graph data
+ for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
+ {
+ if (i->second->key() == typeid(Graph))
+ {
+ out << " <data key=\"" << graph_key_ids[i->first] << "\">"
+ << i->second->get_string(g) << "</data>\n";
+ }
+ }
+
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
+ vertex_iterator v, v_end;
+ for (tie(v, v_end) = vertices(g); v != v_end; ++v)
+ {
+ out << " <node id=\"n" << get(vertex_index, *v) << "\">\n";
+ // Output data
+ for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
+ {
+ if (i->second->key() == typeid(vertex_descriptor))
+ {
+ out << " <data key=\"" << vertex_key_ids[i->first] << "\">"
+ << i->second->get_string(*v) << "</data>\n";
+ }
+ }
+ out << " </node>\n";
+ }
+
+ typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
+ edge_iterator e, e_end;
+ typename graph_traits<Graph>::edges_size_type edge_count = 0;
+ for (tie(e, e_end) = edges(g); e != e_end; ++e)
+ {
+ out << " <edge id=\"e" << edge_count++ << "\" source=\"n"
+ << get(vertex_index, source(*e, g)) << "\" target=\"n"
+ << get(vertex_index, target(*e, g)) << "\">\n";
+
+ // Output data
+ for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
+ {
+ if (i->second->key() == typeid(edge_descriptor))
+ {
+ out << " <data key=\"" << edge_key_ids[i->first] << "\">"
+ << i->second->get_string(*e) << "</data>\n";
+ }
+ }
+ out << " </edge>\n";
+ }
+
+ out << " </graph>\n"
+ << "</graphml>\n";
+}
+
+
+template <typename Graph>
+void
+write_graphml(std::ostream& out, const Graph& g, const dynamic_properties& dp,
+ bool ordered_vertices=false)
+{
+ write_graphml(out, g, get(vertex_index, g), dp, ordered_vertices);
+}
+
+} // boost namespace
+
+#endif // BOOST_GRAPH_GRAPHML_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/graphviz.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/graphviz.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,783 @@
+//=======================================================================
+// Copyright 2001 University of Notre Dame.
+// Copyright 2003 Jeremy Siek
+// Authors: Lie-Quan Lee and Jeremy Siek
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_GRAPHVIZ_HPP
+#define BOOST_GRAPHVIZ_HPP
+
+#include <boost/config.hpp>
+#include <string>
+#include <map>
+#include <iostream>
+#include <fstream>
+#include <stdio.h> // for FILE
+#include <boost/property_map.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/subgraph.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/dynamic_property_map.hpp>
+
+#ifdef BOOST_HAS_DECLSPEC
+# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_GRAPH_DYN_LINK)
+# ifdef BOOST_GRAPH_SOURCE
+# define BOOST_GRAPH_DECL __declspec(dllexport)
+# else
+# define BOOST_GRAPH_DECL __declspec(dllimport)
+# endif // BOOST_GRAPH_SOURCE
+# endif // DYN_LINK
+#endif // BOOST_HAS_DECLSPEC
+
+#ifndef BOOST_GRAPH_DECL
+# define BOOST_GRAPH_DECL
+#endif
+
+namespace boost {
+
+ template <typename directed_category>
+ struct graphviz_io_traits {
+ static std::string name() {
+ return "digraph";
+ }
+ static std::string delimiter() {
+ return "->";
+ } };
+
+ template <>
+ struct graphviz_io_traits <undirected_tag> {
+ static std::string name() {
+ return "graph";
+ }
+ static std::string delimiter() {
+ return "--";
+ }
+ };
+
+ struct default_writer {
+ void operator()(std::ostream&) const {
+ }
+ template <class VorE>
+ void operator()(std::ostream&, const VorE&) const {
+ }
+ };
+
+ template <class Name>
+ class label_writer {
+ public:
+ label_writer(Name _name) : name(_name) {}
+ template <class VertexOrEdge>
+ void operator()(std::ostream& out, const VertexOrEdge& v) const {
+ out << "[label=\"" << get(name, v) << "\"]";
+ }
+ private:
+ Name name;
+ };
+ template <class Name>
+ inline label_writer<Name>
+ make_label_writer(Name n) {
+ return label_writer<Name>(n);
+ }
+
+ enum edge_attribute_t { edge_attribute = 1111 };
+ enum vertex_attribute_t { vertex_attribute = 2222 };
+ enum graph_graph_attribute_t { graph_graph_attribute = 3333 };
+ enum graph_vertex_attribute_t { graph_vertex_attribute = 4444 };
+ enum graph_edge_attribute_t { graph_edge_attribute = 5555 };
+
+ BOOST_INSTALL_PROPERTY(edge, attribute);
+ BOOST_INSTALL_PROPERTY(vertex, attribute);
+ BOOST_INSTALL_PROPERTY(graph, graph_attribute);
+ BOOST_INSTALL_PROPERTY(graph, vertex_attribute);
+ BOOST_INSTALL_PROPERTY(graph, edge_attribute);
+
+
+ template <class Attribute>
+ inline void write_attributes(const Attribute& attr, std::ostream& out) {
+ typename Attribute::const_iterator i, iend;
+ i = attr.begin();
+ iend = attr.end();
+
+ while ( i != iend ) {
+ out << i->first << "=\"" << i->second << "\"";
+ ++i;
+ if ( i != iend )
+ out << ", ";
+ }
+ }
+
+ template<typename Attributes>
+ inline void write_all_attributes(Attributes attributes,
+ const std::string& name,
+ std::ostream& out)
+ {
+ typename Attributes::const_iterator i = attributes.begin(),
+ end = attributes.end();
+ if (i != end) {
+ out << name << " [\n";
+ write_attributes(attributes, out);
+ out << "];\n";
+ }
+ }
+
+ inline void write_all_attributes(detail::error_property_not_found,
+ const std::string&,
+ std::ostream&)
+ {
+ // Do nothing - no attributes exist
+ }
+
+
+
+
+ template <typename GraphGraphAttributes,
+ typename GraphNodeAttributes,
+ typename GraphEdgeAttributes>
+ struct graph_attributes_writer
+ {
+ graph_attributes_writer(GraphGraphAttributes gg,
+ GraphNodeAttributes gn,
+ GraphEdgeAttributes ge)
+ : g_attributes(gg), n_attributes(gn), e_attributes(ge) { }
+
+ void operator()(std::ostream& out) const {
+ write_all_attributes(g_attributes, "graph", out);
+ write_all_attributes(n_attributes, "node", out);
+ write_all_attributes(e_attributes, "edge", out);
+ }
+ GraphGraphAttributes g_attributes;
+ GraphNodeAttributes n_attributes;
+ GraphEdgeAttributes e_attributes;
+ };
+
+ template <typename GAttrMap, typename NAttrMap, typename EAttrMap>
+ graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap>
+ make_graph_attributes_writer(const GAttrMap& g_attr, const NAttrMap& n_attr,
+ const EAttrMap& e_attr) {
+ return graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap>
+ (g_attr, n_attr, e_attr);
+ }
+
+
+ template <typename Graph>
+ graph_attributes_writer
+ <typename graph_property<Graph, graph_graph_attribute_t>::type,
+ typename graph_property<Graph, graph_vertex_attribute_t>::type,
+ typename graph_property<Graph, graph_edge_attribute_t>::type>
+ make_graph_attributes_writer(const Graph& g)
+ {
+ typedef typename graph_property<Graph, graph_graph_attribute_t>::type
+ GAttrMap;
+ typedef typename graph_property<Graph, graph_vertex_attribute_t>::type
+ NAttrMap;
+ typedef typename graph_property<Graph, graph_edge_attribute_t>::type
+ EAttrMap;
+ GAttrMap gam = get_property(g, graph_graph_attribute);
+ NAttrMap nam = get_property(g, graph_vertex_attribute);
+ EAttrMap eam = get_property(g, graph_edge_attribute);
+ graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap> writer(gam, nam, eam);
+ return writer;
+ }
+
+ template <typename AttributeMap>
+ struct attributes_writer {
+ attributes_writer(AttributeMap attr)
+ : attributes(attr) { }
+
+ template <class VorE>
+ void operator()(std::ostream& out, const VorE& e) const {
+ this->write_attribute(out, attributes[e]);
+ }
+
+ private:
+ template<typename AttributeSequence>
+ void write_attribute(std::ostream& out,
+ const AttributeSequence& seq) const
+ {
+ if (!seq.empty()) {
+ out << "[";
+ write_attributes(seq, out);
+ out << "]";
+ }
+ }
+
+ void write_attribute(std::ostream&,
+ detail::error_property_not_found) const
+ {
+ }
+ AttributeMap attributes;
+ };
+
+ template <typename Graph>
+ attributes_writer
+ <typename property_map<Graph, edge_attribute_t>::const_type>
+ make_edge_attributes_writer(const Graph& g)
+ {
+ typedef typename property_map<Graph, edge_attribute_t>::const_type
+ EdgeAttributeMap;
+ return attributes_writer<EdgeAttributeMap>(get(edge_attribute, g));
+ }
+
+ template <typename Graph>
+ attributes_writer
+ <typename property_map<Graph, vertex_attribute_t>::const_type>
+ make_vertex_attributes_writer(const Graph& g)
+ {
+ typedef typename property_map<Graph, vertex_attribute_t>::const_type
+ VertexAttributeMap;
+ return attributes_writer<VertexAttributeMap>(get(vertex_attribute, g));
+ }
+
+ template <typename Graph, typename VertexPropertiesWriter,
+ typename EdgePropertiesWriter, typename GraphPropertiesWriter,
+ typename VertexID>
+ inline void write_graphviz(std::ostream& out, const Graph& g,
+ VertexPropertiesWriter vpw,
+ EdgePropertiesWriter epw,
+ GraphPropertiesWriter gpw,
+ VertexID vertex_id)
+ {
+ typedef typename graph_traits<Graph>::directed_category cat_type;
+ typedef graphviz_io_traits<cat_type> Traits;
+ std::string name = "G";
+ out << Traits::name() << " " << name << " {" << std::endl;
+
+ gpw(out); //print graph properties
+
+ typename graph_traits<Graph>::vertex_iterator i, end;
+
+ for(tie(i,end) = vertices(g); i != end; ++i) {
+ out << get(vertex_id, *i);
+ vpw(out, *i); //print vertex attributes
+ out << ";" << std::endl;
+ }
+ typename graph_traits<Graph>::edge_iterator ei, edge_end;
+ for(tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) {
+ out << get(vertex_id, source(*ei, g)) << Traits::delimiter() << get(vertex_id, target(*ei, g)) << " ";
+ epw(out, *ei); //print edge attributes
+ out << ";" << std::endl;
+ }
+ out << "}" << std::endl;
+ }
+
+ template <typename Graph, typename VertexPropertiesWriter,
+ typename EdgePropertiesWriter, typename GraphPropertiesWriter>
+ inline void write_graphviz(std::ostream& out, const Graph& g,
+ VertexPropertiesWriter vpw,
+ EdgePropertiesWriter epw,
+ GraphPropertiesWriter gpw)
+ { write_graphviz(out, g, vpw, epw, gpw, get(vertex_index, g)); }
+
+#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
+ // ambiguous overload problem with VC++
+ template <typename Graph>
+ inline void
+ write_graphviz(std::ostream& out, const Graph& g) {
+ default_writer dw;
+ default_writer gw;
+ write_graphviz(out, g, dw, dw, gw);
+ }
+#endif
+
+ template <typename Graph, typename VertexWriter>
+ inline void
+ write_graphviz(std::ostream& out, const Graph& g, VertexWriter vw) {
+ default_writer dw;
+ default_writer gw;
+ write_graphviz(out, g, vw, dw, gw);
+ }
+
+ template <typename Graph, typename VertexWriter, typename EdgeWriter>
+ inline void
+ write_graphviz(std::ostream& out, const Graph& g,
+ VertexWriter vw, EdgeWriter ew) {
+ default_writer gw;
+ write_graphviz(out, g, vw, ew, gw);
+ }
+
+ namespace detail {
+
+ template <class Graph_, class RandomAccessIterator, class VertexID>
+ void write_graphviz_subgraph (std::ostream& out,
+ const subgraph<Graph_>& g,
+ RandomAccessIterator vertex_marker,
+ RandomAccessIterator edge_marker,
+ VertexID vertex_id)
+ {
+ typedef subgraph<Graph_> Graph;
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename graph_traits<Graph>::directed_category cat_type;
+ typedef graphviz_io_traits<cat_type> Traits;
+
+ typedef typename graph_property<Graph, graph_name_t>::type NameType;
+ const NameType& g_name = get_property(g, graph_name);
+
+ if ( g.is_root() )
+ out << Traits::name() ;
+ else
+ out << "subgraph";
+
+ out << " " << g_name << " {" << std::endl;
+
+ typename Graph::const_children_iterator i_child, j_child;
+
+ //print graph/node/edge attributes
+#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
+ typedef typename graph_property<Graph, graph_graph_attribute_t>::type
+ GAttrMap;
+ typedef typename graph_property<Graph, graph_vertex_attribute_t>::type
+ NAttrMap;
+ typedef typename graph_property<Graph, graph_edge_attribute_t>::type
+ EAttrMap;
+ GAttrMap gam = get_property(g, graph_graph_attribute);
+ NAttrMap nam = get_property(g, graph_vertex_attribute);
+ EAttrMap eam = get_property(g, graph_edge_attribute);
+ graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap> writer(gam, nam, eam);
+ writer(out);
+#else
+ make_graph_attributes_writer(g)(out);
+#endif
+
+ //print subgraph
+ for ( tie(i_child,j_child) = g.children();
+ i_child != j_child; ++i_child )
+ write_graphviz_subgraph(out, *i_child, vertex_marker, edge_marker,
+ vertex_id);
+
+ // Print out vertices and edges not in the subgraphs.
+
+ typename graph_traits<Graph>::vertex_iterator i, end;
+ typename graph_traits<Graph>::edge_iterator ei, edge_end;
+
+ for(tie(i,end) = vertices(g); i != end; ++i) {
+ Vertex v = g.local_to_global(*i);
+ int pos = get(vertex_id, v);
+ if ( vertex_marker[pos] ) {
+ vertex_marker[pos] = false;
+ out << pos;
+#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
+ typedef typename property_map<Graph, vertex_attribute_t>::const_type
+ VertexAttributeMap;
+ attributes_writer<VertexAttributeMap> vawriter(get(vertex_attribute,
+ g.root()));
+ vawriter(out, v);
+#else
+ make_vertex_attributes_writer(g.root())(out, v);
+#endif
+ out << ";" << std::endl;
+ }
+ }
+
+ for (tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) {
+ Vertex u = g.local_to_global(source(*ei,g)),
+ v = g.local_to_global(target(*ei, g));
+ int pos = get(get(edge_index, g.root()), g.local_to_global(*ei));
+ if ( edge_marker[pos] ) {
+ edge_marker[pos] = false;
+ out << get(vertex_id, u) << " " << Traits::delimiter()
+ << " " << get(vertex_id, v);
+#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
+ typedef typename property_map<Graph, edge_attribute_t>::const_type
+ EdgeAttributeMap;
+ attributes_writer<EdgeAttributeMap> eawriter(get(edge_attribute, g));
+ eawriter(out, *ei);
+#else
+ make_edge_attributes_writer(g)(out, *ei); //print edge properties
+#endif
+ out << ";" << std::endl;
+ }
+ }
+ out << "}" << std::endl;
+ }
+ } // namespace detail
+
+ // requires graph_name graph property
+ template <typename Graph>
+ void write_graphviz(std::ostream& out, const subgraph<Graph>& g) {
+ std::vector<bool> edge_marker(num_edges(g), true);
+ std::vector<bool> vertex_marker(num_vertices(g), true);
+
+ detail::write_graphviz_subgraph(out, g,
+ vertex_marker.begin(),
+ edge_marker.begin(),
+ get(vertex_index, g));
+ }
+
+ template <typename Graph>
+ void write_graphviz(const std::string& filename, const subgraph<Graph>& g) {
+ std::ofstream out(filename.c_str());
+ std::vector<bool> edge_marker(num_edges(g), true);
+ std::vector<bool> vertex_marker(num_vertices(g), true);
+
+ detail::write_graphviz_subgraph(out, g,
+ vertex_marker.begin(),
+ edge_marker.begin(),
+ get(vertex_index, g));
+ }
+
+ template <typename Graph, typename VertexID>
+ void write_graphviz(std::ostream& out, const subgraph<Graph>& g,
+ VertexID vertex_id)
+ {
+ std::vector<bool> edge_marker(num_edges(g), true);
+ std::vector<bool> vertex_marker(num_vertices(g), true);
+
+ detail::write_graphviz_subgraph(out, g,
+ vertex_marker.begin(),
+ edge_marker.begin(),
+ vertex_id);
+ }
+
+ template <typename Graph, typename VertexID>
+ void write_graphviz(const std::string& filename, const subgraph<Graph>& g,
+ VertexID vertex_id)
+ {
+ std::ofstream out(filename.c_str());
+ std::vector<bool> edge_marker(num_edges(g), true);
+ std::vector<bool> vertex_marker(num_vertices(g), true);
+
+ detail::write_graphviz_subgraph(out, g,
+ vertex_marker.begin(),
+ edge_marker.begin(),
+ vertex_id);
+ }
+
+ typedef std::map<std::string, std::string> GraphvizAttrList;
+
+ typedef property<vertex_attribute_t, GraphvizAttrList>
+ GraphvizVertexProperty;
+
+ typedef property<edge_attribute_t, GraphvizAttrList,
+ property<edge_index_t, int> >
+ GraphvizEdgeProperty;
+
+ typedef property<graph_graph_attribute_t, GraphvizAttrList,
+ property<graph_vertex_attribute_t, GraphvizAttrList,
+ property<graph_edge_attribute_t, GraphvizAttrList,
+ property<graph_name_t, std::string> > > >
+ GraphvizGraphProperty;
+
+ typedef subgraph<adjacency_list<vecS,
+ vecS, directedS,
+ GraphvizVertexProperty,
+ GraphvizEdgeProperty,
+ GraphvizGraphProperty> >
+ GraphvizDigraph;
+
+ typedef subgraph<adjacency_list<vecS,
+ vecS, undirectedS,
+ GraphvizVertexProperty,
+ GraphvizEdgeProperty,
+ GraphvizGraphProperty> >
+ GraphvizGraph;
+
+
+ // These four require linking the BGL-Graphviz library: libbgl-viz.a
+ // from the /src directory.
+ extern void read_graphviz(const std::string& file, GraphvizDigraph& g);
+ extern void read_graphviz(FILE* file, GraphvizDigraph& g);
+
+ extern void read_graphviz(const std::string& file, GraphvizGraph& g);
+ extern void read_graphviz(FILE* file, GraphvizGraph& g);
+
+ class dynamic_properties_writer
+ {
+ public:
+ dynamic_properties_writer(const dynamic_properties& dp) : dp(&dp) { }
+
+ template<typename Descriptor>
+ void operator()(std::ostream& out, Descriptor key) const
+ {
+ bool first = true;
+ for (dynamic_properties::const_iterator i = dp->begin();
+ i != dp->end(); ++i) {
+ if (typeid(key) == i->second->key()) {
+ if (first) out << " [";
+ else out << ", ";
+ first = false;
+
+ out << i->first << "=\"" << i->second->get_string(key) << "\"";
+ }
+ }
+
+ if (!first) out << "]";
+ }
+
+ private:
+ const dynamic_properties* dp;
+ };
+
+ class dynamic_vertex_properties_writer
+ {
+ public:
+ dynamic_vertex_properties_writer(const dynamic_properties& dp,
+ const std::string& node_id)
+ : dp(&dp), node_id(&node_id) { }
+
+ template<typename Descriptor>
+ void operator()(std::ostream& out, Descriptor key) const
+ {
+ bool first = true;
+ for (dynamic_properties::const_iterator i = dp->begin();
+ i != dp->end(); ++i) {
+ if (typeid(key) == i->second->key()
+ && i->first != *node_id) {
+ if (first) out << " [";
+ else out << ", ";
+ first = false;
+
+ out << i->first << "=\"" << i->second->get_string(key) << "\"";
+ }
+ }
+
+ if (!first) out << "]";
+ }
+
+ private:
+ const dynamic_properties* dp;
+ const std::string* node_id;
+ };
+
+ namespace graph { namespace detail {
+
+ template<typename Vertex>
+ struct node_id_property_map
+ {
+ typedef std::string value_type;
+ typedef value_type reference;
+ typedef Vertex key_type;
+ typedef readable_property_map_tag category;
+
+ node_id_property_map() {}
+
+ node_id_property_map(const dynamic_properties& dp,
+ const std::string& node_id)
+ : dp(&dp), node_id(&node_id) { }
+
+ const dynamic_properties* dp;
+ const std::string* node_id;
+ };
+
+ template<typename Vertex>
+ inline std::string
+ get(node_id_property_map<Vertex> pm,
+ typename node_id_property_map<Vertex>::key_type v)
+ { return get(*pm.node_id, *pm.dp, v); }
+
+ } } // end namespace graph::detail
+
+ template<typename Graph>
+ inline void
+ write_graphviz(std::ostream& out, const Graph& g,
+ const dynamic_properties& dp,
+ const std::string& node_id = "node_id")
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ write_graphviz(out, g, dp, node_id,
+ graph::detail::node_id_property_map<Vertex>(dp, node_id));
+ }
+
+ template<typename Graph, typename VertexID>
+ void
+ write_graphviz(std::ostream& out, const Graph& g,
+ const dynamic_properties& dp, const std::string& node_id,
+ VertexID id)
+ {
+ write_graphviz
+ (out, g,
+ /*vertex_writer=*/dynamic_vertex_properties_writer(dp, node_id),
+ /*edge_writer=*/dynamic_properties_writer(dp),
+ /*graph_writer=*/default_writer(),
+ id);
+ }
+
+/////////////////////////////////////////////////////////////////////////////
+// Graph reader exceptions
+/////////////////////////////////////////////////////////////////////////////
+struct graph_exception : public std::exception {
+ virtual ~graph_exception() throw() {}
+ virtual const char* what() const throw() = 0;
+};
+
+struct bad_parallel_edge : public graph_exception {
+ std::string from;
+ std::string to;
+ mutable std::string statement;
+ bad_parallel_edge(const std::string& i, const std::string& j) :
+ from(i), to(j) {}
+
+ virtual ~bad_parallel_edge() throw() {}
+ const char* what() const throw() {
+ if(statement.empty())
+ statement =
+ std::string("Failed to add parallel edge: (")
+ + from + "," + to + ")\n";
+
+ return statement.c_str();
+ }
+};
+
+struct directed_graph_error : public graph_exception {
+ virtual ~directed_graph_error() throw() {}
+ virtual const char* what() const throw() {
+ return
+ "read_graphviz: "
+ "Tried to read a directed graph into an undirected graph.";
+ }
+};
+
+struct undirected_graph_error : public graph_exception {
+ virtual ~undirected_graph_error() throw() {}
+ virtual const char* what() const throw() {
+ return
+ "read_graphviz: "
+ "Tried to read an undirected graph into a directed graph.";
+ }
+};
+
+namespace detail { namespace graph {
+
+typedef std::string id_t;
+typedef id_t node_t;
+
+// edges are not uniquely determined by adjacent nodes
+class edge_t {
+ int idx_;
+ explicit edge_t(int i) : idx_(i) {}
+public:
+ static edge_t new_edge() {
+ static int idx = 0;
+ return edge_t(idx++);
+ };
+
+ bool operator==(const edge_t& rhs) const {
+ return idx_ == rhs.idx_;
+ }
+ bool operator<(const edge_t& rhs) const {
+ return idx_ < rhs.idx_;
+ }
+};
+
+class mutate_graph
+{
+ public:
+ virtual ~mutate_graph() {}
+ virtual bool is_directed() const = 0;
+ virtual void do_add_vertex(const node_t& node) = 0;
+
+ virtual void
+ do_add_edge(const edge_t& edge, const node_t& source, const node_t& target)
+ = 0;
+
+ virtual void
+ set_node_property(const id_t& key, const node_t& node, const id_t& value) = 0;
+
+ virtual void
+ set_edge_property(const id_t& key, const edge_t& edge, const id_t& value) = 0;
+
+ virtual void // RG: need new second parameter to support BGL subgraphs
+ set_graph_property(const id_t& key, const id_t& value) = 0;
+};
+
+template<typename MutableGraph>
+class mutate_graph_impl : public mutate_graph
+{
+ typedef typename graph_traits<MutableGraph>::vertex_descriptor bgl_vertex_t;
+ typedef typename graph_traits<MutableGraph>::edge_descriptor bgl_edge_t;
+
+ public:
+ mutate_graph_impl(MutableGraph& graph, dynamic_properties& dp,
+ std::string node_id_prop)
+ : graph_(graph), dp_(dp), node_id_prop_(node_id_prop) { }
+
+ ~mutate_graph_impl() {}
+
+ bool is_directed() const
+ {
+ return
+ boost::is_convertible<
+ typename boost::graph_traits<MutableGraph>::directed_category,
+ boost::directed_tag>::value;
+ }
+
+ virtual void do_add_vertex(const node_t& node)
+ {
+ // Add the node to the graph.
+ bgl_vertex_t v = add_vertex(graph_);
+
+ // Set up a mapping from name to BGL vertex.
+ bgl_nodes.insert(std::make_pair(node, v));
+
+ // node_id_prop_ allows the caller to see the real id names for nodes.
+ put(node_id_prop_, dp_, v, node);
+ }
+
+ void
+ do_add_edge(const edge_t& edge, const node_t& source, const node_t& target)
+ {
+ std::pair<bgl_edge_t, bool> result =
+ add_edge(bgl_nodes[source], bgl_nodes[target], graph_);
+
+ if(!result.second) {
+ // In the case of no parallel edges allowed
+ throw bad_parallel_edge(source, target);
+ } else {
+ bgl_edges.insert(std::make_pair(edge, result.first));
+ }
+ }
+
+ void
+ set_node_property(const id_t& key, const node_t& node, const id_t& value)
+ {
+ put(key, dp_, bgl_nodes[node], value);
+ }
+
+ void
+ set_edge_property(const id_t& key, const edge_t& edge, const id_t& value)
+ {
+ put(key, dp_, bgl_edges[edge], value);
+ }
+
+ void
+ set_graph_property(const id_t& key, const id_t& value)
+ {
+ /* RG: pointer to graph prevents copying */
+ put(key, dp_, &graph_, value);
+ }
+
+
+ protected:
+ MutableGraph& graph_;
+ dynamic_properties& dp_;
+ std::string node_id_prop_;
+ std::map<node_t, bgl_vertex_t> bgl_nodes;
+ std::map<edge_t, bgl_edge_t> bgl_edges;
+};
+
+BOOST_GRAPH_DECL
+bool read_graphviz(std::istream& in, mutate_graph& graph);
+
+} } // end namespace detail::graph
+
+// Parse the passed stream as a GraphViz dot file.
+template <typename MutableGraph>
+bool read_graphviz(std::istream& in, MutableGraph& graph,
+ dynamic_properties& dp,
+ std::string const& node_id = "node_id")
+{
+ detail::graph::mutate_graph_impl<MutableGraph> m_graph(graph, dp, node_id);
+ return detail::graph::read_graphviz(in, m_graph);
+}
+
+} // namespace boost
+
+#ifdef BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS
+# include <boost/graph/detail/read_graphviz_spirit.hpp>
+#endif // BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS
+
+#endif // BOOST_GRAPHVIZ_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/gursoy_atun_layout.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/gursoy_atun_layout.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,631 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// 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)
+
+// Authors: Jeremiah Willcock
+// Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP
+#define BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP
+
+// Gursoy-Atun graph layout, based on:
+// "Neighbourhood Preserving Load Balancing: A Self-Organizing Approach"
+// in EuroPar 2000, p. 234 of LNCS 1900
+// http://springerlink.metapress.com/link.asp?id=pcu07ew5rhexp9yt
+
+#include <cmath>
+#include <vector>
+#include <exception>
+#include <algorithm>
+
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/named_function_params.hpp>
+
+namespace boost {
+
+namespace detail {
+
+struct over_distance_limit : public std::exception {};
+
+template <typename PositionMap, typename NodeDistanceMap, typename Topology,
+ typename Graph>
+struct update_position_visitor {
+ typedef typename Topology::point_type Point;
+ PositionMap position_map;
+ NodeDistanceMap node_distance;
+ const Topology& space;
+ Point input_vector;
+ double distance_limit;
+ double learning_constant;
+ double falloff_ratio;
+
+ typedef boost::on_examine_vertex event_filter;
+
+ typedef typename graph_traits<Graph>::vertex_descriptor
+ vertex_descriptor;
+
+ update_position_visitor(PositionMap position_map,
+ NodeDistanceMap node_distance,
+ const Topology& space,
+ const Point& input_vector,
+ double distance_limit,
+ double learning_constant,
+ double falloff_ratio):
+ position_map(position_map), node_distance(node_distance),
+ space(space),
+ input_vector(input_vector), distance_limit(distance_limit),
+ learning_constant(learning_constant), falloff_ratio(falloff_ratio) {}
+
+ void operator()(vertex_descriptor v, const Graph&) const
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::pow;
+#endif
+
+ if (get(node_distance, v) > distance_limit)
+ throw over_distance_limit();
+ Point old_position = get(position_map, v);
+ double distance = get(node_distance, v);
+ double fraction =
+ learning_constant * pow(falloff_ratio, distance * distance);
+ put(position_map, v,
+ space.move_position_toward(old_position, fraction, input_vector));
+ }
+};
+
+template<typename EdgeWeightMap>
+struct gursoy_shortest
+{
+ template<typename Graph, typename NodeDistanceMap, typename UpdatePosition>
+ static inline void
+ run(const Graph& g, typename graph_traits<Graph>::vertex_descriptor s,
+ NodeDistanceMap node_distance, UpdatePosition& update_position,
+ EdgeWeightMap weight)
+ {
+ boost::dijkstra_shortest_paths(g, s, weight_map(weight).
+ visitor(boost::make_dijkstra_visitor(std::make_pair(
+ boost::record_distances(node_distance, boost::on_edge_relaxed()),
+ update_position))));
+ }
+};
+
+template<>
+struct gursoy_shortest<dummy_property_map>
+{
+ template<typename Graph, typename NodeDistanceMap, typename UpdatePosition>
+ static inline void
+ run(const Graph& g, typename graph_traits<Graph>::vertex_descriptor s,
+ NodeDistanceMap node_distance, UpdatePosition& update_position,
+ dummy_property_map)
+ {
+ boost::breadth_first_search(g, s,
+ visitor(boost::make_bfs_visitor(std::make_pair(
+ boost::record_distances(node_distance, boost::on_tree_edge()),
+ update_position))));
+ }
+};
+
+} // namespace detail
+
+template <typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap, typename Diameter, typename VertexIndexMap,
+ typename EdgeWeightMap>
+void
+gursoy_atun_step
+ (const VertexListAndIncidenceGraph& graph,
+ const Topology& space,
+ PositionMap position,
+ Diameter diameter,
+ double learning_constant,
+ VertexIndexMap vertex_index_map,
+ EdgeWeightMap weight)
+{
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::pow;
+ using std::exp;
+#endif
+
+ typedef typename graph_traits<VertexListAndIncidenceGraph>::vertex_iterator
+ vertex_iterator;
+ typedef typename graph_traits<VertexListAndIncidenceGraph>::vertex_descriptor
+ vertex_descriptor;
+ typedef typename Topology::point_type point_type;
+ vertex_iterator i, iend;
+ std::vector<double> distance_from_input_vector(num_vertices(graph));
+ typedef boost::iterator_property_map<std::vector<double>::iterator,
+ VertexIndexMap,
+ double, double&>
+ DistanceFromInputMap;
+ DistanceFromInputMap distance_from_input(distance_from_input_vector.begin(),
+ vertex_index_map);
+ std::vector<double> node_distance_map_vector(num_vertices(graph));
+ typedef boost::iterator_property_map<std::vector<double>::iterator,
+ VertexIndexMap,
+ double, double&>
+ NodeDistanceMap;
+ NodeDistanceMap node_distance(node_distance_map_vector.begin(),
+ vertex_index_map);
+ point_type input_vector = space.random_point();
+ vertex_descriptor min_distance_loc
+ = graph_traits<VertexListAndIncidenceGraph>::null_vertex();
+ double min_distance = 0.0;
+ bool min_distance_unset = true;
+ for (boost::tie(i, iend) = vertices(graph); i != iend; ++i) {
+ double this_distance = space.distance(get(position, *i), input_vector);
+ put(distance_from_input, *i, this_distance);
+ if (min_distance_unset || this_distance < min_distance) {
+ min_distance = this_distance;
+ min_distance_loc = *i;
+ }
+ min_distance_unset = false;
+ }
+ assert (!min_distance_unset); // Graph must have at least one vertex
+ boost::detail::update_position_visitor<
+ PositionMap, NodeDistanceMap, Topology,
+ VertexListAndIncidenceGraph>
+ update_position(position, node_distance, space,
+ input_vector, diameter, learning_constant,
+ exp(-1. / (2 * diameter * diameter)));
+ std::fill(node_distance_map_vector.begin(), node_distance_map_vector.end(), 0);
+ try {
+ typedef detail::gursoy_shortest<EdgeWeightMap> shortest;
+ shortest::run(graph, min_distance_loc, node_distance, update_position,
+ weight);
+ } catch (detail::over_distance_limit) {
+ /* Thrown to break out of BFS or Dijkstra early */
+ }
+}
+
+template <typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap, typename VertexIndexMap,
+ typename EdgeWeightMap>
+void gursoy_atun_refine(const VertexListAndIncidenceGraph& graph,
+ const Topology& space,
+ PositionMap position,
+ int nsteps,
+ double diameter_initial,
+ double diameter_final,
+ double learning_constant_initial,
+ double learning_constant_final,
+ VertexIndexMap vertex_index_map,
+ EdgeWeightMap weight)
+{
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::pow;
+ using std::exp;
+#endif
+
+ typedef typename graph_traits<VertexListAndIncidenceGraph>::vertex_iterator
+ vertex_iterator;
+ typedef typename graph_traits<VertexListAndIncidenceGraph>::vertex_descriptor
+ vertex_descriptor;
+ typedef typename Topology::point_type point_type;
+ vertex_iterator i, iend;
+ double diameter_ratio = (double)diameter_final / diameter_initial;
+ double learning_constant_ratio =
+ learning_constant_final / learning_constant_initial;
+ std::vector<double> distance_from_input_vector(num_vertices(graph));
+ typedef boost::iterator_property_map<std::vector<double>::iterator,
+ VertexIndexMap,
+ double, double&>
+ DistanceFromInputMap;
+ DistanceFromInputMap distance_from_input(distance_from_input_vector.begin(),
+ vertex_index_map);
+ std::vector<int> node_distance_map_vector(num_vertices(graph));
+ typedef boost::iterator_property_map<std::vector<int>::iterator,
+ VertexIndexMap, double, double&>
+ NodeDistanceMap;
+ NodeDistanceMap node_distance(node_distance_map_vector.begin(),
+ vertex_index_map);
+ for (int round = 0; round < nsteps; ++round) {
+ double part_done = (double)round / (nsteps - 1);
+ int diameter = (int)(diameter_initial * pow(diameter_ratio, part_done));
+ double learning_constant =
+ learning_constant_initial * pow(learning_constant_ratio, part_done);
+ gursoy_atun_step(graph, space, position, diameter, learning_constant,
+ vertex_index_map, weight);
+ }
+}
+
+template <typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap, typename VertexIndexMap,
+ typename EdgeWeightMap>
+void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
+ const Topology& space,
+ PositionMap position,
+ int nsteps,
+ double diameter_initial,
+ double diameter_final,
+ double learning_constant_initial,
+ double learning_constant_final,
+ VertexIndexMap vertex_index_map,
+ EdgeWeightMap weight)
+{
+ typedef typename graph_traits<VertexListAndIncidenceGraph>::vertex_iterator
+ vertex_iterator;
+ vertex_iterator i, iend;
+ for (boost::tie(i, iend) = vertices(graph); i != iend; ++i) {
+ put(position, *i, space.random_point());
+ }
+ gursoy_atun_refine(graph, space,
+ position, nsteps,
+ diameter_initial, diameter_final,
+ learning_constant_initial, learning_constant_final,
+ vertex_index_map, weight);
+}
+
+template <typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap, typename VertexIndexMap>
+void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
+ const Topology& space,
+ PositionMap position,
+ int nsteps,
+ double diameter_initial,
+ double diameter_final,
+ double learning_constant_initial,
+ double learning_constant_final,
+ VertexIndexMap vertex_index_map)
+{
+ gursoy_atun_layout(graph, space, position, nsteps,
+ diameter_initial, diameter_final,
+ learning_constant_initial, learning_constant_final,
+ vertex_index_map, dummy_property_map());
+}
+
+template <typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap>
+void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
+ const Topology& space,
+ PositionMap position,
+ int nsteps,
+ double diameter_initial,
+ double diameter_final = 1.0,
+ double learning_constant_initial = 0.8,
+ double learning_constant_final = 0.2)
+{
+ gursoy_atun_layout(graph, space, position, nsteps, diameter_initial,
+ diameter_final, learning_constant_initial,
+ learning_constant_final, get(vertex_index, graph));
+}
+
+template <typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap>
+void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
+ const Topology& space,
+ PositionMap position,
+ int nsteps)
+{
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif
+
+ gursoy_atun_layout(graph, space, position, nsteps,
+ sqrt((double)num_vertices(graph)));
+}
+
+template <typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap>
+void gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
+ const Topology& space,
+ PositionMap position)
+{
+ gursoy_atun_layout(graph, space, position, num_vertices(graph));
+}
+
+template<typename VertexListAndIncidenceGraph, typename Topology,
+ typename PositionMap, typename P, typename T, typename R>
+void
+gursoy_atun_layout(const VertexListAndIncidenceGraph& graph,
+ const Topology& space,
+ PositionMap position,
+ const bgl_named_params<P,T,R>& params)
+{
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif
+
+ std::pair<double, double> diam(sqrt(double(num_vertices(graph))), 1.0);
+ std::pair<double, double> learn(0.8, 0.2);
+ gursoy_atun_layout(graph, space, position,
+ choose_param(get_param(params, iterations_t()),
+ num_vertices(graph)),
+ choose_param(get_param(params, diameter_range_t()),
+ diam).first,
+ choose_param(get_param(params, diameter_range_t()),
+ diam).second,
+ choose_param(get_param(params, learning_constant_range_t()),
+ learn).first,
+ choose_param(get_param(params, learning_constant_range_t()),
+ learn).second,
+ choose_const_pmap(get_param(params, vertex_index), graph,
+ vertex_index),
+ choose_param(get_param(params, edge_weight),
+ dummy_property_map()));
+}
+
+/***********************************************************
+ * Topologies *
+ ***********************************************************/
+template<std::size_t Dims>
+class convex_topology
+{
+ struct point
+ {
+ point() { }
+ double& operator[](std::size_t i) {return values[i];}
+ const double& operator[](std::size_t i) const {return values[i];}
+
+ private:
+ double values[Dims];
+ };
+
+ public:
+ typedef point point_type;
+
+ double distance(point a, point b) const
+ {
+ double dist = 0;
+ for (std::size_t i = 0; i < Dims; ++i) {
+ double diff = b[i] - a[i];
+ dist += diff * diff;
+ }
+ // Exact properties of the distance are not important, as long as
+ // < on what this returns matches real distances
+ return dist;
+ }
+
+ point move_position_toward(point a, double fraction, point b) const
+ {
+ point result;
+ for (std::size_t i = 0; i < Dims; ++i)
+ result[i] = a[i] + (b[i] - a[i]) * fraction;
+ return result;
+ }
+};
+
+template<std::size_t Dims,
+ typename RandomNumberGenerator = minstd_rand>
+class hypercube_topology : public convex_topology<Dims>
+{
+ typedef uniform_01<RandomNumberGenerator, double> rand_t;
+
+ public:
+ typedef typename convex_topology<Dims>::point_type point_type;
+
+ explicit hypercube_topology(double scaling = 1.0)
+ : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)),
+ scaling(scaling)
+ { }
+
+ hypercube_topology(RandomNumberGenerator& gen, double scaling = 1.0)
+ : gen_ptr(), rand(new rand_t(gen)), scaling(scaling) { }
+
+ point_type random_point() const
+ {
+ point_type p;
+ for (std::size_t i = 0; i < Dims; ++i)
+ p[i] = (*rand)() * scaling;
+ return p;
+ }
+
+ private:
+ shared_ptr<RandomNumberGenerator> gen_ptr;
+ shared_ptr<rand_t> rand;
+ double scaling;
+};
+
+template<typename RandomNumberGenerator = minstd_rand>
+class square_topology : public hypercube_topology<2, RandomNumberGenerator>
+{
+ typedef hypercube_topology<2, RandomNumberGenerator> inherited;
+
+ public:
+ explicit square_topology(double scaling = 1.0) : inherited(scaling) { }
+
+ square_topology(RandomNumberGenerator& gen, double scaling = 1.0)
+ : inherited(gen, scaling) { }
+};
+
+template<typename RandomNumberGenerator = minstd_rand>
+class cube_topology : public hypercube_topology<3, RandomNumberGenerator>
+{
+ typedef hypercube_topology<3, RandomNumberGenerator> inherited;
+
+ public:
+ explicit cube_topology(double scaling = 1.0) : inherited(scaling) { }
+
+ cube_topology(RandomNumberGenerator& gen, double scaling = 1.0)
+ : inherited(gen, scaling) { }
+};
+
+template<std::size_t Dims,
+ typename RandomNumberGenerator = minstd_rand>
+class ball_topology : public convex_topology<Dims>
+{
+ typedef uniform_01<RandomNumberGenerator, double> rand_t;
+
+ public:
+ typedef typename convex_topology<Dims>::point_type point_type;
+
+ explicit ball_topology(double radius = 1.0)
+ : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)),
+ radius(radius)
+ { }
+
+ ball_topology(RandomNumberGenerator& gen, double radius = 1.0)
+ : gen_ptr(), rand(new rand_t(gen)), radius(radius) { }
+
+ point_type random_point() const
+ {
+ point_type p;
+ double dist_sum;
+ do {
+ dist_sum = 0.0;
+ for (std::size_t i = 0; i < Dims; ++i) {
+ double x = (*rand)() * 2*radius - radius;
+ p[i] = x;
+ dist_sum += x * x;
+ }
+ } while (dist_sum > radius*radius);
+ return p;
+ }
+
+ private:
+ shared_ptr<RandomNumberGenerator> gen_ptr;
+ shared_ptr<rand_t> rand;
+ double radius;
+};
+
+template<typename RandomNumberGenerator = minstd_rand>
+class circle_topology : public ball_topology<2, RandomNumberGenerator>
+{
+ typedef ball_topology<2, RandomNumberGenerator> inherited;
+
+ public:
+ explicit circle_topology(double radius = 1.0) : inherited(radius) { }
+
+ circle_topology(RandomNumberGenerator& gen, double radius = 1.0)
+ : inherited(gen, radius) { }
+};
+
+template<typename RandomNumberGenerator = minstd_rand>
+class sphere_topology : public ball_topology<3, RandomNumberGenerator>
+{
+ typedef ball_topology<3, RandomNumberGenerator> inherited;
+
+ public:
+ explicit sphere_topology(double radius = 1.0) : inherited(radius) { }
+
+ sphere_topology(RandomNumberGenerator& gen, double radius = 1.0)
+ : inherited(gen, radius) { }
+};
+
+template<typename RandomNumberGenerator = minstd_rand>
+class heart_topology
+{
+ // Heart is defined as the union of three shapes:
+ // Square w/ corners (+-1000, -1000), (0, 0), (0, -2000)
+ // Circle centered at (-500, -500) radius 500*sqrt(2)
+ // Circle centered at (500, -500) radius 500*sqrt(2)
+ // Bounding box (-1000, -2000) - (1000, 500*(sqrt(2) - 1))
+
+ struct point
+ {
+ point() { values[0] = 0.0; values[1] = 0.0; }
+ point(double x, double y) { values[0] = x; values[1] = y; }
+
+ double& operator[](std::size_t i) { return values[i]; }
+ double operator[](std::size_t i) const { return values[i]; }
+
+ private:
+ double values[2];
+ };
+
+ bool in_heart(point p) const
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::abs;
+ using std::pow;
+#endif
+
+ if (p[1] < abs(p[0]) - 2000) return false; // Bottom
+ if (p[1] <= -1000) return true; // Diagonal of square
+ if (pow(p[0] - -500, 2) + pow(p[1] - -500, 2) <= 500000)
+ return true; // Left circle
+ if (pow(p[0] - 500, 2) + pow(p[1] - -500, 2) <= 500000)
+ return true; // Right circle
+ return false;
+ }
+
+ bool segment_within_heart(point p1, point p2) const
+ {
+ // Assumes that p1 and p2 are within the heart
+ if ((p1[0] < 0) == (p2[0] < 0)) return true; // Same side of symmetry line
+ if (p1[0] == p2[0]) return true; // Vertical
+ double slope = (p2[1] - p1[1]) / (p2[0] - p1[0]);
+ double intercept = p1[1] - p1[0] * slope;
+ if (intercept > 0) return false; // Crosses between circles
+ return true;
+ }
+
+ typedef uniform_01<RandomNumberGenerator, double> rand_t;
+
+ public:
+ typedef point point_type;
+
+ heart_topology()
+ : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)) { }
+
+ heart_topology(RandomNumberGenerator& gen)
+ : gen_ptr(), rand(new rand_t(gen)) { }
+
+ point random_point() const
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif
+
+ point result;
+ double sqrt2 = sqrt(2.);
+ do {
+ result[0] = (*rand)() * (1000 + 1000 * sqrt2) - (500 + 500 * sqrt2);
+ result[1] = (*rand)() * (2000 + 500 * (sqrt2 - 1)) - 2000;
+ } while (!in_heart(result));
+ return result;
+ }
+
+ double distance(point a, point b) const
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif
+ if (segment_within_heart(a, b)) {
+ // Straight line
+ return sqrt((b[0] - a[0]) * (b[0] - a[0]) + (b[1] - a[1]) * (b[1] - a[1]));
+ } else {
+ // Straight line bending around (0, 0)
+ return sqrt(a[0] * a[0] + a[1] * a[1]) + sqrt(b[0] * b[0] + b[1] * b[1]);
+ }
+ }
+
+ point move_position_toward(point a, double fraction, point b) const
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif
+
+ if (segment_within_heart(a, b)) {
+ // Straight line
+ return point(a[0] + (b[0] - a[0]) * fraction,
+ a[1] + (b[1] - a[1]) * fraction);
+ } else {
+ double distance_to_point_a = sqrt(a[0] * a[0] + a[1] * a[1]);
+ double distance_to_point_b = sqrt(b[0] * b[0] + b[1] * b[1]);
+ double location_of_point = distance_to_point_a /
+ (distance_to_point_a + distance_to_point_b);
+ if (fraction < location_of_point)
+ return point(a[0] * (1 - fraction / location_of_point),
+ a[1] * (1 - fraction / location_of_point));
+ else
+ return point(
+ b[0] * ((fraction - location_of_point) / (1 - location_of_point)),
+ b[1] * ((fraction - location_of_point) / (1 - location_of_point)));
+ }
+ }
+
+ private:
+ shared_ptr<RandomNumberGenerator> gen_ptr;
+ shared_ptr<rand_t> rand;
+};
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/howard_cycle_ratio.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/howard_cycle_ratio.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,611 @@
+/*!
+* Copyright 2007 Technical University of Catalonia
+*
+* Use, modification and distribution is subject to 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)
+*
+* Authors: Dmitry Bufistov
+* Andrey Parfenov
+*/
+
+#ifndef BOOST_GRAPH_HOWARD_CYCLE_RATIO_HOWARD_HPP
+#define BOOST_GRAPH_HOWARD_CYCLE_RATIO_HOWARD_HPP
+
+/*!
+* \file Maximum cycle ratio algorithm (Jean Cochet-Terrasson, Guy
+* Cochen and others)
+*/
+#include <exception>
+#include <set>
+#include <boost/bind.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/is_signed.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/reverse_graph.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/iteration_macros.hpp>
+
+namespace boost {
+ namespace detail {
+ /// To avoid round error.
+ static const double mcr_howard_ltolerance = 0.00001;
+
+ /*!
+ * Calculate maximum cycle ratio of "good" directed multigraph
+ * g. Use Howard's iteration policy algorithm ("Numerical
+ * Computation of Spectral Elements in MAX-PLUS algebra" by Jean
+ * Cochet-Terrasson, Guy Cochen and others).
+ *
+ * \param g = (V, E) - a "good" directed multigraph (out_degree of
+ * each vertex is greater then 0). If graph is strongly connected
+ * then it is "good".
+ *
+ * \param vim - Vertex Index, read property Map: V -> [0,
+ * num_vertices(g)).
+ *
+ * \param ewm - edge weight read property map: E -> R
+ *
+ * \param ewm2 - edge weight2 read property map: E -> R+
+ *
+ * \return maximum_{for all cycles C}CR(C), or
+ * -(std::numeric_limits<double>)::max() if g is not "good".
+ */
+ template <typename TGraph, typename TVertexIndexMap,
+ typename TWeight1EdgeMap, typename TWeight2EdgeMap >
+ class Cmcr_Howard
+ {
+ public:
+ Cmcr_Howard(const TGraph& g, TVertexIndexMap vim, TWeight1EdgeMap ewm,
+ TWeight2EdgeMap ew2m)
+ : m_g(g), m_vim(vim), m_ew1m(ewm), m_ew2m(ew2m),
+ m_g2pi_g_vm(std::vector<pi_vertex_t>().end(), m_vim), /// Stupid dummy initialization
+ m_minus_infinity(-(std::numeric_limits<double>::max)())
+ {
+ typedef typename boost::graph_traits<TGraph>::directed_category DirCat;
+ BOOST_STATIC_ASSERT((boost::is_convertible<DirCat*, boost::directed_tag*>::value == true));
+ m_cr = m_minus_infinity;
+ }
+
+ double operator()()
+ {
+ return maximum_cycle_ratio_Howard();
+ }
+
+ virtual ~Cmcr_Howard() { }
+
+ protected:
+ typedef typename boost::graph_traits<TGraph>::vertex_descriptor
+ mcr_vertex_t;
+ typedef typename boost::graph_traits<TGraph>::edge_descriptor
+ mcr_edge_t;
+
+ const TGraph& m_g;
+ typedef std::vector<double> eigenmode_t;
+ eigenmode_t m_eigen_value;
+ eigenmode_t m_eigen_vector;
+ TVertexIndexMap m_vim;
+ TWeight1EdgeMap m_ew1m;
+ TWeight2EdgeMap m_ew2m;
+
+ typedef typename boost::remove_const<typename boost::property_traits<TWeight1EdgeMap>::value_type>::type mcr_edge_weight1_t;
+ typedef typename boost::remove_const<typename boost::property_traits<TWeight2EdgeMap>::value_type>::type mcr_edge_weight2_t;
+ typedef typename boost::adjacency_list<
+ boost::listS, boost::vecS, boost::bidirectionalS,
+ boost::no_property,
+ boost::property<boost::edge_weight_t,
+ mcr_edge_weight1_t,
+ boost::property<boost::edge_weight2_t,
+ mcr_edge_weight2_t> > >
+ pi_graph_t;
+ typedef typename boost::property_map<pi_graph_t, boost::vertex_index_t>::type TPiGraphVertexIndexMap;
+ typedef typename boost::property_map<pi_graph_t, boost::edge_weight_t>::type TPiGraphEdgeWeight1Map;
+ typedef typename boost::property_map<pi_graph_t, boost::edge_weight2_t>::type TPiGraphEdgeWeight2Map;
+
+ typedef typename boost::property_traits<TPiGraphVertexIndexMap>::value_type pigraph_vertex_index_t;
+
+ pi_graph_t m_pi_g;
+ typedef typename boost::graph_traits<pi_graph_t>::vertex_descriptor pi_vertex_t;
+ typedef typename boost::graph_traits<pi_graph_t>::edge_descriptor pi_edge_t;
+ typedef typename boost::iterator_property_map<typename std::vector<pi_vertex_t>::iterator, TVertexIndexMap> g2pi_g_vm_t;
+ g2pi_g_vm_t m_g2pi_g_vm; ///Graph to Pi graph vertex map
+ std::vector<pi_vertex_t> m_g2pig;
+ int m_step_number;
+ const double m_minus_infinity;
+ typedef typename std::vector<mcr_edge_t> critical_cycle_t;
+ double m_cr; ///Cycle ratio that already has been found
+
+ class bad_graph
+ {
+ public:
+ typedef typename boost::property_traits<TVertexIndexMap>::value_type
+ v_index_t;
+
+ bad_graph(v_index_t bvi) : bad_vertex_index(bvi) {}
+ v_index_t what() const throw()
+ {
+ return bad_vertex_index;
+ }
+
+ private:
+ v_index_t bad_vertex_index;
+ };
+
+ double maximum_cycle_ratio_Howard()
+ {
+ try
+ {
+ construct_pi_graph();
+ }
+ catch (const bad_graph& a)
+ {
+ return m_minus_infinity;
+ }
+ std::vector<double> max_eigen_val(boost::num_vertices(m_g));
+ m_eigen_value.resize(boost::num_vertices(m_g));
+ m_eigen_vector.resize(boost::num_vertices(m_g));
+ m_step_number = 0;
+ do
+ {
+ pi_eingen_value(get(vertex_index, m_pi_g), get(boost::edge_weight, m_pi_g), get(boost::edge_weight2, m_pi_g));
+ ++m_step_number;
+ }
+ while (improve_policy_try1(max_eigen_val) || improve_policy_try2(max_eigen_val));
+ return *(std::max_element(m_eigen_value.begin(), m_eigen_value.end()));
+ }
+
+ /*!
+ * Construct an arbitrary policy m_pi_g.
+ */
+ void construct_pi_graph()
+ {
+ m_g2pig.resize(boost::num_vertices(m_g));
+ m_g2pi_g_vm = boost::make_iterator_property_map(m_g2pig.begin(), m_vim);
+ BGL_FORALL_VERTICES_T(vd, m_g, TGraph)
+ {
+ m_g2pi_g_vm[vd] = boost::add_vertex(m_pi_g);
+ store_pivertex(m_g2pi_g_vm[vd], vd);
+ }
+ BGL_FORALL_VERTICES_T(vd1, m_g, TGraph)
+ {
+ if (boost::out_edges(vd1, m_g).first == boost::out_edges(vd1, m_g).second) throw bad_graph(m_vim[vd1]);
+ mcr_edge_t ed = *boost::out_edges(vd1, m_g).first;
+ pi_edge_t pied = boost::add_edge(m_g2pi_g_vm[source(ed, m_g)], m_g2pi_g_vm[target(ed, m_g)], m_pi_g).first;
+ boost::put(boost::edge_weight, m_pi_g, pied, m_ew1m[ed]);
+ boost::put(boost::edge_weight2, m_pi_g, pied, m_ew2m[ed]);
+ }
+ }
+
+ class bfs_eingmode_visitor : public boost::default_bfs_visitor
+ {
+ public:
+ bfs_eingmode_visitor(TPiGraphVertexIndexMap vi_m, TPiGraphEdgeWeight1Map w_m, TPiGraphEdgeWeight2Map& d_m,
+ eigenmode_t& e_val, eigenmode_t& e_vec, double ev) : m_index_map(vi_m), m_weight_map(w_m), m_delay_map(d_m),
+ m_eig_value(&e_val), m_eig_vec(&e_vec), m_eigen_value(ev) { }
+
+ template < typename Edge, typename g_t>
+ void examine_edge(Edge e, const g_t & g) const
+ {
+ typedef typename boost::graph_traits<g_t>::vertex_descriptor Vertex;
+ Vertex u = boost::target(e, g), v = boost::source(e, g);
+ pigraph_vertex_index_t ind = m_index_map[u];
+ (*m_eig_value)[ind] = m_eigen_value;
+ (*m_eig_vec)[ind] = m_weight_map[e] - m_eigen_value * m_delay_map[e] + (*m_eig_vec)[m_index_map[v]];
+ }
+ private:
+ TPiGraphVertexIndexMap m_index_map;
+ TPiGraphEdgeWeight1Map m_weight_map;
+ TPiGraphEdgeWeight2Map m_delay_map;
+ eigenmode_t* m_eig_value;
+ eigenmode_t* m_eig_vec;
+ double m_eigen_value;
+ };
+
+ /*!
+ * Find a vertex in the Pi Graph which belongs to cycle, just a DFV until back edge found
+ */
+ pi_vertex_t find_good_source(const pi_vertex_t start_vertex)
+ {
+ pi_vertex_t good_vertex = start_vertex;
+ typename std::set<pi_vertex_t> s;
+ s.insert(start_vertex);
+ do
+ {
+ good_vertex = boost::target(*boost::out_edges(good_vertex, m_pi_g).first, m_pi_g);
+ }
+ while (s.insert(good_vertex).second);
+ return good_vertex;
+ }
+ virtual void store_pivertex(pi_vertex_t pivd, mcr_vertex_t vd) {}
+ virtual void store_critical_edge(pi_edge_t ed, critical_cycle_t& cc) {}
+ virtual void store_critical_cycle(critical_cycle_t& cc) {}
+
+ /*!
+ * \param startV - vertex that belongs to a cycle in policy graph m_pi_g
+ */
+ double calculate_eigen_value(pi_vertex_t startV)
+ {
+ std::pair<double, double> accum_sums(0., 0.);
+ pi_vertex_t vd = startV;
+ critical_cycle_t cc;
+ do
+ {
+ pi_edge_t tmp_ed = *(boost::out_edges(vd, m_pi_g).first);
+ store_critical_edge(tmp_ed, cc);
+ accum_sums.first += boost::get(boost::edge_weight, m_pi_g, tmp_ed);
+ accum_sums.second += boost::get(boost::edge_weight2, m_pi_g, tmp_ed);
+ vd = boost::target(tmp_ed, m_pi_g);
+ }
+ while (vd != startV);
+ //assert((std::abs<double>(accum_sums.first) <= 0.00000001) && "Division by zerro!");
+ double cr = accum_sums.first / accum_sums.second;
+ if (cr > m_cr)
+ {
+ m_cr = cr;
+ store_critical_cycle(cc);
+ }
+ else
+ {
+
+ }
+ return cr;
+ }
+
+ /*!
+ * Value determination. Find a generalized eigenmode (n^{k+1}, x^{k+1}) of A^{Ï_{k+1}} of the pi graph (Algorithm IV.1).
+ */
+ void pi_eingen_value(
+ TPiGraphVertexIndexMap index_map,
+ TPiGraphEdgeWeight1Map weight_map,
+ TPiGraphEdgeWeight2Map weigh2_map)
+ {
+ using namespace boost;
+ typedef std::vector<default_color_type> color_map_t;
+ color_map_t vcm(num_vertices(m_pi_g), white_color);//Vertex color map
+ color_map_t::iterator uv_itr = vcm.begin(); //Undiscovered vertex
+ reverse_graph<pi_graph_t> rev_g(m_pi_g); //For backward breadth visit
+
+ while ((uv_itr = std::find_if(uv_itr, vcm.end(),
+ boost::bind(std::equal_to<default_color_type>(), boost::white_color, _1))) != vcm.end())
+ ///While there are undiscovered vertices
+ {
+ pi_vertex_t gv = find_good_source(pi_vertex_t(uv_itr - vcm.begin()));
+ pigraph_vertex_index_t gv_ind = index_map[gv];
+ m_eigen_value[gv_ind] = calculate_eigen_value(gv) ;
+ bfs_eingmode_visitor bfs_vis(index_map, weight_map, weigh2_map, m_eigen_value, m_eigen_vector, m_eigen_value[gv_ind]);
+ typename boost::queue<pi_vertex_t> Q;
+ breadth_first_visit(rev_g, gv, Q, bfs_vis, make_iterator_property_map(vcm.begin(), index_map));
+ }
+ }
+
+ void improve_policy(mcr_vertex_t vd, mcr_edge_t new_edge)
+ {
+ remove_edge(*(out_edges(m_g2pi_g_vm[vd], m_pi_g).first), m_pi_g);
+ pi_edge_t ned = add_edge(m_g2pi_g_vm[vd], m_g2pi_g_vm[target(new_edge, m_g)], m_pi_g).first;
+ put(edge_weight, m_pi_g, ned, m_ew1m[new_edge]);
+ put(edge_weight2, m_pi_g, ned, m_ew2m[new_edge]);
+ }
+ /*!
+ * Policy Improvement. Improve the policy graph. The new policy graph has greater cycle ratio.
+ * \return false if nothing can be improved.
+ */
+ bool improve_policy_try1(std::vector<double>& max_eing_vals)
+ {
+ bool improved = false;
+ BGL_FORALL_VERTICES_T(vd, m_g, TGraph)
+ {
+ double max_ev = m_minus_infinity;/// Maximum eigen value for vertex
+ mcr_edge_t cr_ed;///Critical edge
+
+ BGL_FORALL_OUTEDGES_T(vd, outed, m_g, TGraph)
+ {
+ if (m_eigen_value[m_vim[target(outed, m_g)]] > max_ev)
+ {
+ max_ev = m_eigen_value[m_vim[boost::target(outed, m_g)]];
+ cr_ed = outed;
+ }
+ }
+ if (max_ev > m_eigen_value[get(m_vim,vd)])
+ {
+ improve_policy(vd, cr_ed);
+ improved = true;
+ }
+ max_eing_vals[get(m_vim,vd)] = max_ev;
+ }
+ return improved;
+ }
+
+ /*!
+ * \param max_eigen_values[u] = max_(for all adjacent vertices (u,v)) m_eigen_value[v]
+ */
+ bool improve_policy_try2(const std::vector<double>& max_eigen_values)
+ {
+ bool improved = false;
+ BGL_FORALL_VERTICES_T(vd, m_g, TGraph)
+ {
+ mcr_edge_t impr_edge;
+ double max_val = m_minus_infinity;
+ BGL_FORALL_OUTEDGES_T(vd, outed, m_g, TGraph)
+ {
+ ///If vertex vd is in the K(vd) set
+ if (max_eigen_values[get(m_vim, vd)] <= m_eigen_value[get(m_vim, target(outed, m_g))])
+ {
+ double c_val = m_ew1m[outed] - m_ew2m[outed] * m_eigen_value[m_vim[boost::target(outed, m_g)]] +
+ m_eigen_vector[m_vim[boost::target(outed, m_g)]];
+ if (c_val > max_val)
+ {
+ max_val = c_val;
+ impr_edge = outed;
+ }
+ }
+ }
+ if ((max_val - m_eigen_vector[get(m_vim, vd)]) > mcr_howard_ltolerance)
+ ///If m_eigen_vector[vd] == max_val
+ {
+ improve_policy(vd, impr_edge);
+ improved = true;
+ }
+ }
+ return improved;
+ }
+ };///Cmcr_Howard
+
+ /*!
+ * \return maximum cycle ratio and one critical cycle.
+ */
+ template <typename TGraph, typename TVertexIndexMap, typename TWeight1EdgeMap, typename TWeight2EdgeMap>
+ class Cmcr_Howard1 : public Cmcr_Howard<TGraph, TVertexIndexMap, TWeight1EdgeMap, TWeight2EdgeMap>
+ {
+ public:
+ typedef Cmcr_Howard<TGraph, TVertexIndexMap, TWeight1EdgeMap, TWeight2EdgeMap> inhr_t;
+ Cmcr_Howard1(const TGraph& g, TVertexIndexMap vim, TWeight1EdgeMap ewm, TWeight2EdgeMap ew2m) : inhr_t(g, vim, ewm, ew2m)
+ {
+ m_pi_g2g.resize(boost::num_vertices(g));
+ m_pi_g2g_vm = boost::make_iterator_property_map(m_pi_g2g.begin(), boost::get(boost::vertex_index, this->m_pi_g));
+ }
+
+ void get_critical_cycle(typename inhr_t::critical_cycle_t& cc) { return cc.swap(m_critical_cycle); }
+ protected:
+ void store_pivertex(typename inhr_t::pi_vertex_t pivd, typename inhr_t::mcr_vertex_t vd)
+ {
+ m_pi_g2g_vm[pivd] = vd;
+ }
+ void store_critical_edge(typename inhr_t::pi_edge_t ed, typename inhr_t::critical_cycle_t& cc)
+ {
+ typename inhr_t::pi_vertex_t s = boost::source(ed, this->m_pi_g);
+ typename inhr_t::pi_vertex_t t = boost::target(ed, this->m_pi_g);
+ assert(boost::edge(m_pi_g2g_vm[s], m_pi_g2g_vm[t], this->m_g).second);
+ cc.push_back(boost::edge(m_pi_g2g_vm[s], m_pi_g2g_vm[t], this->m_g).first); ///Store corresponding edge of the m_g
+ }
+ void store_critical_cycle(typename inhr_t::critical_cycle_t& cc)
+ {
+ m_critical_cycle.swap(cc);
+ }
+ private:
+ typename inhr_t::critical_cycle_t m_critical_cycle;
+ typedef typename boost::iterator_property_map<typename std::vector<typename inhr_t::mcr_vertex_t>::iterator, typename inhr_t::TPiGraphVertexIndexMap> pi_g2g_vm_t;
+ pi_g2g_vm_t m_pi_g2g_vm; ///Maps policy graph vertices to input graph vertices
+ typename std::vector<typename inhr_t::mcr_vertex_t> m_pi_g2g;
+ };
+
+ /*!
+ * Add sink vertex - this will make any graph good, the selfloop will have ratio equal to infinity
+ * Properties must be "self increasing"
+ */
+ template <typename TGraph, typename TWeight1EdgeMap, typename TWeight2EdgeMap>
+ typename boost::graph_traits<TGraph>::vertex_descriptor
+ make_graph_good(TGraph& g, TWeight1EdgeMap ewm, TWeight2EdgeMap ew2m,
+ typename boost::property_traits<TWeight1EdgeMap>::value_type infinity)
+ {
+ typedef typename boost::graph_traits<TGraph>::edge_descriptor Edge;
+ typename boost::graph_traits<TGraph>::vertex_descriptor sink = boost::add_vertex(g);
+
+ BGL_FORALL_VERTICES_T(vd, g, TGraph)
+ {
+ Edge newed = boost::add_edge(vd, sink, g).first;
+ boost::put(ewm, newed, 0);
+ boost::put(ew2m, newed, 1);
+ }
+ Edge selfed = boost::edge(sink, sink, g).first;
+ boost::put(ewm, selfed, infinity);
+ return sink;
+ }
+
+ /*!
+ * Construct from input graph g "safe" (suitable for maximum_cycle_ratio1() call) version - safeg
+ */
+ template <typename TG, typename TIndVertexMap, typename TW1EdgeMap, typename TW2EdgeMap, typename TSafeG, typename SafeG2GEdgeMap>
+ void construct_safe_graph(const TG& g, TIndVertexMap vim, TW1EdgeMap ew1m, TW2EdgeMap ew2m, TSafeG& safeg, SafeG2GEdgeMap& sg2gm)
+ {
+ assert(num_vertices(g) == num_vertices(safeg));
+ typedef typename graph_traits<TSafeG>::edge_descriptor tmp_edge_t;
+ typedef typename graph_traits<TG>::edge_descriptor edge_t;
+ typename graph_traits<TG>::edge_iterator ei, ei_end;
+
+ for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ tmp_edge_t tmped = add_edge(vim[source(*ei, g)], vim[target(*ei, g)], safeg).first;
+ sg2gm[tmped] = *ei;
+ put(edge_weight, safeg, tmped, get(ew1m, *ei));
+ put(edge_weight2, safeg, tmped, get(ew2m, *ei));
+ }
+ }
+
+ template <typename TGraph, typename TVertexIndexMap, typename TWeight1EdgeMap, typename TWeight2EdgeMap>
+ double maximum_cycle_ratio_good_graph(const TGraph& g, TVertexIndexMap vim, TWeight1EdgeMap ewm, TWeight2EdgeMap ew2m,
+ typename std::vector<typename boost::graph_traits<TGraph>::edge_descriptor>* pcc = 0)
+ {
+ if (pcc == 0)
+ {
+ return detail::Cmcr_Howard<TGraph, TVertexIndexMap, TWeight1EdgeMap, TWeight2EdgeMap>(g, vim, ewm, ew2m)();
+ }
+ else
+ {
+ detail::Cmcr_Howard1<TGraph, TVertexIndexMap, TWeight1EdgeMap, TWeight2EdgeMap> obj(g, vim, ewm, ew2m);
+ double maxcr = obj();
+ obj.get_critical_cycle(*pcc);
+ return maxcr;
+ }
+ }
+
+ template <typename TGraph, typename TVertexIndexMap, typename TWeight1EdgeMap, typename TWeight2EdgeMap, typename TEdgeIndexMap>
+ double minimum_cycle_ratio_good_graph(const TGraph& g, TVertexIndexMap vim, TWeight1EdgeMap ewm,
+ TWeight2EdgeMap ew2m, TEdgeIndexMap eim,
+ typename std::vector<typename boost::graph_traits<TGraph>::edge_descriptor>* pcc = 0)
+ {
+ typedef typename boost::remove_const<typename boost::property_traits<TWeight1EdgeMap>::value_type>::type weight_value_t;
+ BOOST_STATIC_ASSERT(!is_integral<weight_value_t>::value || is_signed<weight_value_t>::value);
+ typename std::vector<weight_value_t> ne_w(boost::num_edges(g));
+ BGL_FORALL_EDGES_T(ed, g, TGraph) ne_w[boost::get(eim, ed)] = -ewm[ed];
+ return -maximum_cycle_ratio_good_graph(g, vim, boost::make_iterator_property_map(ne_w.begin(), eim), ew2m, pcc);
+ }
+
+ /*!
+ * \param g directed multigraph.
+ * \param pcc - pointer to the critical edges list.
+ * \param minus_infinity must be small enough to garanty that g has at least one cycle with greater ratio.
+ * \return minus_infinity if there're no cycles in the graph
+ */
+ template <typename TGraph, typename TWeight1EdgeMap, typename TWeight2EdgeMap>
+ double maximum_cycle_ratio1(const TGraph& g, TWeight1EdgeMap ewm, TWeight2EdgeMap ew2m,
+ typename std::vector<typename boost::graph_traits<TGraph>::edge_descriptor>* pcc = 0,
+ typename boost::property_traits<TWeight1EdgeMap>::value_type minus_infinity = -(std::numeric_limits<int>::max)())
+ {
+ typedef typename boost::graph_traits<TGraph>::vertex_descriptor Vertex;
+ typedef typename boost::graph_traits<TGraph>::edge_descriptor Edge;
+ boost::function_requires< boost::ReadWritePropertyMapConcept<TWeight1EdgeMap, Edge> >();
+ boost::function_requires< boost::ReadWritePropertyMapConcept<TWeight2EdgeMap, Edge> >();
+
+ TGraph& ncg = const_cast<TGraph&>(g);
+ Vertex sink = detail::make_graph_good(ncg, ewm, ew2m, minus_infinity );
+
+ double res = maximum_cycle_ratio_good_graph(ncg, boost::get(boost::vertex_index, g), ewm, ew2m, pcc);
+ boost::clear_vertex(sink, ncg); boost::remove_vertex(sink, ncg);
+ return res;
+ }
+
+ /*!
+ * Edge index MUST be in diapazon [0,..., num_edges(g)-1]
+ * \return plus_infinity if g has no cycles.
+ */
+ template <typename TGraph, typename TWeight1EdgeMap, typename TWeight2EdgeMap, typename TEdgeIndexMap>
+ double minimum_cycle_ratio1(const TGraph& g, TWeight1EdgeMap ewm, TWeight2EdgeMap ew2m, TEdgeIndexMap eim,
+ typename std::vector<typename boost::graph_traits<TGraph>::edge_descriptor>* pcc = 0,
+ typename boost::property_traits<TWeight1EdgeMap>::value_type plus_infinity = (std::numeric_limits<int>::max)()
+ )
+ {
+ typedef typename boost::property_traits<TEdgeIndexMap>::value_type ei_t;
+ typedef typename boost::graph_traits<TGraph>::vertex_descriptor Vertex;
+ typedef typename boost::graph_traits<TGraph>::edge_descriptor Edge;
+
+ boost::function_requires< boost::ReadWritePropertyMapConcept<TWeight1EdgeMap, Edge> >();
+ boost::function_requires< boost::ReadWritePropertyMapConcept<TWeight2EdgeMap, Edge> >();
+ boost::function_requires< boost::ReadWritePropertyMapConcept<TEdgeIndexMap, Edge> >();
+
+ TGraph& ncg = const_cast<TGraph&>(g);
+
+ ei_t nei = ei_t(boost::num_edges(g));
+ Vertex sink = detail::make_graph_good(ncg, ewm, ew2m, plus_infinity );
+ ///Maintain edge index invariant
+ BGL_FORALL_VERTICES_T(vd, ncg, TGraph)
+ {
+ typename boost::graph_traits<TGraph>::edge_descriptor ed = boost::edge(vd, sink, ncg).first;
+ boost::put(eim, ed, nei++);
+ }
+ double res = minimum_cycle_ratio_good_graph(ncg, boost::get(boost::vertex_index, ncg), ewm, ew2m, eim, pcc);
+ boost::clear_vertex(sink, ncg); boost::remove_vertex(sink, ncg);
+ return res;
+ }
+ struct edge_less_than
+ {
+ template <typename TEdgeDescriptor> bool operator()(const TEdgeDescriptor& x, const TEdgeDescriptor& y) const
+ {
+ return x.get_property() < y.get_property();
+ }
+ };
+ }///namespace detail
+ namespace
+ {
+ template <typename TW1, typename TW2> struct safe_graph
+ {
+ typedef typename boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property,
+ typename boost::property<boost::edge_weight_t, TW1, typename boost::property<boost::edge_weight2_t, TW2> > > type;
+ };
+ }
+
+ /*!
+ * Calculate the maximum cycle ratio (mcr) of the directed multigraph g.
+ * \param g directed multigraph
+ * \param pcc - If provided then a critical cycle will be written to corresponding vector.
+ * \param minus_infinity small enough value to garanty that g has at least one cycle with greater ratio.
+ * \return mcr or minus_infinity if g has no cycles.
+ */
+ template <typename TGraph, typename TVertexIndexMap, typename TW1EdgeMap, typename TW2EdgeMap>
+ double maximum_cycle_ratio(const TGraph& g, TVertexIndexMap vim, TW1EdgeMap ew1m, TW2EdgeMap ew2m,
+ typename std::vector<typename boost::graph_traits<TGraph>::edge_descriptor>* pcc = 0,
+ typename boost::property_traits<TW1EdgeMap>::value_type minus_infinity =
+ -(std::numeric_limits<int>::max)())
+ {
+ typedef typename remove_const<typename property_traits<TW1EdgeMap>::value_type>::type w1_t;
+ typedef typename remove_const<typename property_traits<TW2EdgeMap>::value_type>::type w2_t;
+ typedef typename safe_graph<w1_t, w2_t>::type safe_graph_t;
+ typedef typename graph_traits<safe_graph_t>::edge_descriptor tmp_edge_t;
+ typedef typename graph_traits<TGraph>::edge_descriptor edge_t;
+ typename std::map<tmp_edge_t, edge_t, detail::edge_less_than> tmpg2g;
+ std::vector<tmp_edge_t> cc;
+ safe_graph_t sg(num_vertices(g));
+ detail::construct_safe_graph(g, vim, ew1m, ew2m, sg, tmpg2g);
+ double mcr = maximum_cycle_ratio1(sg, get(edge_weight, sg), get(edge_weight2, sg), pcc ? &cc : 0, minus_infinity);
+ if (pcc && (mcr > minus_infinity))
+ {
+ pcc->clear();
+ for (typename std::vector<tmp_edge_t>::iterator it = cc.begin(); it != cc.end(); ++it) pcc->push_back(tmpg2g[*it]);
+ }
+ return mcr;
+ }
+
+ template <typename TGraph, typename TVertexIndexMap, typename TW1EdgeMap, typename TW2EdgeMap, typename TIndEdgeMap>
+ double minimum_cycle_ratio(const TGraph& g, TVertexIndexMap vim, TW1EdgeMap ew1m, TW2EdgeMap ew2m, TIndEdgeMap eim,
+ typename std::vector<typename boost::graph_traits<TGraph>::edge_descriptor>* pcc = 0,
+ typename boost::property_traits<TW1EdgeMap>::value_type plus_infinity =
+ (std::numeric_limits<int>::max)())
+ {
+ typedef typename boost::remove_const<typename boost::property_traits<TW1EdgeMap>::value_type>::type weight_value_t;
+ BOOST_STATIC_ASSERT(!is_integral<weight_value_t>::value || is_signed<weight_value_t>::value);
+ typename std::vector<weight_value_t> ne_w(boost::num_edges(g));
+ BGL_FORALL_EDGES_T(ed, g, TGraph) ne_w[boost::get(eim, ed)] = -ew1m[ed];
+ return -maximum_cycle_ratio(g, vim, boost::make_iterator_property_map(ne_w.begin(), eim), ew2m, pcc, -plus_infinity);
+ }
+ /*!
+ * Calculate maximum mean cycle of directed weighted multigraph.
+ * \param g directed multigraph
+ * \return maximum mean cycle of g or minus_infinity if g has no cycles.
+ */
+ template <typename TGraph, typename TVertexIndexMap, typename TWeightEdgeMap, typename TIndEdgeMap>
+ double maximum_mean_cycle(const TGraph& g, TVertexIndexMap vim, TWeightEdgeMap ewm, TIndEdgeMap eim,
+ typename std::vector<typename boost::graph_traits<TGraph>::edge_descriptor>* pcc = 0,
+ typename boost::property_traits<TWeightEdgeMap>::value_type minus_infinity =
+ -(std::numeric_limits<int>::max)())
+ {
+ typedef typename boost::remove_const<typename boost::property_traits<TWeightEdgeMap>::value_type>::type weight_value_t;
+ typedef typename boost::graph_traits<TGraph>::edge_descriptor Edge;
+ typename std::vector<weight_value_t> ed_w2(boost::num_edges(g), 1);
+ return maximum_cycle_ratio(g, vim, ewm, boost::make_iterator_property_map(ed_w2.begin(), eim), pcc, minus_infinity);
+ }
+
+ template <typename TGraph, typename TVertexIndexMap, typename TWeightEdgeMap, typename TIndEdgeMap>
+ double minimum_mean_cycle(const TGraph& g, TVertexIndexMap vim, TWeightEdgeMap ewm, TIndEdgeMap eim,
+ typename std::vector<typename boost::graph_traits<TGraph>::edge_descriptor>* pcc = 0,
+ typename boost::property_traits<TWeightEdgeMap>::value_type plus_infinity =
+ (std::numeric_limits<int>::max)())
+ {
+ typedef typename boost::remove_const<typename boost::property_traits<TWeightEdgeMap>::value_type>::type weight_value_t;
+ typedef typename boost::graph_traits<TGraph>::edge_descriptor Edge;
+ typename std::vector<weight_value_t> ed_w2(boost::num_edges(g), 1);
+ return minimum_cycle_ratio(g, vim, ewm, boost::make_iterator_property_map(ed_w2.begin(), eim), eim, pcc, plus_infinity);
+ }
+} //namespace boost
+#endif
Added: branches/CMake/release/libs/graph/include/boost/graph/incremental_components.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/incremental_components.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,170 @@
+//
+//=======================================================================
+// Copyright 1997-2001 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+
+#ifndef BOOST_INCREMENTAL_COMPONENTS_HPP
+#define BOOST_INCREMENTAL_COMPONENTS_HPP
+
+#include <boost/detail/iterator.hpp>
+#include <boost/graph/detail/incremental_components.hpp>
+
+namespace boost {
+
+ // A connected component algorithm for the case when dynamically
+ // adding (but not removing) edges is common. The
+ // incremental_components() function is a preparing operation. Call
+ // same_component to check whether two vertices are in the same
+ // component, or use disjoint_set::find_set to determine the
+ // representative for a vertex.
+
+ // This version of connected components does not require a full
+ // Graph. Instead, it just needs an edge list, where the vertices of
+ // each edge need to be of integer type. The edges are assumed to
+ // be undirected. The other difference is that the result is stored in
+ // a container, instead of just a decorator. The container should be
+ // empty before the algorithm is called. It will grow during the
+ // course of the algorithm. The container must be a model of
+ // BackInsertionSequence and RandomAccessContainer
+ // (std::vector is a good choice). After running the algorithm the
+ // index container will map each vertex to the representative
+ // vertex of the component to which it belongs.
+ //
+ // Adapted from an implementation by Alex Stepanov. The disjoint
+ // sets data structure is from Tarjan's "Data Structures and Network
+ // Algorithms", and the application to connected components is
+ // similar to the algorithm described in Ch. 22 of "Intro to
+ // Algorithms" by Cormen, et. all.
+ //
+ // RankContainer is a random accessable container (operator[] is
+ // defined) with a value type that can represent an integer part of
+ // a binary log of the value type of the corresponding
+ // ParentContainer (char is always enough) its size_type is no less
+ // than the size_type of the corresponding ParentContainer
+
+ // An implementation of disjoint sets can be found in
+ // boost/pending/disjoint_sets.hpp
+
+ template <class EdgeListGraph, class DisjointSets>
+ void incremental_components(EdgeListGraph& g, DisjointSets& ds)
+ {
+ typename graph_traits<EdgeListGraph>::edge_iterator e, end;
+ for (tie(e,end) = edges(g); e != end; ++e)
+ ds.union_set(source(*e,g),target(*e,g));
+ }
+
+ template <class ParentIterator>
+ void compress_components(ParentIterator first, ParentIterator last)
+ {
+ for (ParentIterator current = first; current != last; ++current)
+ detail::find_representative_with_full_compression(first, current-first);
+ }
+
+ template <class ParentIterator>
+ typename boost::detail::iterator_traits<ParentIterator>::difference_type
+ component_count(ParentIterator first, ParentIterator last)
+ {
+ std::ptrdiff_t count = 0;
+ for (ParentIterator current = first; current != last; ++current)
+ if (*current == current - first) ++count;
+ return count;
+ }
+
+ // This algorithm can be applied to the result container of the
+ // connected_components algorithm to normalize
+ // the components.
+ template <class ParentIterator>
+ void normalize_components(ParentIterator first, ParentIterator last)
+ {
+ for (ParentIterator current = first; current != last; ++current)
+ detail::normalize_node(first, current - first);
+ }
+
+ template <class VertexListGraph, class DisjointSets>
+ void initialize_incremental_components(VertexListGraph& G, DisjointSets& ds)
+ {
+ typename graph_traits<VertexListGraph>
+ ::vertex_iterator v, vend;
+ for (tie(v, vend) = vertices(G); v != vend; ++v)
+ ds.make_set(*v);
+ }
+
+ template <class Vertex, class DisjointSet>
+ inline bool same_component(Vertex u, Vertex v, DisjointSet& ds)
+ {
+ return ds.find_set(u) == ds.find_set(v);
+ }
+
+ // considering changing the so that it initializes with a pair of
+ // vertex iterators and a parent PA.
+
+ template <class IndexT>
+ class component_index
+ {
+ public://protected: (avoid friends for now)
+ typedef std::vector<IndexT> MyIndexContainer;
+ MyIndexContainer header;
+ MyIndexContainer index;
+ typedef typename MyIndexContainer::size_type SizeT;
+ typedef typename MyIndexContainer::const_iterator IndexIter;
+ public:
+ typedef detail::component_iterator<IndexIter, IndexT, SizeT>
+ component_iterator;
+ class component {
+ friend class component_index;
+ protected:
+ IndexT number;
+ const component_index<IndexT>* comp_ind_ptr;
+ component(IndexT i, const component_index<IndexT>* p)
+ : number(i), comp_ind_ptr(p) {}
+ public:
+ typedef component_iterator iterator;
+ typedef component_iterator const_iterator;
+ typedef IndexT value_type;
+ iterator begin() const {
+ return iterator( comp_ind_ptr->index.begin(),
+ (comp_ind_ptr->header)[number] );
+ }
+ iterator end() const {
+ return iterator( comp_ind_ptr->index.begin(),
+ comp_ind_ptr->index.size() );
+ }
+ };
+ typedef SizeT size_type;
+ typedef component value_type;
+
+#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
+ template <class Iterator>
+ component_index(Iterator first, Iterator last)
+ : index(std::distance(first, last))
+ {
+ std::copy(first, last, index.begin());
+ detail::construct_component_index(index, header);
+ }
+#else
+ template <class Iterator>
+ component_index(Iterator first, Iterator last)
+ : index(first, last)
+ {
+ detail::construct_component_index(index, header);
+ }
+#endif
+
+ component operator[](IndexT i) const {
+ return component(i, this);
+ }
+ SizeT size() const {
+ return header.size();
+ }
+
+ };
+
+} // namespace boost
+
+#endif // BOOST_INCREMENTAL_COMPONENTS_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/is_kuratowski_subgraph.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/is_kuratowski_subgraph.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,332 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// 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)
+//=======================================================================
+#ifndef __IS_KURATOWSKI_SUBGRAPH_HPP__
+#define __IS_KURATOWSKI_SUBGRAPH_HPP__
+
+#include <boost/config.hpp>
+#include <boost/utility.hpp> //for next/prior
+#include <boost/tuple/tuple.hpp> //for tie
+#include <boost/property_map.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/isomorphism.hpp>
+#include <boost/graph/adjacency_list.hpp>
+
+#include <algorithm>
+#include <vector>
+#include <set>
+
+
+
+namespace boost
+{
+
+ namespace detail
+ {
+
+ template <typename Graph>
+ Graph make_K_5()
+ {
+ typename graph_traits<Graph>::vertex_iterator vi, vi_end, inner_vi;
+ Graph K_5(5);
+ for(tie(vi,vi_end) = vertices(K_5); vi != vi_end; ++vi)
+ for(inner_vi = next(vi); inner_vi != vi_end; ++inner_vi)
+ add_edge(*vi, *inner_vi, K_5);
+ return K_5;
+ }
+
+
+ template <typename Graph>
+ Graph make_K_3_3()
+ {
+ typename graph_traits<Graph>::vertex_iterator
+ vi, vi_end, bipartition_start, inner_vi;
+ Graph K_3_3(6);
+ bipartition_start = next(next(next(vertices(K_3_3).first)));
+ for(tie(vi, vi_end) = vertices(K_3_3); vi != bipartition_start; ++vi)
+ for(inner_vi= bipartition_start; inner_vi != vi_end; ++inner_vi)
+ add_edge(*vi, *inner_vi, K_3_3);
+ return K_3_3;
+ }
+
+
+ template <typename AdjacencyList, typename Vertex>
+ void contract_edge(AdjacencyList& neighbors, Vertex u, Vertex v)
+ {
+ // Remove u from v's neighbor list
+ neighbors[v].erase(std::remove(neighbors[v].begin(),
+ neighbors[v].end(), u
+ ),
+ neighbors[v].end()
+ );
+
+ // Replace any references to u with references to v
+ typedef typename AdjacencyList::value_type::iterator
+ adjacency_iterator_t;
+
+ adjacency_iterator_t u_neighbor_end = neighbors[u].end();
+ for(adjacency_iterator_t u_neighbor_itr = neighbors[u].begin();
+ u_neighbor_itr != u_neighbor_end; ++u_neighbor_itr
+ )
+ {
+ Vertex u_neighbor(*u_neighbor_itr);
+ std::replace(neighbors[u_neighbor].begin(),
+ neighbors[u_neighbor].end(), u, v
+ );
+ }
+
+ // Remove v from u's neighbor list
+ neighbors[u].erase(std::remove(neighbors[u].begin(),
+ neighbors[u].end(), v
+ ),
+ neighbors[u].end()
+ );
+
+ // Add everything in u's neighbor list to v's neighbor list
+ std::copy(neighbors[u].begin(),
+ neighbors[u].end(),
+ std::back_inserter(neighbors[v])
+ );
+
+ // Clear u's neighbor list
+ neighbors[u].clear();
+
+ }
+
+ } // namespace detail
+
+
+
+
+ template <typename Graph, typename ForwardIterator, typename VertexIndexMap>
+ bool is_kuratowski_subgraph(const Graph& g,
+ ForwardIterator begin,
+ ForwardIterator end,
+ VertexIndexMap vm
+ )
+ {
+
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ typedef typename graph_traits<Graph>::edges_size_type e_size_t;
+ typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
+ typedef typename std::vector<vertex_t> v_list_t;
+ typedef typename v_list_t::iterator v_list_iterator_t;
+ typedef iterator_property_map
+ <typename std::vector<v_list_t>::iterator, VertexIndexMap>
+ vertex_to_v_list_map_t;
+
+ typedef adjacency_list<vecS, vecS, undirectedS> small_graph_t;
+
+ enum target_graph_t { k_3_3, k_5};
+
+ target_graph_t target_graph = k_3_3; //unless we decide otherwise later
+
+ static small_graph_t K_5(detail::make_K_5<small_graph_t>());
+
+ static small_graph_t K_3_3(detail::make_K_3_3<small_graph_t>());
+
+ v_size_t n_vertices(num_vertices(g));
+ v_size_t max_num_edges(3*n_vertices - 5);
+
+ std::vector<v_list_t> neighbors_vector(n_vertices);
+ vertex_to_v_list_map_t neighbors(neighbors_vector.begin(), vm);
+
+ e_size_t count = 0;
+ for(ForwardIterator itr = begin; itr != end; ++itr)
+ {
+
+ if (count++ > max_num_edges)
+ return false;
+
+ edge_t e(*itr);
+ vertex_t u(source(e,g));
+ vertex_t v(target(e,g));
+
+ neighbors[u].push_back(v);
+ neighbors[v].push_back(u);
+
+ }
+
+
+ for(v_size_t max_size = 2; max_size < 5; ++max_size)
+ {
+
+ vertex_iterator_t vi, vi_end;
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_t v(*vi);
+
+ //a hack to make sure we don't contract the middle edge of a path
+ //of four degree-3 vertices
+ if (max_size == 4 && neighbors[v].size() == 3)
+ {
+ if (neighbors[neighbors[v][0]].size() +
+ neighbors[neighbors[v][1]].size() +
+ neighbors[neighbors[v][2]].size()
+ < 11 // so, it has two degree-3 neighbors
+ )
+ continue;
+ }
+
+ while (neighbors[v].size() > 0 && neighbors[v].size() < max_size)
+ {
+ // Find one of v's neighbors u such that that v and u
+ // have no neighbors in common. We'll look for such a
+ // neighbor with a naive cubic-time algorithm since the
+ // max size of any of the neighbor sets we'll consider
+ // merging is 3
+
+ bool neighbor_sets_intersect = false;
+
+ vertex_t min_u = graph_traits<Graph>::null_vertex();
+ vertex_t u;
+ v_list_iterator_t v_neighbor_end = neighbors[v].end();
+ for(v_list_iterator_t v_neighbor_itr = neighbors[v].begin();
+ v_neighbor_itr != v_neighbor_end;
+ ++v_neighbor_itr
+ )
+ {
+ neighbor_sets_intersect = false;
+ u = *v_neighbor_itr;
+ v_list_iterator_t u_neighbor_end = neighbors[u].end();
+ for(v_list_iterator_t u_neighbor_itr =
+ neighbors[u].begin();
+ u_neighbor_itr != u_neighbor_end &&
+ !neighbor_sets_intersect;
+ ++u_neighbor_itr
+ )
+ {
+ for(v_list_iterator_t inner_v_neighbor_itr =
+ neighbors[v].begin();
+ inner_v_neighbor_itr != v_neighbor_end;
+ ++inner_v_neighbor_itr
+ )
+ {
+ if (*u_neighbor_itr == *inner_v_neighbor_itr)
+ {
+ neighbor_sets_intersect = true;
+ break;
+ }
+ }
+
+ }
+ if (!neighbor_sets_intersect &&
+ (min_u == graph_traits<Graph>::null_vertex() ||
+ neighbors[u].size() < neighbors[min_u].size())
+ )
+ {
+ min_u = u;
+ }
+
+ }
+
+ if (min_u == graph_traits<Graph>::null_vertex())
+ // Exited the loop without finding an appropriate neighbor of
+ // v, so v must be a lost cause. Move on to other vertices.
+ break;
+ else
+ u = min_u;
+
+ detail::contract_edge(neighbors, u, v);
+
+ }//end iteration over v's neighbors
+
+ }//end iteration through vertices v
+
+ if (max_size == 3)
+ {
+ // check to see whether we should go on to find a K_5
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ if (neighbors[*vi].size() == 4)
+ {
+ target_graph = k_5;
+ break;
+ }
+
+ if (target_graph == k_3_3)
+ break;
+ }
+
+ }//end iteration through max degree 2,3, and 4
+
+
+ //Now, there should only be 5 or 6 vertices with any neighbors. Find them.
+
+ v_list_t main_vertices;
+ vertex_iterator_t vi, vi_end;
+
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ if (!neighbors[*vi].empty())
+ main_vertices.push_back(*vi);
+ }
+
+ // create a graph isomorphic to the contracted graph to test
+ // against K_5 and K_3_3
+ small_graph_t contracted_graph(main_vertices.size());
+ std::map<vertex_t,typename graph_traits<small_graph_t>::vertex_descriptor>
+ contracted_vertex_map;
+
+ typename v_list_t::iterator itr, itr_end;
+ itr_end = main_vertices.end();
+ typename graph_traits<small_graph_t>::vertex_iterator
+ si = vertices(contracted_graph).first;
+
+ for(itr = main_vertices.begin(); itr != itr_end; ++itr, ++si)
+ {
+ contracted_vertex_map[*itr] = *si;
+ }
+
+ typename v_list_t::iterator jtr, jtr_end;
+ for(itr = main_vertices.begin(); itr != itr_end; ++itr)
+ {
+ jtr_end = neighbors[*itr].end();
+ for(jtr = neighbors[*itr].begin(); jtr != jtr_end; ++jtr)
+ {
+ if (get(vm,*itr) < get(vm,*jtr))
+ {
+ add_edge(contracted_vertex_map[*itr],
+ contracted_vertex_map[*jtr],
+ contracted_graph
+ );
+ }
+ }
+ }
+
+ if (target_graph == k_5)
+ {
+ return isomorphism(K_5,contracted_graph);
+ }
+ else //target_graph == k_3_3
+ {
+ return isomorphism(K_3_3,contracted_graph);
+ }
+
+
+ }
+
+
+
+
+
+ template <typename Graph, typename ForwardIterator>
+ bool is_kuratowski_subgraph(const Graph& g,
+ ForwardIterator begin,
+ ForwardIterator end
+ )
+ {
+ return is_kuratowski_subgraph(g, begin, end, get(vertex_index,g));
+ }
+
+
+
+
+}
+
+#endif //__IS_KURATOWSKI_SUBGRAPH_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/is_straight_line_drawing.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/is_straight_line_drawing.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,232 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// 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)
+//=======================================================================
+#ifndef __IS_STRAIGHT_LINE_DRAWING_HPP__
+#define __IS_STRAIGHT_LINE_DRAWING_HPP__
+
+#include <boost/config.hpp>
+#include <boost/utility.hpp> //for next and prior
+#include <boost/tuple/tuple.hpp>
+#include <boost/tuple/tuple_comparison.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/planar_detail/bucket_sort.hpp>
+
+#include <algorithm>
+#include <vector>
+#include <set>
+
+
+
+namespace boost
+{
+
+ // Return true exactly when the line segments s1 = ((x1,y1), (x2,y2)) and
+ // s2 = ((a1,b1), (a2,b2)) intersect in a point other than the endpoints of
+ // the line segments. The one exception to this rule is when s1 = s2, in
+ // which case false is returned - this is to accomodate multiple edges
+ // between the same pair of vertices, which shouldn't invalidate the straight
+ // line embedding. A tolerance variable epsilon can also be used, which
+ // defines how far away from the endpoints of s1 and s2 we want to consider
+ // an intersection.
+
+ bool intersects(double x1, double y1,
+ double x2, double y2,
+ double a1, double b1,
+ double a2, double b2,
+ double epsilon = 0.000001
+ )
+ {
+
+ if (x1 - x2 == 0)
+ {
+ std::swap(x1,a1);
+ std::swap(y1,b1);
+ std::swap(x2,a2);
+ std::swap(y2,b2);
+ }
+
+ if (x1 - x2 == 0)
+ {
+ BOOST_USING_STD_MAX();
+ BOOST_USING_STD_MIN();
+
+ //two vertical line segments
+ double min_y = min BOOST_PREVENT_MACRO_SUBSTITUTION(y1,y2);
+ double max_y = max BOOST_PREVENT_MACRO_SUBSTITUTION(y1,y2);
+ double min_b = min BOOST_PREVENT_MACRO_SUBSTITUTION(b1,b2);
+ double max_b = max BOOST_PREVENT_MACRO_SUBSTITUTION(b1,b2);
+ if ((max_y > max_b && max_b > min_y) ||
+ (max_b > max_y && max_y > min_b)
+ )
+ return true;
+ else
+ return false;
+ }
+
+ double x_diff = x1 - x2;
+ double y_diff = y1 - y2;
+ double a_diff = a2 - a1;
+ double b_diff = b2 - b1;
+
+ double beta_denominator = b_diff - (y_diff/((double)x_diff)) * a_diff;
+
+ if (beta_denominator == 0)
+ {
+ //parallel lines
+ return false;
+ }
+
+ double beta = (b2 - y2 - (y_diff/((double)x_diff)) * (a2 - x2)) /
+ beta_denominator;
+ double alpha = (a2 - x2 - beta*(a_diff))/x_diff;
+
+ double upper_bound = 1 - epsilon;
+ double lower_bound = 0 + epsilon;
+
+ return (beta < upper_bound && beta > lower_bound &&
+ alpha < upper_bound && alpha > lower_bound);
+
+ }
+
+
+ template <typename Graph,
+ typename GridPositionMap,
+ typename VertexIndexMap
+ >
+ bool is_straight_line_drawing(const Graph& g,
+ GridPositionMap drawing,
+ VertexIndexMap vm
+ )
+ {
+
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ typedef typename graph_traits<Graph>::edge_iterator edge_iterator_t;
+ typedef typename graph_traits<Graph>::edges_size_type e_size_t;
+ typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
+
+ typedef std::size_t x_coord_t;
+ typedef std::size_t y_coord_t;
+ typedef boost::tuple<edge_t, x_coord_t, y_coord_t> edge_event_t;
+ typedef typename std::vector< edge_event_t > edge_event_queue_t;
+
+ typedef tuple<y_coord_t, y_coord_t, x_coord_t, x_coord_t> active_map_key_t;
+ typedef edge_t active_map_value_t;
+ typedef std::map< active_map_key_t, active_map_value_t > active_map_t;
+ typedef typename active_map_t::iterator active_map_iterator_t;
+
+
+ edge_event_queue_t edge_event_queue;
+ active_map_t active_edges;
+
+ edge_iterator_t ei, ei_end;
+ for(tie(ei,ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ vertex_t s(source(e,g));
+ vertex_t t(target(e,g));
+ edge_event_queue.push_back
+ (make_tuple(e,
+ static_cast<std::size_t>(drawing[s].x),
+ static_cast<std::size_t>(drawing[s].y)
+ )
+ );
+ edge_event_queue.push_back
+ (make_tuple(e,
+ static_cast<std::size_t>(drawing[t].x),
+ static_cast<std::size_t>(drawing[t].y)
+ )
+ );
+ }
+
+ // Order by edge_event_queue by first, then second coordinate
+ // (bucket_sort is a stable sort.)
+ bucket_sort(edge_event_queue.begin(), edge_event_queue.end(),
+ property_map_tuple_adaptor<edge_event_t, 2>()
+ );
+
+ bucket_sort(edge_event_queue.begin(), edge_event_queue.end(),
+ property_map_tuple_adaptor<edge_event_t, 1>()
+ );
+
+ typedef typename edge_event_queue_t::iterator event_queue_iterator_t;
+ event_queue_iterator_t itr_end = edge_event_queue.end();
+ for(event_queue_iterator_t itr = edge_event_queue.begin();
+ itr != itr_end; ++itr
+ )
+ {
+ edge_t e(get<0>(*itr));
+ vertex_t source_v(source(e,g));
+ vertex_t target_v(target(e,g));
+ if (drawing[source_v].x > drawing[target_v].x)
+ std::swap(source_v, target_v);
+
+ active_map_key_t key(get(drawing, source_v).y,
+ get(drawing, target_v).y,
+ get(drawing, source_v).x,
+ get(drawing, target_v).x
+ );
+
+ active_map_iterator_t a_itr = active_edges.find(key);
+ if (a_itr == active_edges.end())
+ {
+ active_edges[key] = e;
+ }
+ else
+ {
+ active_map_iterator_t before, after;
+ if (a_itr == active_edges.begin())
+ before = active_edges.end();
+ else
+ before = prior(a_itr);
+ after = next(a_itr);
+
+ if (after != active_edges.end() || before != active_edges.end())
+ {
+
+ edge_t f = after != active_edges.end() ?
+ after->second : before->second;
+
+ vertex_t e_source(source(e,g));
+ vertex_t e_target(target(e,g));
+ vertex_t f_source(source(f,g));
+ vertex_t f_target(target(f,g));
+
+ if (intersects(drawing[e_source].x,
+ drawing[e_source].y,
+ drawing[e_target].x,
+ drawing[e_target].y,
+ drawing[f_source].x,
+ drawing[f_source].y,
+ drawing[f_target].x,
+ drawing[f_target].y
+ )
+ )
+ return false;
+ }
+
+ active_edges.erase(a_itr);
+
+ }
+ }
+
+ return true;
+
+ }
+
+
+ template <typename Graph, typename GridPositionMap>
+ bool is_straight_line_drawing(const Graph& g, GridPositionMap drawing)
+ {
+ return is_straight_line_drawing(g, drawing, get(vertex_index,g));
+ }
+
+}
+
+#endif // __IS_STRAIGHT_LINE_DRAWING_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/isomorphism.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/isomorphism.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,467 @@
+// Copyright (C) 2001 Jeremy Siek, Douglas Gregor, Brian Osman
+//
+// 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)
+#ifndef BOOST_GRAPH_ISOMORPHISM_HPP
+#define BOOST_GRAPH_ISOMORPHISM_HPP
+
+#include <utility>
+#include <vector>
+#include <iterator>
+#include <algorithm>
+#include <boost/config.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/utility.hpp>
+#include <boost/detail/algorithm.hpp>
+#include <boost/pending/indirect_cmp.hpp> // for make_indirect_pmap
+
+#ifndef BOOST_GRAPH_ITERATION_MACROS_HPP
+#define BOOST_ISO_INCLUDED_ITER_MACROS // local macro, see bottom of file
+#include <boost/graph/iteration_macros.hpp>
+#endif
+
+namespace boost {
+
+ namespace detail {
+
+ template <typename Graph1, typename Graph2, typename IsoMapping,
+ typename Invariant1, typename Invariant2,
+ typename IndexMap1, typename IndexMap2>
+ class isomorphism_algo
+ {
+ typedef typename graph_traits<Graph1>::vertex_descriptor vertex1_t;
+ typedef typename graph_traits<Graph2>::vertex_descriptor vertex2_t;
+ typedef typename graph_traits<Graph1>::edge_descriptor edge1_t;
+ typedef typename graph_traits<Graph1>::vertices_size_type size_type;
+ typedef typename Invariant1::result_type invar1_value;
+ typedef typename Invariant2::result_type invar2_value;
+
+ const Graph1& G1;
+ const Graph2& G2;
+ IsoMapping f;
+ Invariant1 invariant1;
+ Invariant2 invariant2;
+ std::size_t max_invariant;
+ IndexMap1 index_map1;
+ IndexMap2 index_map2;
+
+ std::vector<vertex1_t> dfs_vertices;
+ typedef typename std::vector<vertex1_t>::iterator vertex_iter;
+ std::vector<int> dfs_num_vec;
+ typedef safe_iterator_property_map<typename std::vector<int>::iterator,
+ IndexMap1
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ , int, int&
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ > DFSNumMap;
+ DFSNumMap dfs_num;
+ std::vector<edge1_t> ordered_edges;
+ typedef typename std::vector<edge1_t>::iterator edge_iter;
+
+ std::vector<char> in_S_vec;
+ typedef safe_iterator_property_map<typename std::vector<char>::iterator,
+ IndexMap2
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ , char, char&
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ > InSMap;
+ InSMap in_S;
+
+ int num_edges_on_k;
+
+ friend struct compare_multiplicity;
+ struct compare_multiplicity
+ {
+ compare_multiplicity(Invariant1 invariant1, size_type* multiplicity)
+ : invariant1(invariant1), multiplicity(multiplicity) { }
+ bool operator()(const vertex1_t& x, const vertex1_t& y) const {
+ return multiplicity[invariant1(x)] < multiplicity[invariant1(y)];
+ }
+ Invariant1 invariant1;
+ size_type* multiplicity;
+ };
+
+ struct record_dfs_order : default_dfs_visitor
+ {
+ record_dfs_order(std::vector<vertex1_t>& v, std::vector<edge1_t>& e)
+ : vertices(v), edges(e) { }
+
+ void discover_vertex(vertex1_t v, const Graph1&) const {
+ vertices.push_back(v);
+ }
+ void examine_edge(edge1_t e, const Graph1& G1) const {
+ edges.push_back(e);
+ }
+ std::vector<vertex1_t>& vertices;
+ std::vector<edge1_t>& edges;
+ };
+
+ struct edge_cmp {
+ edge_cmp(const Graph1& G1, DFSNumMap dfs_num)
+ : G1(G1), dfs_num(dfs_num) { }
+ bool operator()(const edge1_t& e1, const edge1_t& e2) const {
+ using namespace std;
+ int u1 = dfs_num[source(e1,G1)], v1 = dfs_num[target(e1,G1)];
+ int u2 = dfs_num[source(e2,G1)], v2 = dfs_num[target(e2,G1)];
+ int m1 = (max)(u1, v1);
+ int m2 = (max)(u2, v2);
+ // lexicographical comparison
+ return std::make_pair(m1, std::make_pair(u1, v1))
+ < std::make_pair(m2, std::make_pair(u2, v2));
+ }
+ const Graph1& G1;
+ DFSNumMap dfs_num;
+ };
+
+ public:
+ isomorphism_algo(const Graph1& G1, const Graph2& G2, IsoMapping f,
+ Invariant1 invariant1, Invariant2 invariant2, std::size_t max_invariant,
+ IndexMap1 index_map1, IndexMap2 index_map2)
+ : G1(G1), G2(G2), f(f), invariant1(invariant1), invariant2(invariant2),
+ max_invariant(max_invariant),
+ index_map1(index_map1), index_map2(index_map2)
+ {
+ in_S_vec.resize(num_vertices(G1));
+ in_S = make_safe_iterator_property_map
+ (in_S_vec.begin(), in_S_vec.size(), index_map2
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ , in_S_vec.front()
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ );
+ }
+
+ bool test_isomorphism()
+ {
+ {
+ std::vector<invar1_value> invar1_array;
+ BGL_FORALL_VERTICES_T(v, G1, Graph1)
+ invar1_array.push_back(invariant1(v));
+ sort(invar1_array);
+
+ std::vector<invar2_value> invar2_array;
+ BGL_FORALL_VERTICES_T(v, G2, Graph2)
+ invar2_array.push_back(invariant2(v));
+ sort(invar2_array);
+ if (! equal(invar1_array, invar2_array))
+ return false;
+ }
+
+ std::vector<vertex1_t> V_mult;
+ BGL_FORALL_VERTICES_T(v, G1, Graph1)
+ V_mult.push_back(v);
+ {
+ std::vector<size_type> multiplicity(max_invariant, 0);
+ BGL_FORALL_VERTICES_T(v, G1, Graph1)
+ ++multiplicity[invariant1(v)];
+ sort(V_mult, compare_multiplicity(invariant1, &multiplicity[0]));
+ }
+
+ std::vector<default_color_type> color_vec(num_vertices(G1));
+ safe_iterator_property_map<std::vector<default_color_type>::iterator,
+ IndexMap1
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ , default_color_type, default_color_type&
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ >
+ color_map(color_vec.begin(), color_vec.size(), index_map1);
+ record_dfs_order dfs_visitor(dfs_vertices, ordered_edges);
+ typedef color_traits<default_color_type> Color;
+ for (vertex_iter u = V_mult.begin(); u != V_mult.end(); ++u) {
+ if (color_map[*u] == Color::white()) {
+ dfs_visitor.start_vertex(*u, G1);
+ depth_first_visit(G1, *u, dfs_visitor, color_map);
+ }
+ }
+ // Create the dfs_num array and dfs_num_map
+ dfs_num_vec.resize(num_vertices(G1));
+ dfs_num = make_safe_iterator_property_map(dfs_num_vec.begin(),
+ dfs_num_vec.size(),
+ index_map1
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ , dfs_num_vec.front()
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ );
+ size_type n = 0;
+ for (vertex_iter v = dfs_vertices.begin(); v != dfs_vertices.end(); ++v)
+ dfs_num[*v] = n++;
+
+ sort(ordered_edges, edge_cmp(G1, dfs_num));
+
+
+ int dfs_num_k = -1;
+ return this->match(ordered_edges.begin(), dfs_num_k);
+ }
+
+ private:
+ bool match(edge_iter iter, int dfs_num_k)
+ {
+ if (iter != ordered_edges.end()) {
+ vertex1_t i = source(*iter, G1), j = target(*iter, G2);
+ if (dfs_num[i] > dfs_num_k) {
+ vertex1_t kp1 = dfs_vertices[dfs_num_k + 1];
+ BGL_FORALL_VERTICES_T(u, G2, Graph2) {
+ if (invariant1(kp1) == invariant2(u) && in_S[u] == false) {
+ f[kp1] = u;
+ in_S[u] = true;
+ num_edges_on_k = 0;
+
+ if (match(iter, dfs_num_k + 1))
+#if 0
+ // dwa 2003/7/11 -- this *HAS* to be a bug!
+ ;
+#endif
+ return true;
+
+ in_S[u] = false;
+ }
+ }
+
+ }
+ else if (dfs_num[j] > dfs_num_k) {
+ vertex1_t k = dfs_vertices[dfs_num_k];
+ num_edges_on_k -=
+ count_if(adjacent_vertices(f[k], G2), make_indirect_pmap(in_S));
+
+ for (int jj = 0; jj < dfs_num_k; ++jj) {
+ vertex1_t j = dfs_vertices[jj];
+ num_edges_on_k -= count(adjacent_vertices(f[j], G2), f[k]);
+ }
+
+ if (num_edges_on_k != 0)
+ return false;
+ BGL_FORALL_ADJ_T(f[i], v, G2, Graph2)
+ if (invariant2(v) == invariant1(j) && in_S[v] == false) {
+ f[j] = v;
+ in_S[v] = true;
+ num_edges_on_k = 1;
+ BOOST_USING_STD_MAX();
+ int next_k = max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num_k, max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num[i], dfs_num[j]));
+ if (match(next(iter), next_k))
+ return true;
+ in_S[v] = false;
+ }
+
+
+ }
+ else {
+ if (container_contains(adjacent_vertices(f[i], G2), f[j])) {
+ ++num_edges_on_k;
+ if (match(next(iter), dfs_num_k))
+ return true;
+ }
+
+ }
+ } else
+ return true;
+ return false;
+ }
+
+ };
+
+
+ template <typename Graph, typename InDegreeMap>
+ void compute_in_degree(const Graph& g, InDegreeMap in_degree_map)
+ {
+ BGL_FORALL_VERTICES_T(v, g, Graph)
+ put(in_degree_map, v, 0);
+
+ BGL_FORALL_VERTICES_T(u, g, Graph)
+ BGL_FORALL_ADJ_T(u, v, g, Graph)
+ put(in_degree_map, v, get(in_degree_map, v) + 1);
+ }
+
+ } // namespace detail
+
+
+ template <typename InDegreeMap, typename Graph>
+ class degree_vertex_invariant
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::degree_size_type size_type;
+ public:
+ typedef vertex_t argument_type;
+ typedef size_type result_type;
+
+ degree_vertex_invariant(const InDegreeMap& in_degree_map, const Graph& g)
+ : m_in_degree_map(in_degree_map), m_g(g) { }
+
+ size_type operator()(vertex_t v) const {
+ return (num_vertices(m_g) + 1) * out_degree(v, m_g)
+ + get(m_in_degree_map, v);
+ }
+ // The largest possible vertex invariant number
+ size_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const {
+ return num_vertices(m_g) * num_vertices(m_g) + num_vertices(m_g);
+ }
+ private:
+ InDegreeMap m_in_degree_map;
+ const Graph& m_g;
+ };
+
+
+ template <typename Graph1, typename Graph2, typename IsoMapping,
+ typename Invariant1, typename Invariant2,
+ typename IndexMap1, typename IndexMap2>
+ bool isomorphism(const Graph1& G1, const Graph2& G2, IsoMapping f,
+ Invariant1 invariant1, Invariant2 invariant2,
+ std::size_t max_invariant,
+ IndexMap1 index_map1, IndexMap2 index_map2)
+
+ {
+ // Graph requirements
+ function_requires< VertexListGraphConcept<Graph1> >();
+ function_requires< EdgeListGraphConcept<Graph1> >();
+ function_requires< VertexListGraphConcept<Graph2> >();
+ function_requires< BidirectionalGraphConcept<Graph2> >();
+
+ typedef typename graph_traits<Graph1>::vertex_descriptor vertex1_t;
+ typedef typename graph_traits<Graph2>::vertex_descriptor vertex2_t;
+ typedef typename graph_traits<Graph1>::vertices_size_type size_type;
+
+ // Vertex invariant requirement
+ function_requires< AdaptableUnaryFunctionConcept<Invariant1,
+ size_type, vertex1_t> >();
+ function_requires< AdaptableUnaryFunctionConcept<Invariant2,
+ size_type, vertex2_t> >();
+
+ // Property map requirements
+ function_requires< ReadWritePropertyMapConcept<IsoMapping, vertex1_t> >();
+ typedef typename property_traits<IsoMapping>::value_type IsoMappingValue;
+ BOOST_STATIC_ASSERT((is_same<IsoMappingValue, vertex2_t>::value));
+
+ function_requires< ReadablePropertyMapConcept<IndexMap1, vertex1_t> >();
+ typedef typename property_traits<IndexMap1>::value_type IndexMap1Value;
+ BOOST_STATIC_ASSERT((is_convertible<IndexMap1Value, size_type>::value));
+
+ function_requires< ReadablePropertyMapConcept<IndexMap2, vertex2_t> >();
+ typedef typename property_traits<IndexMap2>::value_type IndexMap2Value;
+ BOOST_STATIC_ASSERT((is_convertible<IndexMap2Value, size_type>::value));
+
+ if (num_vertices(G1) != num_vertices(G2))
+ return false;
+ if (num_vertices(G1) == 0 && num_vertices(G2) == 0)
+ return true;
+
+ detail::isomorphism_algo<Graph1, Graph2, IsoMapping, Invariant1,
+ Invariant2, IndexMap1, IndexMap2>
+ algo(G1, G2, f, invariant1, invariant2, max_invariant,
+ index_map1, index_map2);
+ return algo.test_isomorphism();
+ }
+
+
+ namespace detail {
+
+ template <typename Graph1, typename Graph2,
+ typename IsoMapping,
+ typename IndexMap1, typename IndexMap2,
+ typename P, typename T, typename R>
+ bool isomorphism_impl(const Graph1& G1, const Graph2& G2,
+ IsoMapping f, IndexMap1 index_map1, IndexMap2 index_map2,
+ const bgl_named_params<P,T,R>& params)
+ {
+ std::vector<std::size_t> in_degree1_vec(num_vertices(G1));
+ typedef safe_iterator_property_map<std::vector<std::size_t>::iterator,
+ IndexMap1
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ , std::size_t, std::size_t&
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ > InDeg1;
+ InDeg1 in_degree1(in_degree1_vec.begin(), in_degree1_vec.size(), index_map1);
+ compute_in_degree(G1, in_degree1);
+
+ std::vector<std::size_t> in_degree2_vec(num_vertices(G2));
+ typedef safe_iterator_property_map<std::vector<std::size_t>::iterator,
+ IndexMap2
+#ifdef BOOST_NO_STD_ITERATOR_TRAITS
+ , std::size_t, std::size_t&
+#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
+ > InDeg2;
+ InDeg2 in_degree2(in_degree2_vec.begin(), in_degree2_vec.size(), index_map2);
+ compute_in_degree(G2, in_degree2);
+
+ degree_vertex_invariant<InDeg1, Graph1> invariant1(in_degree1, G1);
+ degree_vertex_invariant<InDeg2, Graph2> invariant2(in_degree2, G2);
+
+ return isomorphism(G1, G2, f,
+ choose_param(get_param(params, vertex_invariant1_t()), invariant1),
+ choose_param(get_param(params, vertex_invariant2_t()), invariant2),
+ choose_param(get_param(params, vertex_max_invariant_t()), (invariant2.max)()),
+ index_map1, index_map2
+ );
+ }
+
+ } // namespace detail
+
+
+ // Named parameter interface
+ template <typename Graph1, typename Graph2, class P, class T, class R>
+ bool isomorphism(const Graph1& g1,
+ const Graph2& g2,
+ const bgl_named_params<P,T,R>& params)
+ {
+ typedef typename graph_traits<Graph2>::vertex_descriptor vertex2_t;
+ typename std::vector<vertex2_t>::size_type n = num_vertices(g1);
+ std::vector<vertex2_t> f(n);
+ return detail::isomorphism_impl
+ (g1, g2,
+ choose_param(get_param(params, vertex_isomorphism_t()),
+ make_safe_iterator_property_map(f.begin(), f.size(),
+ choose_const_pmap(get_param(params, vertex_index1),
+ g1, vertex_index), vertex2_t())),
+ choose_const_pmap(get_param(params, vertex_index1), g1, vertex_index),
+ choose_const_pmap(get_param(params, vertex_index2), g2, vertex_index),
+ params
+ );
+ }
+
+ // All defaults interface
+ template <typename Graph1, typename Graph2>
+ bool isomorphism(const Graph1& g1, const Graph2& g2)
+ {
+ return isomorphism(g1, g2,
+ bgl_named_params<int, buffer_param_t>(0));// bogus named param
+ }
+
+
+ // Verify that the given mapping iso_map from the vertices of g1 to the
+ // vertices of g2 describes an isomorphism.
+ // Note: this could be made much faster by specializing based on the graph
+ // concepts modeled, but since we're verifying an O(n^(lg n)) algorithm,
+ // O(n^4) won't hurt us.
+ template<typename Graph1, typename Graph2, typename IsoMap>
+ inline bool verify_isomorphism(const Graph1& g1, const Graph2& g2, IsoMap iso_map)
+ {
+#if 0
+ // problematic for filtered_graph!
+ if (num_vertices(g1) != num_vertices(g2) || num_edges(g1) != num_edges(g2))
+ return false;
+#endif
+
+ for (typename graph_traits<Graph1>::edge_iterator e1 = edges(g1).first;
+ e1 != edges(g1).second; ++e1) {
+ bool found_edge = false;
+ for (typename graph_traits<Graph2>::edge_iterator e2 = edges(g2).first;
+ e2 != edges(g2).second && !found_edge; ++e2) {
+ if (source(*e2, g2) == get(iso_map, source(*e1, g1)) &&
+ target(*e2, g2) == get(iso_map, target(*e1, g1))) {
+ found_edge = true;
+ }
+ }
+
+ if (!found_edge)
+ return false;
+ }
+
+ return true;
+ }
+
+} // namespace boost
+
+#ifdef BOOST_ISO_INCLUDED_ITER_MACROS
+#undef BOOST_ISO_INCLUDED_ITER_MACROS
+#include <boost/graph/iteration_macros_undef.hpp>
+#endif
+
+#endif // BOOST_GRAPH_ISOMORPHISM_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/iteration_macros.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/iteration_macros.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,129 @@
+//=======================================================================
+// Copyright 2001 Indiana University
+// Author: Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_ITERATION_MACROS_HPP
+#define BOOST_GRAPH_ITERATION_MACROS_HPP
+
+#define BGL_CAT(x,y) x ## y
+#define BGL_FIRST(linenum) BGL_CAT(bgl_first_,linenum)
+#define BGL_LAST(linenum) BGL_CAT(bgl_last_,linenum)
+
+/*
+ BGL_FORALL_VERTICES_T(v, g, graph_t) // This is on line 9
+ expands to the following, but all on the same line
+
+ for (typename boost::graph_traits<graph_t>::vertex_iterator
+ bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second;
+ bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9)
+ for (typename boost::graph_traits<graph_t>::vertex_descriptor v;
+ bgl_first_9 != bgl_last ? (v = *bgl_first_9, true) : false;
+ ++bgl_first_9)
+
+ The purpose of having two for-loops is just to provide a place to
+ declare both the iterator and value variables. There is really only
+ one loop. The stopping condition gets executed two more times than it
+ usually would be, oh well. The reason for the bgl_first_9 = bgl_last_9
+ in the outer for-loop is in case the user puts a break statement
+ in the inner for-loop.
+
+ The other macros work in a similar fashion.
+
+ Use the _T versions when the graph type is a template parameter or
+ dependent on a template parameter. Otherwise use the non _T versions.
+
+ */
+
+
+#define BGL_FORALL_VERTICES_T(VNAME, GNAME, GraphType) \
+for (typename boost::graph_traits<GraphType>::vertex_iterator \
+ BGL_FIRST(__LINE__) = vertices(GNAME).first, BGL_LAST(__LINE__) = vertices(GNAME).second; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
+ for (typename boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false; \
+ ++BGL_FIRST(__LINE__))
+
+#define BGL_FORALL_VERTICES(VNAME, GNAME, GraphType) \
+for (boost::graph_traits<GraphType>::vertex_iterator \
+ BGL_FIRST(__LINE__) = vertices(GNAME).first, BGL_LAST(__LINE__) = vertices(GNAME).second; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
+ for (boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false; \
+ ++BGL_FIRST(__LINE__))
+
+#define BGL_FORALL_EDGES_T(ENAME, GNAME, GraphType) \
+for (typename boost::graph_traits<GraphType>::edge_iterator \
+ BGL_FIRST(__LINE__) = edges(GNAME).first, BGL_LAST(__LINE__) = edges(GNAME).second; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
+ for (typename boost::graph_traits<GraphType>::edge_descriptor ENAME; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true):false; \
+ ++BGL_FIRST(__LINE__))
+
+#define BGL_FORALL_EDGES(ENAME, GNAME, GraphType) \
+for (boost::graph_traits<GraphType>::edge_iterator \
+ BGL_FIRST(__LINE__) = edges(GNAME).first, BGL_LAST(__LINE__) = edges(GNAME).second; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
+ for (boost::graph_traits<GraphType>::edge_descriptor ENAME; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true):false; \
+ ++BGL_FIRST(__LINE__))
+
+#define BGL_FORALL_ADJ_T(UNAME, VNAME, GNAME, GraphType) \
+for (typename boost::graph_traits<GraphType>::adjacency_iterator \
+ BGL_FIRST(__LINE__) = adjacent_vertices(UNAME, GNAME).first,\
+ BGL_LAST(__LINE__) = adjacent_vertices(UNAME, GNAME).second; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
+for (typename boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true) : false; \
+ ++BGL_FIRST(__LINE__))
+
+#define BGL_FORALL_ADJ(UNAME, VNAME, GNAME, GraphType) \
+for (boost::graph_traits<GraphType>::adjacency_iterator \
+ BGL_FIRST(__LINE__) = adjacent_vertices(UNAME, GNAME).first,\
+ BGL_LAST(__LINE__) = adjacent_vertices(UNAME, GNAME).second; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
+for (boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true) : false; \
+ ++BGL_FIRST(__LINE__))
+
+#define BGL_FORALL_OUTEDGES_T(UNAME, ENAME, GNAME, GraphType) \
+for (typename boost::graph_traits<GraphType>::out_edge_iterator \
+ BGL_FIRST(__LINE__) = out_edges(UNAME, GNAME).first,\
+ BGL_LAST(__LINE__) = out_edges(UNAME, GNAME).second; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
+for (typename boost::graph_traits<GraphType>::edge_descriptor ENAME; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
+ ++BGL_FIRST(__LINE__))
+
+#define BGL_FORALL_OUTEDGES(UNAME, ENAME, GNAME, GraphType) \
+for (boost::graph_traits<GraphType>::out_edge_iterator \
+ BGL_FIRST(__LINE__) = out_edges(UNAME, GNAME).first,\
+ BGL_LAST(__LINE__) = out_edges(UNAME, GNAME).second; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
+for (boost::graph_traits<GraphType>::edge_descriptor ENAME; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
+ ++BGL_FIRST(__LINE__))
+
+#define BGL_FORALL_INEDGES_T(UNAME, ENAME, GNAME, GraphType) \
+for (typename boost::graph_traits<GraphType>::in_edge_iterator \
+ BGL_FIRST(__LINE__) = in_edges(UNAME, GNAME).first,\
+ BGL_LAST(__LINE__) = in_edges(UNAME, GNAME).second; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
+for (typename boost::graph_traits<GraphType>::edge_descriptor ENAME; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
+ ++BGL_FIRST(__LINE__))
+
+#define BGL_FORALL_INEDGES(UNAME, ENAME, GNAME, GraphType) \
+for (boost::graph_traits<GraphType>::in_edge_iterator \
+ BGL_FIRST(__LINE__) = in_edges(UNAME, GNAME).first,\
+ BGL_LAST(__LINE__) = in_edges(UNAME, GNAME).second; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
+for (boost::graph_traits<GraphType>::edge_descriptor ENAME; \
+ BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
+ ++BGL_FIRST(__LINE__))
+
+#endif // BOOST_GRAPH_ITERATION_MACROS_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/iteration_macros_undef.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/iteration_macros_undef.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,22 @@
+//=======================================================================
+// Copyright 2002 Indiana University.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifdef BOOST_GRAPH_ITERATION_MACROS_HPP
+
+#undef BOOST_GRAPH_ITERATION_MACROS_HPP
+#undef BGL_CAT
+#undef BGL_FIRST
+#undef BGL_LAST
+#undef BGL_FORALL_VERTICES
+#undef BGL_FORALL_EDGES
+#undef BGL_FORALL_ADJACENT
+#undef BGL_FORALL_OUTEDGES
+#undef BGL_FORALL_INEDGES
+
+#endif
Added: branches/CMake/release/libs/graph/include/boost/graph/johnson_all_pairs_shortest.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/johnson_all_pairs_shortest.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,205 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+/*
+ This file implements the function
+
+ template <class VertexAndEdgeListGraph, class DistanceMatrix,
+ class P, class T, class R>
+ bool
+ johnson_all_pairs_shortest_paths
+ (VertexAndEdgeListGraph& g,
+ DistanceMatrix& D,
+ const bgl_named_params<P, T, R>& params)
+ */
+
+#ifndef BOOST_GRAPH_JOHNSON_HPP
+#define BOOST_GRAPH_JOHNSON_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/bellman_ford_shortest_paths.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/type_traits/same_traits.hpp>
+
+namespace boost {
+
+ template <class VertexAndEdgeListGraph, class DistanceMatrix,
+ class VertexID, class Weight, typename BinaryPredicate,
+ typename BinaryFunction, typename Infinity, class DistanceZero>
+ bool
+ johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1,
+ DistanceMatrix& D,
+ VertexID id1, Weight w1, const BinaryPredicate& compare,
+ const BinaryFunction& combine, const Infinity& inf,
+ DistanceZero zero)
+ {
+ typedef graph_traits<VertexAndEdgeListGraph> Traits1;
+ typedef typename property_traits<Weight>::value_type DT;
+ function_requires< BasicMatrixConcept<DistanceMatrix,
+ typename Traits1::vertices_size_type, DT> >();
+
+ typedef typename Traits1::directed_category DirCat;
+ bool is_undirected = is_same<DirCat, undirected_tag>::value;
+
+ typedef adjacency_list<vecS, vecS, directedS,
+ property< vertex_distance_t, DT>,
+ property< edge_weight_t, DT,
+ property< edge_weight2_t, DT > > > Graph2;
+ typedef graph_traits<Graph2> Traits2;
+
+ Graph2 g2(num_vertices(g1) + 1);
+ typename property_map<Graph2, edge_weight_t>::type
+ w = get(edge_weight, g2);
+ typename property_map<Graph2, edge_weight2_t>::type
+ w_hat = get(edge_weight2, g2);
+ typename property_map<Graph2, vertex_distance_t>::type
+ d = get(vertex_distance, g2);
+ typedef typename property_map<Graph2, vertex_index_t>::type VertexID2;
+ VertexID2 id2 = get(vertex_index, g2);
+
+ // Construct g2 where V[g2] = V[g1] U {s}
+ // and E[g2] = E[g1] U {(s,v)| v in V[g1]}
+ std::vector<typename Traits1::vertex_descriptor>
+ verts1(num_vertices(g1) + 1);
+ typename Traits2::vertex_descriptor s = *vertices(g2).first;
+ {
+ typename Traits1::vertex_iterator v, v_end;
+ int i = 1;
+ for (tie(v, v_end) = vertices(g1); v != v_end; ++v, ++i) {
+ typename Traits2::edge_descriptor e; bool z;
+ tie(e, z) = add_edge(s, get(id1, *v) + 1, g2);
+ put(w, e, zero);
+ verts1[i] = *v;
+ }
+ typename Traits1::edge_iterator e, e_end;
+ for (tie(e, e_end) = edges(g1); e != e_end; ++e) {
+ typename Traits2::edge_descriptor e2; bool z;
+ tie(e2, z) = add_edge(get(id1, source(*e, g1)) + 1,
+ get(id1, target(*e, g1)) + 1, g2);
+ put(w, e2, get(w1, *e));
+ if (is_undirected) {
+ tie(e2, z) = add_edge(get(id1, target(*e, g1)) + 1,
+ get(id1, source(*e, g1)) + 1, g2);
+ put(w, e2, get(w1, *e));
+ }
+ }
+ }
+ typename Traits2::vertex_iterator v, v_end, u, u_end;
+ typename Traits2::edge_iterator e, e_end;
+ std::vector<DT> h_vec(num_vertices(g2));
+ typedef typename std::vector<DT>::iterator iter_t;
+ iterator_property_map<iter_t,VertexID2,DT,DT&> h(h_vec.begin(), id2);
+
+ for (tie(v, v_end) = vertices(g2); v != v_end; ++v)
+ d[*v] = inf;
+
+ put(d, s, zero);
+ // Using the non-named parameter versions of bellman_ford and
+ // dijkstra for portability reasons.
+ dummy_property_map pred; bellman_visitor<> bvis;
+ if (bellman_ford_shortest_paths
+ (g2, num_vertices(g2), w, pred, d, combine, compare, bvis)) {
+ for (tie(v, v_end) = vertices(g2); v != v_end; ++v)
+ put(h, *v, get(d, *v));
+ // Reweight the edges to remove negatives
+ for (tie(e, e_end) = edges(g2); e != e_end; ++e) {
+ typename Traits2::vertex_descriptor a = source(*e, g2),
+ b = target(*e, g2);
+ put(w_hat, *e, get(w, *e) + get(h, a) - get(h, b));
+ }
+ for (tie(u, u_end) = vertices(g2); u != u_end; ++u) {
+ dijkstra_visitor<> dvis;
+ dijkstra_shortest_paths
+ (g2, *u, pred, d, w_hat, id2, compare, combine, inf, zero,dvis);
+ for (tie(v, v_end) = vertices(g2); v != v_end; ++v) {
+ if (*u != s && *v != s) {
+ typename Traits1::vertex_descriptor u1, v1;
+ u1 = verts1[id2[*u]]; v1 = verts1[id2[*v]];
+ D[id2[*u]-1][id2[*v]-1] = get(d, *v) + get(h, *v) - get(h, *u);
+ }
+ }
+ }
+ return true;
+ } else
+ return false;
+ }
+
+ template <class VertexAndEdgeListGraph, class DistanceMatrix,
+ class VertexID, class Weight, class DistanceZero>
+ bool
+ johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1,
+ DistanceMatrix& D,
+ VertexID id1, Weight w1, DistanceZero zero)
+ {
+ typedef typename property_traits<Weight>::value_type WT;
+ return johnson_all_pairs_shortest_paths(g1, D, id1, w1,
+ std::less<WT>(),
+ closed_plus<WT>(),
+ (std::numeric_limits<WT>::max)(),
+ zero);
+ }
+
+ namespace detail {
+
+ template <class VertexAndEdgeListGraph, class DistanceMatrix,
+ class P, class T, class R, class Weight,
+ class VertexID>
+ bool
+ johnson_dispatch(VertexAndEdgeListGraph& g,
+ DistanceMatrix& D,
+ const bgl_named_params<P, T, R>& params,
+ Weight w, VertexID id)
+ {
+ typedef typename property_traits<Weight>::value_type WT;
+
+ return johnson_all_pairs_shortest_paths
+ (g, D, id, w,
+ choose_param(get_param(params, distance_compare_t()),
+ std::less<WT>()),
+ choose_param(get_param(params, distance_combine_t()),
+ closed_plus<WT>()),
+ choose_param(get_param(params, distance_inf_t()),
+ std::numeric_limits<WT>::max BOOST_PREVENT_MACRO_SUBSTITUTION()),
+ choose_param(get_param(params, distance_zero_t()), WT()) );
+ }
+
+ } // namespace detail
+
+ template <class VertexAndEdgeListGraph, class DistanceMatrix,
+ class P, class T, class R>
+ bool
+ johnson_all_pairs_shortest_paths
+ (VertexAndEdgeListGraph& g,
+ DistanceMatrix& D,
+ const bgl_named_params<P, T, R>& params)
+ {
+ return detail::johnson_dispatch
+ (g, D, params,
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index)
+ );
+ }
+
+ template <class VertexAndEdgeListGraph, class DistanceMatrix>
+ bool
+ johnson_all_pairs_shortest_paths
+ (VertexAndEdgeListGraph& g, DistanceMatrix& D)
+ {
+ bgl_named_params<int,int> params(1);
+ return detail::johnson_dispatch
+ (g, D, params, get(edge_weight, g), get(vertex_index, g));
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_JOHNSON_HPP
+
+
Added: branches/CMake/release/libs/graph/include/boost/graph/kamada_kawai_spring_layout.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/kamada_kawai_spring_layout.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,542 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// 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)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP
+#define BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/johnson_all_pairs_shortest.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <utility>
+#include <iterator>
+#include <vector>
+#include <boost/limits.hpp>
+#include <cmath>
+
+namespace boost {
+ namespace detail { namespace graph {
+ /**
+ * Denotes an edge or display area side length used to scale a
+ * Kamada-Kawai drawing.
+ */
+ template<bool Edge, typename T>
+ struct edge_or_side
+ {
+ explicit edge_or_side(T value) : value(value) {}
+
+ T value;
+ };
+
+ /**
+ * Compute the edge length from an edge length. This is trivial.
+ */
+ template<typename Graph, typename DistanceMap, typename IndexMap,
+ typename T>
+ T compute_edge_length(const Graph&, DistanceMap, IndexMap,
+ edge_or_side<true, T> length)
+ { return length.value; }
+
+ /**
+ * Compute the edge length based on the display area side
+ length. We do this by dividing the side length by the largest
+ shortest distance between any two vertices in the graph.
+ */
+ template<typename Graph, typename DistanceMap, typename IndexMap,
+ typename T>
+ T
+ compute_edge_length(const Graph& g, DistanceMap distance, IndexMap index,
+ edge_or_side<false, T> length)
+ {
+ T result(0);
+
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
+
+ for (vertex_iterator ui = vertices(g).first, end = vertices(g).second;
+ ui != end; ++ui) {
+ vertex_iterator vi = ui;
+ for (++vi; vi != end; ++vi) {
+ T dij = distance[get(index, *ui)][get(index, *vi)];
+ if (dij > result) result = dij;
+ }
+ }
+ return length.value / result;
+ }
+
+ /**
+ * Implementation of the Kamada-Kawai spring layout algorithm.
+ */
+ template<typename Graph, typename PositionMap, typename WeightMap,
+ typename EdgeOrSideLength, typename Done,
+ typename VertexIndexMap, typename DistanceMatrix,
+ typename SpringStrengthMatrix, typename PartialDerivativeMap>
+ struct kamada_kawai_spring_layout_impl
+ {
+ typedef typename property_traits<WeightMap>::value_type weight_type;
+ typedef std::pair<weight_type, weight_type> deriv_type;
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
+ typedef typename graph_traits<Graph>::vertex_descriptor
+ vertex_descriptor;
+
+ kamada_kawai_spring_layout_impl(
+ const Graph& g,
+ PositionMap position,
+ WeightMap weight,
+ EdgeOrSideLength edge_or_side_length,
+ Done done,
+ weight_type spring_constant,
+ VertexIndexMap index,
+ DistanceMatrix distance,
+ SpringStrengthMatrix spring_strength,
+ PartialDerivativeMap partial_derivatives)
+ : g(g), position(position), weight(weight),
+ edge_or_side_length(edge_or_side_length), done(done),
+ spring_constant(spring_constant), index(index), distance(distance),
+ spring_strength(spring_strength),
+ partial_derivatives(partial_derivatives) {}
+
+ // Compute contribution of vertex i to the first partial
+ // derivatives (dE/dx_m, dE/dy_m) (for vertex m)
+ deriv_type
+ compute_partial_derivative(vertex_descriptor m, vertex_descriptor i)
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif // BOOST_NO_STDC_NAMESPACE
+
+ deriv_type result(0, 0);
+ if (i != m) {
+ weight_type x_diff = position[m].x - position[i].x;
+ weight_type y_diff = position[m].y - position[i].y;
+ weight_type dist = sqrt(x_diff * x_diff + y_diff * y_diff);
+ result.first = spring_strength[get(index, m)][get(index, i)]
+ * (x_diff - distance[get(index, m)][get(index, i)]*x_diff/dist);
+ result.second = spring_strength[get(index, m)][get(index, i)]
+ * (y_diff - distance[get(index, m)][get(index, i)]*y_diff/dist);
+ }
+
+ return result;
+ }
+
+ // Compute partial derivatives dE/dx_m and dE/dy_m
+ deriv_type
+ compute_partial_derivatives(vertex_descriptor m)
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif // BOOST_NO_STDC_NAMESPACE
+
+ deriv_type result(0, 0);
+
+ // TBD: looks like an accumulate to me
+ std::pair<vertex_iterator, vertex_iterator> verts = vertices(g);
+ for (/* no init */; verts.first != verts.second; ++verts.first) {
+ vertex_descriptor i = *verts.first;
+ deriv_type deriv = compute_partial_derivative(m, i);
+ result.first += deriv.first;
+ result.second += deriv.second;
+ }
+
+ return result;
+ }
+
+ // The actual Kamada-Kawai spring layout algorithm implementation
+ bool run()
+ {
+#ifndef BOOST_NO_STDC_NAMESPACE
+ using std::sqrt;
+#endif // BOOST_NO_STDC_NAMESPACE
+
+ // Compute d_{ij} and place it in the distance matrix
+ if (!johnson_all_pairs_shortest_paths(g, distance, index, weight,
+ weight_type(0)))
+ return false;
+
+ // Compute L based on side length (if needed), or retrieve L
+ weight_type edge_length =
+ detail::graph::compute_edge_length(g, distance, index,
+ edge_or_side_length);
+
+ // Compute l_{ij} and k_{ij}
+ const weight_type K = spring_constant;
+ vertex_iterator ui, end = vertices(g).second;
+ for (ui = vertices(g).first; ui != end; ++ui) {
+ vertex_iterator vi = ui;
+ for (++vi; vi != end; ++vi) {
+ weight_type dij = distance[get(index, *ui)][get(index, *vi)];
+ if (dij == (std::numeric_limits<weight_type>::max)())
+ return false;
+ distance[get(index, *ui)][get(index, *vi)] = edge_length * dij;
+ distance[get(index, *vi)][get(index, *ui)] = edge_length * dij;
+ spring_strength[get(index, *ui)][get(index, *vi)] = K/(dij*dij);
+ spring_strength[get(index, *vi)][get(index, *ui)] = K/(dij*dij);
+ }
+ }
+
+ // Compute Delta_i and find max
+ vertex_descriptor p = *vertices(g).first;
+ weight_type delta_p(0);
+
+ for (ui = vertices(g).first; ui != end; ++ui) {
+ deriv_type deriv = compute_partial_derivatives(*ui);
+ put(partial_derivatives, *ui, deriv);
+
+ weight_type delta =
+ sqrt(deriv.first*deriv.first + deriv.second*deriv.second);
+
+ if (delta > delta_p) {
+ p = *ui;
+ delta_p = delta;
+ }
+ }
+
+ while (!done(delta_p, p, g, true)) {
+ // The contribution p makes to the partial derivatives of
+ // each vertex. Computing this (at O(n) cost) allows us to
+ // update the delta_i values in O(n) time instead of O(n^2)
+ // time.
+ std::vector<deriv_type> p_partials(num_vertices(g));
+ for (ui = vertices(g).first; ui != end; ++ui) {
+ vertex_descriptor i = *ui;
+ p_partials[get(index, i)] = compute_partial_derivative(i, p);
+ }
+
+ do {
+ // Compute the 4 elements of the Jacobian
+ weight_type dE_dx_dx = 0, dE_dx_dy = 0, dE_dy_dx = 0, dE_dy_dy = 0;
+ for (ui = vertices(g).first; ui != end; ++ui) {
+ vertex_descriptor i = *ui;
+ if (i != p) {
+ weight_type x_diff = position[p].x - position[i].x;
+ weight_type y_diff = position[p].y - position[i].y;
+ weight_type dist = sqrt(x_diff * x_diff + y_diff * y_diff);
+ weight_type dist_cubed = dist * dist * dist;
+ weight_type k_mi = spring_strength[get(index,p)][get(index,i)];
+ weight_type l_mi = distance[get(index, p)][get(index, i)];
+ dE_dx_dx += k_mi * (1 - (l_mi * y_diff * y_diff)/dist_cubed);
+ dE_dx_dy += k_mi * l_mi * x_diff * y_diff / dist_cubed;
+ dE_dy_dx += k_mi * l_mi * x_diff * y_diff / dist_cubed;
+ dE_dy_dy += k_mi * (1 - (l_mi * x_diff * x_diff)/dist_cubed);
+ }
+ }
+
+ // Solve for delta_x and delta_y
+ weight_type dE_dx = get(partial_derivatives, p).first;
+ weight_type dE_dy = get(partial_derivatives, p).second;
+
+ weight_type delta_x =
+ (dE_dx_dy * dE_dy - dE_dy_dy * dE_dx)
+ / (dE_dx_dx * dE_dy_dy - dE_dx_dy * dE_dy_dx);
+
+ weight_type delta_y =
+ (dE_dx_dx * dE_dy - dE_dy_dx * dE_dx)
+ / (dE_dy_dx * dE_dx_dy - dE_dx_dx * dE_dy_dy);
+
+
+ // Move p by (delta_x, delta_y)
+ position[p].x += delta_x;
+ position[p].y += delta_y;
+
+ // Recompute partial derivatives and delta_p
+ deriv_type deriv = compute_partial_derivatives(p);
+ put(partial_derivatives, p, deriv);
+
+ delta_p =
+ sqrt(deriv.first*deriv.first + deriv.second*deriv.second);
+ } while (!done(delta_p, p, g, false));
+
+ // Select new p by updating each partial derivative and delta
+ vertex_descriptor old_p = p;
+ for (ui = vertices(g).first; ui != end; ++ui) {
+ deriv_type old_deriv_p = p_partials[get(index, *ui)];
+ deriv_type old_p_partial =
+ compute_partial_derivative(*ui, old_p);
+ deriv_type deriv = get(partial_derivatives, *ui);
+
+ deriv.first += old_p_partial.first - old_deriv_p.first;
+ deriv.second += old_p_partial.second - old_deriv_p.second;
+
+ put(partial_derivatives, *ui, deriv);
+ weight_type delta =
+ sqrt(deriv.first*deriv.first + deriv.second*deriv.second);
+
+ if (delta > delta_p) {
+ p = *ui;
+ delta_p = delta;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ const Graph& g;
+ PositionMap position;
+ WeightMap weight;
+ EdgeOrSideLength edge_or_side_length;
+ Done done;
+ weight_type spring_constant;
+ VertexIndexMap index;
+ DistanceMatrix distance;
+ SpringStrengthMatrix spring_strength;
+ PartialDerivativeMap partial_derivatives;
+ };
+ } } // end namespace detail::graph
+
+ /// States that the given quantity is an edge length.
+ template<typename T>
+ inline detail::graph::edge_or_side<true, T>
+ edge_length(T x)
+ { return detail::graph::edge_or_side<true, T>(x); }
+
+ /// States that the given quantity is a display area side length.
+ template<typename T>
+ inline detail::graph::edge_or_side<false, T>
+ side_length(T x)
+ { return detail::graph::edge_or_side<false, T>(x); }
+
+ /**
+ * \brief Determines when to terminate layout of a particular graph based
+ * on a given relative tolerance.
+ */
+ template<typename T = double>
+ struct layout_tolerance
+ {
+ layout_tolerance(const T& tolerance = T(0.001))
+ : tolerance(tolerance), last_energy((std::numeric_limits<T>::max)()),
+ last_local_energy((std::numeric_limits<T>::max)()) { }
+
+ template<typename Graph>
+ bool
+ operator()(T delta_p,
+ typename boost::graph_traits<Graph>::vertex_descriptor p,
+ const Graph& g,
+ bool global)
+ {
+ if (global) {
+ if (last_energy == (std::numeric_limits<T>::max)()) {
+ last_energy = delta_p;
+ return false;
+ }
+
+ T diff = last_energy - delta_p;
+ if (diff < T(0)) diff = -diff;
+ bool done = (delta_p == T(0) || diff / last_energy < tolerance);
+ last_energy = delta_p;
+ return done;
+ } else {
+ if (last_local_energy == (std::numeric_limits<T>::max)()) {
+ last_local_energy = delta_p;
+ return delta_p == T(0);
+ }
+
+ T diff = last_local_energy - delta_p;
+ bool done = (delta_p == T(0) || (diff / last_local_energy) < tolerance);
+ last_local_energy = delta_p;
+ return done;
+ }
+ }
+
+ private:
+ T tolerance;
+ T last_energy;
+ T last_local_energy;
+ };
+
+ /** \brief Kamada-Kawai spring layout for undirected graphs.
+ *
+ * This algorithm performs graph layout (in two dimensions) for
+ * connected, undirected graphs. It operates by relating the layout
+ * of graphs to a dynamic spring system and minimizing the energy
+ * within that system. The strength of a spring between two vertices
+ * is inversely proportional to the square of the shortest distance
+ * (in graph terms) between those two vertices. Essentially,
+ * vertices that are closer in the graph-theoretic sense (i.e., by
+ * following edges) will have stronger springs and will therefore be
+ * placed closer together.
+ *
+ * Prior to invoking this algorithm, it is recommended that the
+ * vertices be placed along the vertices of a regular n-sided
+ * polygon.
+ *
+ * \param g (IN) must be a model of Vertex List Graph, Edge List
+ * Graph, and Incidence Graph and must be undirected.
+ *
+ * \param position (OUT) must be a model of Lvalue Property Map,
+ * where the value type is a class containing fields @c x and @c y
+ * that will be set to the @c x and @c y coordinates of each vertex.
+ *
+ * \param weight (IN) must be a model of Readable Property Map,
+ * which provides the weight of each edge in the graph @p g.
+ *
+ * \param edge_or_side_length (IN) provides either the unit length
+ * @c e of an edge in the layout or the length of a side @c s of the
+ * display area, and must be either @c boost::edge_length(e) or @c
+ * boost::side_length(s), respectively.
+ *
+ * \param done (IN) is a 4-argument function object that is passed
+ * the current value of delta_p (i.e., the energy of vertex @p p),
+ * the vertex @p p, the graph @p g, and a boolean flag indicating
+ * whether @p delta_p is the maximum energy in the system (when @c
+ * true) or the energy of the vertex being moved. Defaults to @c
+ * layout_tolerance instantiated over the value type of the weight
+ * map.
+ *
+ * \param spring_constant (IN) is the constant multiplied by each
+ * spring's strength. Larger values create systems with more energy
+ * that can take longer to stabilize; smaller values create systems
+ * with less energy that stabilize quickly but do not necessarily
+ * result in pleasing layouts. The default value is 1.
+ *
+ * \param index (IN) is a mapping from vertices to index values
+ * between 0 and @c num_vertices(g). The default is @c
+ * get(vertex_index,g).
+ *
+ * \param distance (UTIL/OUT) will be used to store the distance
+ * from every vertex to every other vertex, which is computed in the
+ * first stages of the algorithm. This value's type must be a model
+ * of BasicMatrix with value type equal to the value type of the
+ * weight map. The default is a a vector of vectors.
+ *
+ * \param spring_strength (UTIL/OUT) will be used to store the
+ * strength of the spring between every pair of vertices. This
+ * value's type must be a model of BasicMatrix with value type equal
+ * to the value type of the weight map. The default is a a vector of
+ * vectors.
+ *
+ * \param partial_derivatives (UTIL) will be used to store the
+ * partial derivates of each vertex with respect to the @c x and @c
+ * y coordinates. This must be a Read/Write Property Map whose value
+ * type is a pair with both types equivalent to the value type of
+ * the weight map. The default is an iterator property map.
+ *
+ * \returns @c true if layout was successful or @c false if a
+ * negative weight cycle was detected.
+ */
+ template<typename Graph, typename PositionMap, typename WeightMap,
+ typename T, bool EdgeOrSideLength, typename Done,
+ typename VertexIndexMap, typename DistanceMatrix,
+ typename SpringStrengthMatrix, typename PartialDerivativeMap>
+ bool
+ kamada_kawai_spring_layout(
+ const Graph& g,
+ PositionMap position,
+ WeightMap weight,
+ detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length,
+ Done done,
+ typename property_traits<WeightMap>::value_type spring_constant,
+ VertexIndexMap index,
+ DistanceMatrix distance,
+ SpringStrengthMatrix spring_strength,
+ PartialDerivativeMap partial_derivatives)
+ {
+ BOOST_STATIC_ASSERT((is_convertible<
+ typename graph_traits<Graph>::directed_category*,
+ undirected_tag*
+ >::value));
+
+ detail::graph::kamada_kawai_spring_layout_impl<
+ Graph, PositionMap, WeightMap,
+ detail::graph::edge_or_side<EdgeOrSideLength, T>, Done, VertexIndexMap,
+ DistanceMatrix, SpringStrengthMatrix, PartialDerivativeMap>
+ alg(g, position, weight, edge_or_side_length, done, spring_constant,
+ index, distance, spring_strength, partial_derivatives);
+ return alg.run();
+ }
+
+ /**
+ * \overload
+ */
+ template<typename Graph, typename PositionMap, typename WeightMap,
+ typename T, bool EdgeOrSideLength, typename Done,
+ typename VertexIndexMap>
+ bool
+ kamada_kawai_spring_layout(
+ const Graph& g,
+ PositionMap position,
+ WeightMap weight,
+ detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length,
+ Done done,
+ typename property_traits<WeightMap>::value_type spring_constant,
+ VertexIndexMap index)
+ {
+ typedef typename property_traits<WeightMap>::value_type weight_type;
+
+ typename graph_traits<Graph>::vertices_size_type n = num_vertices(g);
+ typedef std::vector<weight_type> weight_vec;
+
+ std::vector<weight_vec> distance(n, weight_vec(n));
+ std::vector<weight_vec> spring_strength(n, weight_vec(n));
+ std::vector<std::pair<weight_type, weight_type> > partial_derivatives(n);
+
+ return
+ kamada_kawai_spring_layout(
+ g, position, weight, edge_or_side_length, done, spring_constant, index,
+ distance.begin(),
+ spring_strength.begin(),
+ make_iterator_property_map(partial_derivatives.begin(), index,
+ std::pair<weight_type, weight_type>()));
+ }
+
+ /**
+ * \overload
+ */
+ template<typename Graph, typename PositionMap, typename WeightMap,
+ typename T, bool EdgeOrSideLength, typename Done>
+ bool
+ kamada_kawai_spring_layout(
+ const Graph& g,
+ PositionMap position,
+ WeightMap weight,
+ detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length,
+ Done done,
+ typename property_traits<WeightMap>::value_type spring_constant)
+ {
+ return kamada_kawai_spring_layout(g, position, weight, edge_or_side_length,
+ done, spring_constant,
+ get(vertex_index, g));
+ }
+
+ /**
+ * \overload
+ */
+ template<typename Graph, typename PositionMap, typename WeightMap,
+ typename T, bool EdgeOrSideLength, typename Done>
+ bool
+ kamada_kawai_spring_layout(
+ const Graph& g,
+ PositionMap position,
+ WeightMap weight,
+ detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length,
+ Done done)
+ {
+ typedef typename property_traits<WeightMap>::value_type weight_type;
+ return kamada_kawai_spring_layout(g, position, weight, edge_or_side_length,
+ done, weight_type(1));
+ }
+
+ /**
+ * \overload
+ */
+ template<typename Graph, typename PositionMap, typename WeightMap,
+ typename T, bool EdgeOrSideLength>
+ bool
+ kamada_kawai_spring_layout(
+ const Graph& g,
+ PositionMap position,
+ WeightMap weight,
+ detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length)
+ {
+ typedef typename property_traits<WeightMap>::value_type weight_type;
+ return kamada_kawai_spring_layout(g, position, weight, edge_or_side_length,
+ layout_tolerance<weight_type>(),
+ weight_type(1.0),
+ get(vertex_index, g));
+ }
+} // end namespace boost
+
+#endif // BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/king_ordering.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/king_ordering.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,320 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2004, 2005 Trustees of Indiana University
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek,
+// Doug Gregor, D. Kevin McGrath
+//
+// 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)
+//=======================================================================//
+#ifndef BOOST_GRAPH_KING_HPP
+#define BOOST_GRAPH_KING_HPP
+
+#include <boost/config.hpp>
+#include <boost/graph/detail/sparse_ordering.hpp>
+
+/*
+ King Algorithm for matrix reordering
+*/
+
+namespace boost {
+ namespace detail {
+ template<typename OutputIterator, typename Buffer, typename Compare,
+ typename PseudoDegreeMap, typename VecMap, typename VertexIndexMap>
+ class bfs_king_visitor:public default_bfs_visitor
+ {
+ public:
+ bfs_king_visitor(OutputIterator *iter, Buffer *b, Compare compare,
+ PseudoDegreeMap deg, std::vector<int> loc, VecMap color,
+ VertexIndexMap vertices):
+ permutation(iter), Qptr(b), degree(deg), comp(compare),
+ Qlocation(loc), colors(color), vertex_map(vertices) { }
+
+ template <typename Vertex, typename Graph>
+ void finish_vertex(Vertex, Graph& g) {
+ typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
+ Vertex v, w;
+
+ typedef typename std::deque<Vertex>::iterator iterator;
+ typedef typename std::deque<Vertex>::reverse_iterator reverse_iterator;
+
+ reverse_iterator rend = Qptr->rend()-index_begin;
+ reverse_iterator rbegin = Qptr->rbegin();
+
+
+ //heap the vertices already there
+ std::make_heap(rbegin, rend, boost::bind<bool>(comp, _2, _1));
+
+ unsigned i = 0;
+
+ for(i = index_begin; i != Qptr->size(); ++i){
+ colors[get(vertex_map, (*Qptr)[i])] = 1;
+ Qlocation[get(vertex_map, (*Qptr)[i])] = i;
+ }
+
+ i = 0;
+
+ for( ; rbegin != rend; rend--){
+ percolate_down<Vertex>(i);
+ w = (*Qptr)[index_begin+i];
+ for (tie(ei, ei_end) = out_edges(w, g); ei != ei_end; ++ei) {
+ v = target(*ei, g);
+ put(degree, v, get(degree, v) - 1);
+
+ if (colors[get(vertex_map, v)] == 1) {
+ percolate_up<Vertex>(get(vertex_map, v), i);
+ }
+ }
+
+ colors[get(vertex_map, w)] = 0;
+ i++;
+ }
+ }
+
+ template <typename Vertex, typename Graph>
+ void examine_vertex(Vertex u, const Graph&) {
+
+ *(*permutation)++ = u;
+ index_begin = Qptr->size();
+
+ }
+ protected:
+
+
+ //this function replaces pop_heap, and tracks state information
+ template <typename Vertex>
+ void percolate_down(int offset){
+ typedef typename std::deque<Vertex>::reverse_iterator reverse_iterator;
+
+ int heap_last = index_begin + offset;
+ int heap_first = Qptr->size() - 1;
+
+ //pop_heap functionality:
+ //swap first, last
+ std::swap((*Qptr)[heap_last], (*Qptr)[heap_first]);
+
+ //swap in the location queue
+ std::swap(Qlocation[heap_first], Qlocation[heap_last]);
+
+ //set drifter, children
+ int drifter = heap_first;
+ int drifter_heap = Qptr->size() - drifter;
+
+ int right_child_heap = drifter_heap * 2 + 1;
+ int right_child = Qptr->size() - right_child_heap;
+
+ int left_child_heap = drifter_heap * 2;
+ int left_child = Qptr->size() - left_child_heap;
+
+ //check that we are staying in the heap
+ bool valid = (right_child < heap_last) ? false : true;
+
+ //pick smallest child of drifter, and keep in mind there might only be left child
+ int smallest_child = (valid && get(degree, (*Qptr)[left_child]) > get(degree,(*Qptr)[right_child])) ?
+ right_child : left_child;
+
+ while(valid && smallest_child < heap_last && comp((*Qptr)[drifter], (*Qptr)[smallest_child])){
+
+ //if smallest child smaller than drifter, swap them
+ std::swap((*Qptr)[smallest_child], (*Qptr)[drifter]);
+ std::swap(Qlocation[drifter], Qlocation[smallest_child]);
+
+ //update the values, run again, as necessary
+ drifter = smallest_child;
+ drifter_heap = Qptr->size() - drifter;
+
+ right_child_heap = drifter_heap * 2 + 1;
+ right_child = Qptr->size() - right_child_heap;
+
+ left_child_heap = drifter_heap * 2;
+ left_child = Qptr->size() - left_child_heap;
+
+ valid = (right_child < heap_last) ? false : true;
+
+ smallest_child = (valid && get(degree, (*Qptr)[left_child]) > get(degree,(*Qptr)[right_child])) ?
+ right_child : left_child;
+ }
+
+ }
+
+
+
+ // this is like percolate down, but we always compare against the
+ // parent, as there is only a single choice
+ template <typename Vertex>
+ void percolate_up(int vertex, int offset){
+
+ int child_location = Qlocation[vertex];
+ int heap_child_location = Qptr->size() - child_location;
+ int heap_parent_location = (int)(heap_child_location/2);
+ unsigned parent_location = Qptr->size() - heap_parent_location;
+
+ bool valid = (heap_parent_location != 0 && child_location > index_begin + offset &&
+ parent_location < Qptr->size());
+
+ while(valid && comp((*Qptr)[child_location], (*Qptr)[parent_location])){
+
+ //swap in the heap
+ std::swap((*Qptr)[child_location], (*Qptr)[parent_location]);
+
+ //swap in the location queue
+ std::swap(Qlocation[child_location], Qlocation[parent_location]);
+
+ child_location = parent_location;
+ heap_child_location = heap_parent_location;
+ heap_parent_location = (int)(heap_child_location/2);
+ parent_location = Qptr->size() - heap_parent_location;
+ valid = (heap_parent_location != 0 && child_location > index_begin + offset);
+ }
+ }
+
+ OutputIterator *permutation;
+ int index_begin;
+ Buffer *Qptr;
+ PseudoDegreeMap degree;
+ Compare comp;
+ std::vector<int> Qlocation;
+ VecMap colors;
+ VertexIndexMap vertex_map;
+ };
+
+
+ } // namespace detail
+
+
+ template<class Graph, class OutputIterator, class ColorMap, class DegreeMap,
+ typename VertexIndexMap>
+ OutputIterator
+ king_ordering(const Graph& g,
+ std::deque< typename graph_traits<Graph>::vertex_descriptor >
+ vertex_queue,
+ OutputIterator permutation,
+ ColorMap color, DegreeMap degree,
+ VertexIndexMap index_map)
+ {
+ typedef typename property_traits<DegreeMap>::value_type ds_type;
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef iterator_property_map<typename std::vector<ds_type>::iterator, VertexIndexMap, ds_type, ds_type&> PseudoDegreeMap;
+ typedef indirect_cmp<PseudoDegreeMap, std::less<ds_type> > Compare;
+ typedef typename boost::sparse::sparse_ordering_queue<Vertex> queue;
+ typedef typename detail::bfs_king_visitor<OutputIterator, queue, Compare,
+ PseudoDegreeMap, std::vector<int>, VertexIndexMap > Visitor;
+ typedef typename graph_traits<Graph>::vertices_size_type
+ vertices_size_type;
+ std::vector<ds_type> pseudo_degree_vec(num_vertices(g));
+ PseudoDegreeMap pseudo_degree(pseudo_degree_vec.begin(), index_map);
+
+ typename graph_traits<Graph>::vertex_iterator ui, ui_end;
+ queue Q;
+ // Copy degree to pseudo_degree
+ // initialize the color map
+ for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui){
+ put(pseudo_degree, *ui, get(degree, *ui));
+ put(color, *ui, Color::white());
+ }
+
+ Compare comp(pseudo_degree);
+ std::vector<int> colors(num_vertices(g));
+
+ for(vertices_size_type i = 0; i < num_vertices(g); i++)
+ colors[i] = 0;
+
+ std::vector<int> loc(num_vertices(g));
+
+ //create the visitor
+ Visitor vis(&permutation, &Q, comp, pseudo_degree, loc, colors, index_map);
+
+ while( !vertex_queue.empty() ) {
+ Vertex s = vertex_queue.front();
+ vertex_queue.pop_front();
+
+ //call BFS with visitor
+ breadth_first_visit(g, s, Q, vis, color);
+ }
+
+ return permutation;
+ }
+
+
+ // This is the case where only a single starting vertex is supplied.
+ template <class Graph, class OutputIterator,
+ class ColorMap, class DegreeMap, typename VertexIndexMap>
+ OutputIterator
+ king_ordering(const Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor s,
+ OutputIterator permutation,
+ ColorMap color, DegreeMap degree, VertexIndexMap index_map)
+ {
+
+ std::deque< typename graph_traits<Graph>::vertex_descriptor > vertex_queue;
+ vertex_queue.push_front( s );
+ return king_ordering(g, vertex_queue, permutation, color, degree,
+ index_map);
+ }
+
+
+ template < class Graph, class OutputIterator,
+ class ColorMap, class DegreeMap, class VertexIndexMap>
+ OutputIterator
+ king_ordering(const Graph& G, OutputIterator permutation,
+ ColorMap color, DegreeMap degree, VertexIndexMap index_map)
+ {
+ if (vertices(G).first == vertices(G).second)
+ return permutation;
+
+ typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename boost::graph_traits<Graph>::vertex_iterator VerIter;
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+
+ std::deque<Vertex> vertex_queue;
+
+ // Mark everything white
+ BGL_FORALL_VERTICES_T(v, G, Graph) put(color, v, Color::white());
+
+ // Find one vertex from each connected component
+ BGL_FORALL_VERTICES_T(v, G, Graph) {
+ if (get(color, v) == Color::white()) {
+ depth_first_visit(G, v, dfs_visitor<>(), color);
+ vertex_queue.push_back(v);
+ }
+ }
+
+ // Find starting nodes for all vertices
+ // TBD: How to do this with a directed graph?
+ for (typename std::deque<Vertex>::iterator i = vertex_queue.begin();
+ i != vertex_queue.end(); ++i)
+ *i = find_starting_node(G, *i, color, degree);
+
+ return king_ordering(G, vertex_queue, permutation, color, degree,
+ index_map);
+ }
+
+ template<typename Graph, typename OutputIterator, typename VertexIndexMap>
+ OutputIterator
+ king_ordering(const Graph& G, OutputIterator permutation,
+ VertexIndexMap index_map)
+ {
+ if (vertices(G).first == vertices(G).second)
+ return permutation;
+
+ typedef out_degree_property_map<Graph> DegreeMap;
+ std::vector<default_color_type> colors(num_vertices(G));
+ return king_ordering(G, permutation,
+ make_iterator_property_map(&colors[0], index_map,
+ colors[0]),
+ make_out_degree_map(G), index_map);
+ }
+
+ template<typename Graph, typename OutputIterator>
+ inline OutputIterator
+ king_ordering(const Graph& G, OutputIterator permutation)
+ { return king_ordering(G, permutation, get(vertex_index, G)); }
+
+} // namespace boost
+
+
+#endif // BOOST_GRAPH_KING_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/kolmogorov_max_flow.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/kolmogorov_max_flow.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,807 @@
+// Copyright (c) 2006, Stephan Diederich
+//
+// This code may be used under either of the following two licences:
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE.
+//
+// Or:
+//
+// 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)
+
+#ifndef BOOST_KOLMOGOROV_MAX_FLOW_HPP
+#define BOOST_KOLMOGOROV_MAX_FLOW_HPP
+
+#include <boost/config.hpp>
+#include <cassert>
+#include <vector>
+#include <list>
+#include <utility>
+#include <iosfwd>
+#include <algorithm> // for std::min and std::max
+
+#include <boost/pending/queue.hpp>
+#include <boost/limits.hpp>
+#include <boost/property_map.hpp>
+#include <boost/none_t.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/named_function_params.hpp>
+
+namespace boost {
+ namespace detail {
+
+ template <class Graph,
+ class EdgeCapacityMap,
+ class ResidualCapacityEdgeMap,
+ class ReverseEdgeMap,
+ class PredecessorMap,
+ class ColorMap,
+ class DistanceMap,
+ class IndexMap>
+ class kolmogorov{
+ typedef typename property_traits<EdgeCapacityMap>::value_type tEdgeVal;
+ typedef graph_traits<Graph> tGraphTraits;
+ typedef typename tGraphTraits::vertex_iterator vertex_iterator;
+ typedef typename tGraphTraits::vertex_descriptor vertex_descriptor;
+ typedef typename tGraphTraits::edge_descriptor edge_descriptor;
+ typedef typename tGraphTraits::edge_iterator edge_iterator;
+ typedef typename tGraphTraits::out_edge_iterator out_edge_iterator;
+ typedef boost::queue<vertex_descriptor> tQueue; //queue of vertices, used in adoption-stage
+ typedef typename property_traits<ColorMap>::value_type tColorValue;
+ typedef color_traits<tColorValue> tColorTraits;
+ typedef typename property_traits<DistanceMap>::value_type tDistanceVal;
+
+ public:
+ kolmogorov(Graph& g,
+ EdgeCapacityMap cap,
+ ResidualCapacityEdgeMap res,
+ ReverseEdgeMap rev,
+ PredecessorMap pre,
+ ColorMap color,
+ DistanceMap dist,
+ IndexMap idx,
+ vertex_descriptor src,
+ vertex_descriptor sink):
+ m_g(g),
+ m_index_map(idx),
+ m_cap_map(cap),
+ m_res_cap_map(res),
+ m_rev_edge_map(rev),
+ m_pre_map(pre),
+ m_tree_map(color),
+ m_dist_map(dist),
+ m_source(src),
+ m_sink(sink),
+ m_active_nodes(),
+ m_in_active_list_vec(num_vertices(g), false),
+ m_in_active_list_map(make_iterator_property_map(m_in_active_list_vec.begin(), m_index_map)),
+ m_has_parent_vec(num_vertices(g), false),
+ m_has_parent_map(make_iterator_property_map(m_has_parent_vec.begin(), m_index_map)),
+ m_time_vec(num_vertices(g), 0),
+ m_time_map(make_iterator_property_map(m_time_vec.begin(), m_index_map)),
+ m_flow(0),
+ m_time(1),
+ m_last_grow_vertex(graph_traits<Graph>::null_vertex()){
+ // initialize the color-map with gray-values
+ vertex_iterator vi, v_end;
+ for(tie(vi, v_end) = vertices(m_g); vi != v_end; ++vi){
+ set_tree(*vi, tColorTraits::gray());
+ }
+ // Initialize flow to zero which means initializing
+ // the residual capacity equal to the capacity
+ edge_iterator ei, e_end;
+ for(tie(ei, e_end) = edges(m_g); ei != e_end; ++ei) {
+ m_res_cap_map[*ei] = m_cap_map[*ei];
+ assert(m_rev_edge_map[m_rev_edge_map[*ei]] == *ei); //check if the reverse edge map is build up properly
+ }
+ //init the search trees with the two terminals
+ set_tree(m_source, tColorTraits::black());
+ set_tree(m_sink, tColorTraits::white());
+ m_time_map[m_source] = 1;
+ m_time_map[m_sink] = 1;
+ }
+
+ ~kolmogorov(){}
+
+ tEdgeVal max_flow(){
+ //augment direct paths from SOURCE->SINK and SOURCE->VERTEX->SINK
+ augment_direct_paths();
+ //start the main-loop
+ while(true){
+ bool path_found;
+ edge_descriptor connecting_edge;
+ tie(connecting_edge, path_found) = grow(); //find a path from source to sink
+ if(!path_found){
+ //we're finished, no more paths were found
+ break;
+ }
+ ++m_time;
+ augment(connecting_edge); //augment that path
+ adopt(); //rebuild search tree structure
+ }
+ return m_flow;
+ }
+
+ //the complete class is protected, as we want access to members in derived test-class (see $(BOOST_ROOT)/libs/graph/test/kolmogorov_max_flow_test.cpp)
+ protected:
+ void augment_direct_paths(){
+ //in a first step, we augment all direct paths from source->NODE->sink
+ //and additionally paths from source->sink
+ //this improves especially graphcuts for segmentation, as most of the nodes have source/sink connects
+ //but shouldn't have an impact on other maxflow problems (this is done in grow() anyway)
+ out_edge_iterator ei, e_end;
+ for(tie(ei, e_end) = out_edges(m_source, m_g); ei != e_end; ++ei){
+ edge_descriptor from_source = *ei;
+ vertex_descriptor current_node = target(from_source, m_g);
+ if(current_node == m_sink){
+ tEdgeVal cap = m_res_cap_map[from_source];
+ m_res_cap_map[from_source] = 0;
+ m_flow += cap;
+ continue;
+ }
+ edge_descriptor to_sink;
+ bool is_there;
+ tie(to_sink, is_there) = edge(current_node, m_sink, m_g);
+ if(is_there){
+ tEdgeVal cap_from_source = m_res_cap_map[from_source];
+ tEdgeVal cap_to_sink = m_res_cap_map[to_sink];
+ if(cap_from_source > cap_to_sink){
+ set_tree(current_node, tColorTraits::black());
+ add_active_node(current_node);
+ set_edge_to_parent(current_node, from_source);
+ m_dist_map[current_node] = 1;
+ m_time_map[current_node] = 1;
+ //add stuff to flow and update residuals
+ //we dont need to update reverse_edges, as incoming/outgoing edges to/from source/sink don't count for max-flow
+ m_res_cap_map[from_source] -= cap_to_sink;
+ m_res_cap_map[to_sink] = 0;
+ m_flow += cap_to_sink;
+ } else if(cap_to_sink > 0){
+ set_tree(current_node, tColorTraits::white());
+ add_active_node(current_node);
+ set_edge_to_parent(current_node, to_sink);
+ m_dist_map[current_node] = 1;
+ m_time_map[current_node] = 1;
+ //add stuff to flow and update residuals
+ //we dont need to update reverse_edges, as incoming/outgoing edges to/from source/sink don't count for max-flow
+ m_res_cap_map[to_sink] -= cap_from_source;
+ m_res_cap_map[from_source] = 0;
+ m_flow += cap_from_source;
+ }
+ } else if(m_res_cap_map[from_source]){
+ //there is no sink connect, so we can't augment this path
+ //but to avoid adding m_source to the active nodes, we just activate this node and set the approciate things
+ set_tree(current_node, tColorTraits::black());
+ set_edge_to_parent(current_node, from_source);
+ m_dist_map[current_node] = 1;
+ m_time_map[current_node] = 1;
+ add_active_node(current_node);
+ }
+ }
+ for(tie(ei, e_end) = out_edges(m_sink, m_g); ei != e_end; ++ei){
+ edge_descriptor to_sink = m_rev_edge_map[*ei];
+ vertex_descriptor current_node = source(to_sink, m_g);
+ if(m_res_cap_map[to_sink]){
+ set_tree(current_node, tColorTraits::white());
+ set_edge_to_parent(current_node, to_sink);
+ m_dist_map[current_node] = 1;
+ m_time_map[current_node] = 1;
+ add_active_node(current_node);
+ }
+ }
+ }
+
+ /**
+ * returns a pair of an edge and a boolean. if the bool is true, the edge is a connection of a found path from s->t , read "the link" and
+ * source(returnVal, m_g) is the end of the path found in the source-tree
+ * target(returnVal, m_g) is the beginning of the path found in the sink-tree
+ */
+ std::pair<edge_descriptor, bool> grow(){
+ assert(m_orphans.empty());
+ vertex_descriptor current_node;
+ while((current_node = get_next_active_node()) != graph_traits<Graph>::null_vertex()){ //if there is one
+ assert(get_tree(current_node) != tColorTraits::gray() && (has_parent(current_node) || current_node==m_source || current_node==m_sink));
+ if(get_tree(current_node) == tColorTraits::black()){
+ //source tree growing
+ out_edge_iterator ei, e_end;
+ if(current_node != m_last_grow_vertex){
+ m_last_grow_vertex = current_node;
+ tie(m_last_grow_edge_it, m_last_grow_edge_end) = out_edges(current_node, m_g);
+ }
+ for(; m_last_grow_edge_it != m_last_grow_edge_end; ++m_last_grow_edge_it){
+ edge_descriptor out_edge = *m_last_grow_edge_it;
+ if(m_res_cap_map[out_edge] > 0){ //check if we have capacity left on this edge
+ vertex_descriptor other_node = target(out_edge, m_g);
+ if(get_tree(other_node) == tColorTraits::gray()){ //it's a free node
+ set_tree(other_node, tColorTraits::black()); //aquire other node to our search tree
+ set_edge_to_parent(other_node, out_edge); //set us as parent
+ m_dist_map[other_node] = m_dist_map[current_node] + 1; //and update the distance-heuristic
+ m_time_map[other_node] = m_time_map[current_node];
+ add_active_node(other_node);
+ } else if(get_tree(other_node) == tColorTraits::black()){
+ if(is_closer_to_terminal(current_node, other_node)){ //we do this to get shorter paths. check if we are nearer to the source as its parent is
+ set_edge_to_parent(other_node, out_edge);
+ m_dist_map[other_node] = m_dist_map[current_node] + 1;
+ m_time_map[other_node] = m_time_map[current_node];
+ }
+ } else{
+ assert(get_tree(other_node)==tColorTraits::white());
+ //kewl, found a path from one to the other search tree, return the connecting edge in src->sink dir
+ return std::make_pair(out_edge, true);
+ }
+ }
+ } //for all out-edges
+ } //source-tree-growing
+ else{
+ assert(get_tree(current_node) == tColorTraits::white());
+ out_edge_iterator ei, e_end;
+ if(current_node != m_last_grow_vertex){
+ m_last_grow_vertex = current_node;
+ tie(m_last_grow_edge_it, m_last_grow_edge_end) = out_edges(current_node, m_g);
+ }
+ for(; m_last_grow_edge_it != m_last_grow_edge_end; ++m_last_grow_edge_it){
+ edge_descriptor in_edge = m_rev_edge_map[*m_last_grow_edge_it];
+ if(m_res_cap_map[in_edge] > 0){ //check if there is capacity left
+ vertex_descriptor other_node = source(in_edge, m_g);
+ if(get_tree(other_node) == tColorTraits::gray()){ //it's a free node
+ set_tree(other_node, tColorTraits::white()); //aquire that node to our search tree
+ set_edge_to_parent(other_node, in_edge); //set us as parent
+ add_active_node(other_node); //activate that node
+ m_dist_map[other_node] = m_dist_map[current_node] + 1; //set its distance
+ m_time_map[other_node] = m_time_map[current_node]; //and time
+ } else if(get_tree(other_node) == tColorTraits::white()){
+ if(is_closer_to_terminal(current_node, other_node)){
+ //we are closer to the sink than its parent is, so we "adopt" him
+ set_edge_to_parent(other_node, in_edge);
+ m_dist_map[other_node] = m_dist_map[current_node] + 1;
+ m_time_map[other_node] = m_time_map[current_node];
+ }
+ } else{
+ assert(get_tree(other_node)==tColorTraits::black());
+ //kewl, found a path from one to the other search tree, return the connecting edge in src->sink dir
+ return std::make_pair(in_edge, true);
+ }
+ }
+ } //for all out-edges
+ } //sink-tree growing
+ //all edges of that node are processed, and no more paths were found. so remove if from the front of the active queue
+ finish_node(current_node);
+ } //while active_nodes not empty
+ return std::make_pair(edge_descriptor(), false); //no active nodes anymore and no path found, we're done
+ }
+
+ /**
+ * augments path from s->t and updates residual graph
+ * source(e, m_g) is the end of the path found in the source-tree
+ * target(e, m_g) is the beginning of the path found in the sink-tree
+ * this phase generates orphans on satured edges, if the attached verts are from different search-trees
+ * orphans are ordered in distance to sink/source. first the farest from the source are front_inserted into the orphans list,
+ * and after that the sink-tree-orphans are front_inserted. when going to adoption stage the orphans are popped_front, and so we process the nearest
+ * verts to the terminals first
+ */
+ void augment(edge_descriptor e){
+ assert(get_tree(target(e, m_g)) == tColorTraits::white());
+ assert(get_tree(source(e, m_g)) == tColorTraits::black());
+ assert(m_orphans.empty());
+
+ const tEdgeVal bottleneck = find_bottleneck(e);
+ //now we push the found flow through the path
+ //for each edge we saturate we have to look for the verts that belong to that edge, one of them becomes an orphans
+ //now process the connecting edge
+ m_res_cap_map[e] -= bottleneck;
+ assert(m_res_cap_map[e] >= 0);
+ m_res_cap_map[m_rev_edge_map[e]] += bottleneck;
+
+ //now we follow the path back to the source
+ vertex_descriptor current_node = source(e, m_g);
+ while(current_node != m_source){
+ edge_descriptor pred = get_edge_to_parent(current_node);
+ m_res_cap_map[pred] -= bottleneck;
+ assert(m_res_cap_map[pred] >= 0);
+ m_res_cap_map[m_rev_edge_map[pred]] += bottleneck;
+ if(m_res_cap_map[pred] == 0){
+ set_no_parent(current_node);
+ m_orphans.push_front(current_node);
+ }
+ current_node = source(pred, m_g);
+ }
+ //then go forward in the sink-tree
+ current_node = target(e, m_g);
+ while(current_node != m_sink){
+ edge_descriptor pred = get_edge_to_parent(current_node);
+ m_res_cap_map[pred] -= bottleneck;
+ assert(m_res_cap_map[pred] >= 0);
+ m_res_cap_map[m_rev_edge_map[pred]] += bottleneck;
+ if(m_res_cap_map[pred] == 0){
+ set_no_parent(current_node);
+ m_orphans.push_front(current_node);
+ }
+ current_node = target(pred, m_g);
+ }
+ //and add it to the max-flow
+ m_flow += bottleneck;
+ }
+
+ /**
+ * returns the bottleneck of a s->t path (end_of_path is last vertex in source-tree, begin_of_path is first vertex in sink-tree)
+ */
+ inline tEdgeVal find_bottleneck(edge_descriptor e){
+ BOOST_USING_STD_MIN();
+ tEdgeVal minimum_cap = m_res_cap_map[e];
+ vertex_descriptor current_node = source(e, m_g);
+ //first go back in the source tree
+ while(current_node != m_source){
+ edge_descriptor pred = get_edge_to_parent(current_node);
+ minimum_cap = min BOOST_PREVENT_MACRO_SUBSTITUTION(minimum_cap, m_res_cap_map[pred]);
+ current_node = source(pred, m_g);
+ }
+ //then go forward in the sink-tree
+ current_node = target(e, m_g);
+ while(current_node != m_sink){
+ edge_descriptor pred = get_edge_to_parent(current_node);
+ minimum_cap = min BOOST_PREVENT_MACRO_SUBSTITUTION(minimum_cap, m_res_cap_map[pred]);
+ current_node = target(pred, m_g);
+ }
+ return minimum_cap;
+ }
+
+ /**
+ * rebuild search trees
+ * empty the queue of orphans, and find new parents for them or just drop them from the search trees
+ */
+ void adopt(){
+ while(!m_orphans.empty() || !m_child_orphans.empty()){
+ vertex_descriptor current_node;
+ if(m_child_orphans.empty()){
+ //get the next orphan from the main-queue and remove it
+ current_node = m_orphans.front();
+ m_orphans.pop_front();
+ } else{
+ current_node = m_child_orphans.front();
+ m_child_orphans.pop();
+ }
+ if(get_tree(current_node) == tColorTraits::black()){
+ //we're in the source-tree
+ tDistanceVal min_distance = (std::numeric_limits<tDistanceVal>::max)();
+ edge_descriptor new_parent_edge;
+ out_edge_iterator ei, e_end;
+ for(tie(ei, e_end) = out_edges(current_node, m_g); ei != e_end; ++ei){
+ const edge_descriptor in_edge = m_rev_edge_map[*ei];
+ assert(target(in_edge, m_g) == current_node); //we should be the target of this edge
+ if(m_res_cap_map[in_edge] > 0){
+ vertex_descriptor other_node = source(in_edge, m_g);
+ if(get_tree(other_node) == tColorTraits::black() && has_source_connect(other_node)){
+ if(m_dist_map[other_node] < min_distance){
+ min_distance = m_dist_map[other_node];
+ new_parent_edge = in_edge;
+ }
+ }
+ }
+ }
+ if(min_distance != (std::numeric_limits<tDistanceVal>::max)()){
+ set_edge_to_parent(current_node, new_parent_edge);
+ m_dist_map[current_node] = min_distance + 1;
+ m_time_map[current_node] = m_time;
+ } else{
+ m_time_map[current_node] = 0;
+ for(tie(ei, e_end) = out_edges(current_node, m_g); ei != e_end; ++ei){
+ edge_descriptor in_edge = m_rev_edge_map[*ei];
+ vertex_descriptor other_node = source(in_edge, m_g);
+ if(get_tree(other_node) == tColorTraits::black() && has_parent(other_node)){
+ if(m_res_cap_map[in_edge] > 0){
+ add_active_node(other_node);
+ }
+ if(source(get_edge_to_parent(other_node), m_g) == current_node){
+ //we are the parent of that node
+ //it has to find a new parent, too
+ set_no_parent(other_node);
+ m_child_orphans.push(other_node);
+ }
+ }
+ }
+ set_tree(current_node, tColorTraits::gray());
+ } //no parent found
+ } //source-tree-adoption
+ else{
+ //now we should be in the sink-tree, check that...
+ assert(get_tree(current_node) == tColorTraits::white());
+ out_edge_iterator ei, e_end;
+ edge_descriptor new_parent_edge;
+ tDistanceVal min_distance = (std::numeric_limits<tDistanceVal>::max)();
+ for(tie(ei, e_end) = out_edges(current_node, m_g); ei != e_end; ++ei){
+ const edge_descriptor out_edge = *ei;
+ if(m_res_cap_map[out_edge] > 0){
+ const vertex_descriptor other_node = target(out_edge, m_g);
+ if(get_tree(other_node) == tColorTraits::white() && has_sink_connect(other_node))
+ if(m_dist_map[other_node] < min_distance){
+ min_distance = m_dist_map[other_node];
+ new_parent_edge = out_edge;
+ }
+ }
+ }
+ if(min_distance != (std::numeric_limits<tDistanceVal>::max)()){
+ set_edge_to_parent(current_node, new_parent_edge);
+ m_dist_map[current_node] = min_distance + 1;
+ m_time_map[current_node] = m_time;
+ } else{
+ m_time_map[current_node] = 0;
+ for(tie(ei, e_end) = out_edges(current_node, m_g); ei != e_end; ++ei){
+ const edge_descriptor out_edge = *ei;
+ const vertex_descriptor other_node = target(out_edge, m_g);
+ if(get_tree(other_node) == tColorTraits::white() && has_parent(other_node)){
+ if(m_res_cap_map[out_edge] > 0){
+ add_active_node(other_node);
+ }
+ if(target(get_edge_to_parent(other_node), m_g) == current_node){
+ //we were it's parent, so it has to find a new one, too
+ set_no_parent(other_node);
+ m_child_orphans.push(other_node);
+ }
+ }
+ }
+ set_tree(current_node, tColorTraits::gray());
+ } //no parent found
+ } //sink-tree adoption
+ } //while !orphans.empty()
+ } //adopt
+
+ /**
+ * return next active vertex if there is one, otherwise a null_vertex
+ */
+ inline vertex_descriptor get_next_active_node(){
+ while(true){
+ if(m_active_nodes.empty())
+ return graph_traits<Graph>::null_vertex();
+ vertex_descriptor v = m_active_nodes.front();
+
+ if(!has_parent(v) && v != m_source && v != m_sink){ //if it has no parent, this node can't be active(if its not source or sink)
+ m_active_nodes.pop();
+ m_in_active_list_map[v] = false;
+ } else{
+ assert(get_tree(v) == tColorTraits::black() || get_tree(v) == tColorTraits::white());
+ return v;
+ }
+ }
+ }
+
+ /**
+ * adds v as an active vertex, but only if its not in the list already
+ */
+ inline void add_active_node(vertex_descriptor v){
+ assert(get_tree(v) != tColorTraits::gray());
+ if(m_in_active_list_map[v]){
+ return;
+ } else{
+ m_in_active_list_map[v] = true;
+ m_active_nodes.push(v);
+ }
+ }
+
+ /**
+ * finish_node removes a node from the front of the active queue (its called in grow phase, if no more paths can be found using this node)
+ */
+ inline void finish_node(vertex_descriptor v){
+ assert(m_active_nodes.front() == v);
+ m_active_nodes.pop();
+ m_in_active_list_map[v] = false;
+ m_last_grow_vertex = graph_traits<Graph>::null_vertex();
+ }
+
+ /**
+ * removes a vertex from the queue of active nodes (actually this does nothing,
+ * but checks if this node has no parent edge, as this is the criteria for beeing no more active)
+ */
+ inline void remove_active_node(vertex_descriptor v){
+ assert(!has_parent(v));
+ }
+
+ /**
+ * returns the search tree of v; tColorValue::black() for source tree, white() for sink tree, gray() for no tree
+ */
+ inline tColorValue get_tree(vertex_descriptor v) const {
+ return m_tree_map[v];
+ }
+
+ /**
+ * sets search tree of v; tColorValue::black() for source tree, white() for sink tree, gray() for no tree
+ */
+ inline void set_tree(vertex_descriptor v, tColorValue t){
+ m_tree_map[v] = t;
+ }
+
+ /**
+ * returns edge to parent vertex of v;
+ */
+ inline edge_descriptor get_edge_to_parent(vertex_descriptor v) const{
+ return m_pre_map[v];
+ }
+
+ /**
+ * returns true if the edge stored in m_pre_map[v] is a valid entry
+ */
+ inline bool has_parent(vertex_descriptor v) const{
+ return m_has_parent_map[v];
+ }
+
+ /**
+ * sets edge to parent vertex of v;
+ */
+ inline void set_edge_to_parent(vertex_descriptor v, edge_descriptor f_edge_to_parent){
+ assert(m_res_cap_map[f_edge_to_parent] > 0);
+ m_pre_map[v] = f_edge_to_parent;
+ m_has_parent_map[v] = true;
+ }
+
+ /**
+ * removes the edge to parent of v (this is done by invalidating the entry an additional map)
+ */
+ inline void set_no_parent(vertex_descriptor v){
+ m_has_parent_map[v] = false;
+ }
+
+ /**
+ * checks if vertex v has a connect to the sink-vertex (@var m_sink)
+ * @param v the vertex which is checked
+ * @return true if a path to the sink was found, false if not
+ */
+ inline bool has_sink_connect(vertex_descriptor v){
+ tDistanceVal current_distance = 0;
+ vertex_descriptor current_vertex = v;
+ while(true){
+ if(m_time_map[current_vertex] == m_time){
+ //we found a node which was already checked this round. use it for distance calculations
+ current_distance += m_dist_map[current_vertex];
+ break;
+ }
+ if(current_vertex == m_sink){
+ m_time_map[m_sink] = m_time;
+ break;
+ }
+ if(has_parent(current_vertex)){
+ //it has a parent, so get it
+ current_vertex = target(get_edge_to_parent(current_vertex), m_g);
+ ++current_distance;
+ } else{
+ //no path found
+ return false;
+ }
+ }
+ current_vertex=v;
+ while(m_time_map[current_vertex] != m_time){
+ m_dist_map[current_vertex] = current_distance--;
+ m_time_map[current_vertex] = m_time;
+ current_vertex = target(get_edge_to_parent(current_vertex), m_g);
+ }
+ return true;
+ }
+
+ /**
+ * checks if vertex v has a connect to the source-vertex (@var m_source)
+ * @param v the vertex which is checked
+ * @return true if a path to the source was found, false if not
+ */
+ inline bool has_source_connect(vertex_descriptor v){
+ tDistanceVal current_distance = 0;
+ vertex_descriptor current_vertex = v;
+ while(true){
+ if(m_time_map[current_vertex] == m_time){
+ //we found a node which was already checked this round. use it for distance calculations
+ current_distance += m_dist_map[current_vertex];
+ break;
+ }
+ if(current_vertex == m_source){
+ m_time_map[m_source] = m_time;
+ break;
+ }
+ if(has_parent(current_vertex)){
+ //it has a parent, so get it
+ current_vertex = source(get_edge_to_parent(current_vertex), m_g);
+ ++current_distance;
+ } else{
+ //no path found
+ return false;
+ }
+ }
+ current_vertex=v;
+ while(m_time_map[current_vertex] != m_time){
+ m_dist_map[current_vertex] = current_distance-- ;
+ m_time_map[current_vertex] = m_time;
+ current_vertex = source(get_edge_to_parent(current_vertex), m_g);
+ }
+ return true;
+ }
+
+ /**
+ * returns true, if p is closer to a terminal than q
+ */
+ inline bool is_closer_to_terminal(vertex_descriptor p, vertex_descriptor q){
+ //checks the timestamps first, to build no cycles, and after that the real distance
+ return (m_time_map[q] <= m_time_map[p] && m_dist_map[q] > m_dist_map[p]+1);
+ }
+
+ ////////
+ // member vars
+ ////////
+ Graph& m_g;
+ IndexMap m_index_map;
+ EdgeCapacityMap m_cap_map;
+ ResidualCapacityEdgeMap m_res_cap_map;
+ ReverseEdgeMap m_rev_edge_map;
+ PredecessorMap m_pre_map; //stores paths found in the growth stage
+ ColorMap m_tree_map; //maps each vertex into one of the two search tree or none (gray())
+ DistanceMap m_dist_map; //stores distance to source/sink nodes
+ vertex_descriptor m_source;
+ vertex_descriptor m_sink;
+
+ tQueue m_active_nodes;
+ std::vector<bool> m_in_active_list_vec;
+ iterator_property_map<std::vector<bool>::iterator, IndexMap> m_in_active_list_map;
+
+ std::list<vertex_descriptor> m_orphans;
+ tQueue m_child_orphans; // we use a second queuqe for child orphans, as they are FIFO processed
+
+ std::vector<bool> m_has_parent_vec;
+ iterator_property_map<std::vector<bool>::iterator, IndexMap> m_has_parent_map;
+
+ std::vector<long> m_time_vec; //timestamp of each node, used for sink/source-path calculations
+ iterator_property_map<std::vector<long>::iterator, IndexMap> m_time_map;
+ tEdgeVal m_flow;
+ long m_time;
+ vertex_descriptor m_last_grow_vertex;
+ out_edge_iterator m_last_grow_edge_it;
+ out_edge_iterator m_last_grow_edge_end;
+ };
+ } //namespace detail
+
+ /**
+ * non-named-parameter version, given everything
+ * this is the catch all version
+ */
+ template <class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap, class ReverseEdgeMap,
+ class PredecessorMap, class ColorMap, class DistanceMap, class IndexMap>
+ typename property_traits<CapacityEdgeMap>::value_type
+ kolmogorov_max_flow
+ (Graph& g,
+ CapacityEdgeMap cap,
+ ResidualCapacityEdgeMap res_cap,
+ ReverseEdgeMap rev_map,
+ PredecessorMap pre_map,
+ ColorMap color,
+ DistanceMap dist,
+ IndexMap idx,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink
+ )
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
+ //as this method is the last one before we instantiate the solver, we do the concept checks here
+ function_requires<VertexListGraphConcept<Graph> >(); //to have vertices(), num_vertices(),
+ function_requires<EdgeListGraphConcept<Graph> >(); //to have edges()
+ function_requires<IncidenceGraphConcept<Graph> >(); //to have source(), target() and out_edges()
+ function_requires<LvaluePropertyMapConcept<CapacityEdgeMap, edge_descriptor> >(); //read flow-values from edges
+ function_requires<Mutable_LvaluePropertyMapConcept<ResidualCapacityEdgeMap, edge_descriptor> >(); //write flow-values to residuals
+ function_requires<LvaluePropertyMapConcept<ReverseEdgeMap, edge_descriptor> >(); //read out reverse edges
+ function_requires<Mutable_LvaluePropertyMapConcept<PredecessorMap, vertex_descriptor> >(); //store predecessor there
+ function_requires<Mutable_LvaluePropertyMapConcept<ColorMap, vertex_descriptor> >(); //write corresponding tree
+ function_requires<Mutable_LvaluePropertyMapConcept<DistanceMap, vertex_descriptor> >(); //write distance to source/sink
+ function_requires<ReadablePropertyMapConcept<IndexMap, vertex_descriptor> >(); //get index 0...|V|-1
+ assert(num_vertices(g) >= 2 && src != sink);
+ detail::kolmogorov<Graph, CapacityEdgeMap, ResidualCapacityEdgeMap, ReverseEdgeMap, PredecessorMap, ColorMap, DistanceMap, IndexMap>
+ algo(g, cap, res_cap, rev_map, pre_map, color, dist, idx, src, sink);
+ return algo.max_flow();
+ }
+
+ /**
+ * non-named-parameter version, given: capacity, residucal_capacity, reverse_edges, and an index map.
+ */
+ template <class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap, class ReverseEdgeMap, class IndexMap>
+ typename property_traits<CapacityEdgeMap>::value_type
+ kolmogorov_max_flow
+ (Graph& g,
+ CapacityEdgeMap cap,
+ ResidualCapacityEdgeMap res_cap,
+ ReverseEdgeMap rev,
+ IndexMap idx,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink)
+ {
+ typename graph_traits<Graph>::vertices_size_type n_verts = num_vertices(g);
+ std::vector<typename graph_traits<Graph>::edge_descriptor> predecessor_vec(n_verts);
+ std::vector<default_color_type> color_vec(n_verts);
+ std::vector<typename graph_traits<Graph>::vertices_size_type> distance_vec(n_verts);
+ return kolmogorov_max_flow
+ (g, cap, res_cap, rev,
+ make_iterator_property_map(predecessor_vec.begin(), idx),
+ make_iterator_property_map(color_vec.begin(), idx),
+ make_iterator_property_map(distance_vec.begin(), idx),
+ idx, src, sink);
+ }
+
+ /**
+ * non-named-parameter version, some given: capacity, residual_capacity, reverse_edges, color_map and an index map.
+ * Use this if you are interested in the minimum cut, as the color map provides that info
+ */
+ template <class Graph, class CapacityEdgeMap, class ResidualCapacityEdgeMap, class ReverseEdgeMap, class ColorMap, class IndexMap>
+ typename property_traits<CapacityEdgeMap>::value_type
+ kolmogorov_max_flow
+ (Graph& g,
+ CapacityEdgeMap cap,
+ ResidualCapacityEdgeMap res_cap,
+ ReverseEdgeMap rev,
+ ColorMap color,
+ IndexMap idx,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink)
+ {
+ typename graph_traits<Graph>::vertices_size_type n_verts = num_vertices(g);
+ std::vector<typename graph_traits<Graph>::edge_descriptor> predecessor_vec(n_verts);
+ std::vector<typename graph_traits<Graph>::vertices_size_type> distance_vec(n_verts);
+
+ return kolmogorov_max_flow
+ (g, cap, res_cap, rev,
+ make_iterator_property_map(predecessor_vec.begin(), idx),
+ color,
+ make_iterator_property_map(distance_vec.begin(), idx),
+ idx, src, sink);
+ }
+
+ /**
+ * named-parameter version, some given
+ */
+ template <class Graph, class P, class T, class R>
+ typename property_traits<typename property_map<Graph, edge_capacity_t>::const_type>::value_type
+ kolmogorov_max_flow
+ (Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink,
+ const bgl_named_params<P, T, R>& params)
+ {
+ return kolmogorov_max_flow(g,
+ choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
+ choose_pmap(get_param(params, edge_residual_capacity), g, edge_residual_capacity),
+ choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
+ choose_pmap(get_param(params, vertex_predecessor), g, vertex_predecessor),
+ choose_pmap(get_param(params, vertex_color), g, vertex_color),
+ choose_pmap(get_param(params, vertex_distance), g, vertex_distance),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
+ src, sink);
+ }
+
+ /**
+ * named-parameter version, none given
+ */
+ template <class Graph>
+ typename property_traits<typename property_map<Graph, edge_capacity_t>::const_type>::value_type
+ kolmogorov_max_flow
+ (Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink)
+ {
+ bgl_named_params<int, buffer_param_t> params(0); // bogus empty param
+ return kolmogorov_max_flow(g, src, sink, params);
+ }
+} // namespace boost
+
+#endif // BOOST_KOLMOGOROV_MAX_FLOW_HPP
+
Added: branches/CMake/release/libs/graph/include/boost/graph/kruskal_min_spanning_tree.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/kruskal_min_spanning_tree.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,155 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_MST_KRUSKAL_HPP
+#define BOOST_GRAPH_MST_KRUSKAL_HPP
+
+/*
+ *Minimum Spanning Tree
+ * Kruskal Algorithm
+ *
+ *Requirement:
+ * undirected graph
+ */
+
+#include <vector>
+#include <queue>
+#include <functional>
+
+#include <boost/property_map.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/named_function_params.hpp>
+#include <boost/pending/disjoint_sets.hpp>
+#include <boost/pending/indirect_cmp.hpp>
+
+
+namespace boost {
+
+ // Kruskal's algorithm for Minimum Spanning Tree
+ //
+ // This is a greedy algorithm to calculate the Minimum Spanning Tree
+ // for an undirected graph with weighted edges. The output will be a
+ // set of edges.
+ //
+
+ namespace detail {
+
+ template <class Graph, class OutputIterator,
+ class Rank, class Parent, class Weight>
+ void
+ kruskal_mst_impl(const Graph& G,
+ OutputIterator spanning_tree_edges,
+ Rank rank, Parent parent, Weight weight)
+ {
+ if (num_vertices(G) == 0) return; // Nothing to do in this case
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename graph_traits<Graph>::edge_descriptor Edge;
+ function_requires<VertexListGraphConcept<Graph> >();
+ function_requires<EdgeListGraphConcept<Graph> >();
+ function_requires<OutputIteratorConcept<OutputIterator, Edge> >();
+ function_requires<ReadWritePropertyMapConcept<Rank, Vertex> >();
+ function_requires<ReadWritePropertyMapConcept<Parent, Vertex> >();
+ function_requires<ReadablePropertyMapConcept<Weight, Edge> >();
+ typedef typename property_traits<Weight>::value_type W_value;
+ typedef typename property_traits<Rank>::value_type R_value;
+ typedef typename property_traits<Parent>::value_type P_value;
+ function_requires<ComparableConcept<W_value> >();
+ function_requires<ConvertibleConcept<P_value, Vertex> >();
+ function_requires<IntegerConcept<R_value> >();
+
+ disjoint_sets<Rank, Parent> dset(rank, parent);
+
+ typename graph_traits<Graph>::vertex_iterator ui, uiend;
+ for (boost::tie(ui, uiend) = vertices(G); ui != uiend; ++ui)
+ dset.make_set(*ui);
+
+ typedef indirect_cmp<Weight, std::greater<W_value> > weight_greater;
+ weight_greater wl(weight);
+ std::priority_queue<Edge, std::vector<Edge>, weight_greater> Q(wl);
+ /*push all edge into Q*/
+ typename graph_traits<Graph>::edge_iterator ei, eiend;
+ for (boost::tie(ei, eiend) = edges(G); ei != eiend; ++ei)
+ Q.push(*ei);
+
+ while (! Q.empty()) {
+ Edge e = Q.top();
+ Q.pop();
+ Vertex u = dset.find_set(source(e, G));
+ Vertex v = dset.find_set(target(e, G));
+ if ( u != v ) {
+ *spanning_tree_edges++ = e;
+ dset.link(u, v);
+ }
+ }
+ }
+
+ } // namespace detail
+
+ // Named Parameters Variants
+
+ template <class Graph, class OutputIterator>
+ inline void
+ kruskal_minimum_spanning_tree(const Graph& g,
+ OutputIterator spanning_tree_edges)
+ {
+ typedef typename graph_traits<Graph>::vertices_size_type size_type;
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename property_map<Graph, vertex_index_t>::type index_map_t;
+ if (num_vertices(g) == 0) return; // Nothing to do in this case
+ typename graph_traits<Graph>::vertices_size_type
+ n = num_vertices(g);
+ std::vector<size_type> rank_map(n);
+ std::vector<vertex_t> pred_map(n);
+
+ detail::kruskal_mst_impl
+ (g, spanning_tree_edges,
+ make_iterator_property_map(rank_map.begin(), get(vertex_index, g), rank_map[0]),
+ make_iterator_property_map(pred_map.begin(), get(vertex_index, g), pred_map[0]),
+ get(edge_weight, g));
+ }
+
+ template <class Graph, class OutputIterator, class P, class T, class R>
+ inline void
+ kruskal_minimum_spanning_tree(const Graph& g,
+ OutputIterator spanning_tree_edges,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef typename graph_traits<Graph>::vertices_size_type size_type;
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ if (num_vertices(g) == 0) return; // Nothing to do in this case
+ typename graph_traits<Graph>::vertices_size_type n;
+ n = is_default_param(get_param(params, vertex_rank))
+ ? num_vertices(g) : 1;
+ std::vector<size_type> rank_map(n);
+ n = is_default_param(get_param(params, vertex_predecessor))
+ ? num_vertices(g) : 1;
+ std::vector<vertex_t> pred_map(n);
+
+ detail::kruskal_mst_impl
+ (g, spanning_tree_edges,
+ choose_param
+ (get_param(params, vertex_rank),
+ make_iterator_property_map
+ (rank_map.begin(),
+ choose_pmap(get_param(params, vertex_index), g, vertex_index), rank_map[0])),
+ choose_param
+ (get_param(params, vertex_predecessor),
+ make_iterator_property_map
+ (pred_map.begin(),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
+ pred_map[0])),
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight));
+ }
+
+} // namespace boost
+
+
+#endif // BOOST_GRAPH_MST_KRUSKAL_HPP
+
Added: branches/CMake/release/libs/graph/include/boost/graph/leda_graph.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/leda_graph.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,952 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2004 The Trustees of Indiana University.
+// Copyright 2007 University of Karlsruhe
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Douglas Gregor,
+// Jens Mueller
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_GRAPH_LEDA_HPP
+#define BOOST_GRAPH_LEDA_HPP
+
+#include <boost/config.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+
+#include <LEDA/graph.h>
+#include <LEDA/node_array.h>
+#include <LEDA/node_map.h>
+
+// The functions and classes in this file allows the user to
+// treat a LEDA GRAPH object as a boost graph "as is". No
+// wrapper is needed for the GRAPH object.
+
+// Warning: this implementation relies on partial specialization
+// for the graph_traits class (so it won't compile with Visual C++)
+
+// Warning: this implementation is in alpha and has not been tested
+
+#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+namespace boost {
+
+ struct leda_graph_traversal_category :
+ public virtual bidirectional_graph_tag,
+ public virtual adjacency_graph_tag,
+ public virtual vertex_list_graph_tag { };
+
+ template <class vtype, class etype>
+ struct graph_traits< leda::GRAPH<vtype,etype> > {
+ typedef leda::node vertex_descriptor;
+ typedef leda::edge edge_descriptor;
+
+ class adjacency_iterator
+ : public iterator_facade<adjacency_iterator,
+ leda::node,
+ bidirectional_traversal_tag,
+ leda::node,
+ const leda::node*>
+ {
+ public:
+ adjacency_iterator(leda::node node = 0,
+ const leda::GRAPH<vtype, etype>* g = 0)
+ : base(node), g(g) {}
+ private:
+ leda::node dereference() const { return leda::target(base); }
+
+ bool equal(const adjacency_iterator& other) const
+ { return base == other.base; }
+
+ void increment() { base = g->adj_succ(base); }
+ void decrement() { base = g->adj_pred(base); }
+
+ leda::edge base;
+ const leda::GRAPH<vtype, etype>* g;
+
+ friend class iterator_core_access;
+ };
+
+ class out_edge_iterator
+ : public iterator_facade<out_edge_iterator,
+ leda::edge,
+ bidirectional_traversal_tag,
+ const leda::edge&,
+ const leda::edge*>
+ {
+ public:
+ out_edge_iterator(leda::node node = 0,
+ const leda::GRAPH<vtype, etype>* g = 0)
+ : base(node), g(g) {}
+
+ private:
+ const leda::edge& dereference() const { return base; }
+
+ bool equal(const out_edge_iterator& other) const
+ { return base == other.base; }
+
+ void increment() { base = g->adj_succ(base); }
+ void decrement() { base = g->adj_pred(base); }
+
+ leda::edge base;
+ const leda::GRAPH<vtype, etype>* g;
+
+ friend class iterator_core_access;
+ };
+
+ class in_edge_iterator
+ : public iterator_facade<in_edge_iterator,
+ leda::edge,
+ bidirectional_traversal_tag,
+ const leda::edge&,
+ const leda::edge*>
+ {
+ public:
+ in_edge_iterator(leda::node node = 0,
+ const leda::GRAPH<vtype, etype>* g = 0)
+ : base(node), g(g) {}
+
+ private:
+ const leda::edge& dereference() const { return base; }
+
+ bool equal(const in_edge_iterator& other) const
+ { return base == other.base; }
+
+ void increment() { base = g->in_succ(base); }
+ void decrement() { base = g->in_pred(base); }
+
+ leda::edge base;
+ const leda::GRAPH<vtype, etype>* g;
+
+ friend class iterator_core_access;
+ };
+
+ class vertex_iterator
+ : public iterator_facade<vertex_iterator,
+ leda::node,
+ bidirectional_traversal_tag,
+ const leda::node&,
+ const leda::node*>
+ {
+ public:
+ vertex_iterator(leda::node node = 0,
+ const leda::GRAPH<vtype, etype>* g = 0)
+ : base(node), g(g) {}
+
+ private:
+ const leda::node& dereference() const { return base; }
+
+ bool equal(const vertex_iterator& other) const
+ { return base == other.base; }
+
+ void increment() { base = g->succ_node(base); }
+ void decrement() { base = g->pred_node(base); }
+
+ leda::node base;
+ const leda::GRAPH<vtype, etype>* g;
+
+ friend class iterator_core_access;
+ };
+
+ class edge_iterator
+ : public iterator_facade<edge_iterator,
+ leda::edge,
+ bidirectional_traversal_tag,
+ const leda::edge&,
+ const leda::edge*>
+ {
+ public:
+ edge_iterator(leda::edge edge = 0,
+ const leda::GRAPH<vtype, etype>* g = 0)
+ : base(edge), g(g) {}
+
+ private:
+ const leda::edge& dereference() const { return base; }
+
+ bool equal(const edge_iterator& other) const
+ { return base == other.base; }
+
+ void increment() { base = g->succ_edge(base); }
+ void decrement() { base = g->pred_edge(base); }
+
+ leda::node base;
+ const leda::GRAPH<vtype, etype>* g;
+
+ friend class iterator_core_access;
+ };
+
+ typedef directed_tag directed_category;
+ typedef allow_parallel_edge_tag edge_parallel_category; // not sure here
+ typedef leda_graph_traversal_category traversal_category;
+ typedef int vertices_size_type;
+ typedef int edges_size_type;
+ typedef int degree_size_type;
+ };
+
+
+
+ template<>
+ struct graph_traits<leda::graph> {
+ typedef leda::node vertex_descriptor;
+ typedef leda::edge edge_descriptor;
+
+ class adjacency_iterator
+ : public iterator_facade<adjacency_iterator,
+ leda::node,
+ bidirectional_traversal_tag,
+ leda::node,
+ const leda::node*>
+ {
+ public:
+ adjacency_iterator(leda::edge edge = 0,
+ const leda::graph* g = 0)
+ : base(edge), g(g) {}
+
+ private:
+ leda::node dereference() const { return leda::target(base); }
+
+ bool equal(const adjacency_iterator& other) const
+ { return base == other.base; }
+
+ void increment() { base = g->adj_succ(base); }
+ void decrement() { base = g->adj_pred(base); }
+
+ leda::edge base;
+ const leda::graph* g;
+
+ friend class iterator_core_access;
+ };
+
+ class out_edge_iterator
+ : public iterator_facade<out_edge_iterator,
+ leda::edge,
+ bidirectional_traversal_tag,
+ const leda::edge&,
+ const leda::edge*>
+ {
+ public:
+ out_edge_iterator(leda::edge edge = 0,
+ const leda::graph* g = 0)
+ : base(edge), g(g) {}
+
+ private:
+ const leda::edge& dereference() const { return base; }
+
+ bool equal(const out_edge_iterator& other) const
+ { return base == other.base; }
+
+ void increment() { base = g->adj_succ(base); }
+ void decrement() { base = g->adj_pred(base); }
+
+ leda::edge base;
+ const leda::graph* g;
+
+ friend class iterator_core_access;
+ };
+
+ class in_edge_iterator
+ : public iterator_facade<in_edge_iterator,
+ leda::edge,
+ bidirectional_traversal_tag,
+ const leda::edge&,
+ const leda::edge*>
+ {
+ public:
+ in_edge_iterator(leda::edge edge = 0,
+ const leda::graph* g = 0)
+ : base(edge), g(g) {}
+
+ private:
+ const leda::edge& dereference() const { return base; }
+
+ bool equal(const in_edge_iterator& other) const
+ { return base == other.base; }
+
+ void increment() { base = g->in_succ(base); }
+ void decrement() { base = g->in_pred(base); }
+
+ leda::edge base;
+ const leda::graph* g;
+
+ friend class iterator_core_access;
+ };
+
+ class vertex_iterator
+ : public iterator_facade<vertex_iterator,
+ leda::node,
+ bidirectional_traversal_tag,
+ const leda::node&,
+ const leda::node*>
+ {
+ public:
+ vertex_iterator(leda::node node = 0,
+ const leda::graph* g = 0)
+ : base(node), g(g) {}
+
+ private:
+ const leda::node& dereference() const { return base; }
+
+ bool equal(const vertex_iterator& other) const
+ { return base == other.base; }
+
+ void increment() { base = g->succ_node(base); }
+ void decrement() { base = g->pred_node(base); }
+
+ leda::node base;
+ const leda::graph* g;
+
+ friend class iterator_core_access;
+ };
+
+ class edge_iterator
+ : public iterator_facade<edge_iterator,
+ leda::edge,
+ bidirectional_traversal_tag,
+ const leda::edge&,
+ const leda::edge*>
+ {
+ public:
+ edge_iterator(leda::edge edge = 0,
+ const leda::graph* g = 0)
+ : base(edge), g(g) {}
+
+ private:
+ const leda::edge& dereference() const { return base; }
+
+ bool equal(const edge_iterator& other) const
+ { return base == other.base; }
+
+ void increment() { base = g->succ_edge(base); }
+ void decrement() { base = g->pred_edge(base); }
+
+ leda::edge base;
+ const leda::graph* g;
+
+ friend class iterator_core_access;
+ };
+
+ typedef directed_tag directed_category;
+ typedef allow_parallel_edge_tag edge_parallel_category; // not sure here
+ typedef leda_graph_traversal_category traversal_category;
+ typedef int vertices_size_type;
+ typedef int edges_size_type;
+ typedef int degree_size_type;
+ };
+
+} // namespace boost
+#endif
+
+namespace boost {
+
+ //===========================================================================
+ // functions for GRAPH<vtype,etype>
+
+ template <class vtype, class etype>
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor
+ source(typename graph_traits< leda::GRAPH<vtype,etype> >::edge_descriptor e,
+ const leda::GRAPH<vtype,etype>& g)
+ {
+ return source(e);
+ }
+
+ template <class vtype, class etype>
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor
+ target(typename graph_traits< leda::GRAPH<vtype,etype> >::edge_descriptor e,
+ const leda::GRAPH<vtype,etype>& g)
+ {
+ return target(e);
+ }
+
+ template <class vtype, class etype>
+ inline std::pair<
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_iterator,
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_iterator >
+ vertices(const leda::GRAPH<vtype,etype>& g)
+ {
+ typedef typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_iterator
+ Iter;
+ return std::make_pair( Iter(g.first_node(),&g), Iter(0,&g) );
+ }
+
+ template <class vtype, class etype>
+ inline std::pair<
+ typename graph_traits< leda::GRAPH<vtype,etype> >::edge_iterator,
+ typename graph_traits< leda::GRAPH<vtype,etype> >::edge_iterator >
+ edges(const leda::GRAPH<vtype,etype>& g)
+ {
+ typedef typename graph_traits< leda::GRAPH<vtype,etype> >::edge_iterator
+ Iter;
+ return std::make_pair( Iter(g.first_edge(),&g), Iter(0,&g) );
+ }
+
+ template <class vtype, class etype>
+ inline std::pair<
+ typename graph_traits< leda::GRAPH<vtype,etype> >::out_edge_iterator,
+ typename graph_traits< leda::GRAPH<vtype,etype> >::out_edge_iterator >
+ out_edges(
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor u,
+ const leda::GRAPH<vtype,etype>& g)
+ {
+ typedef typename graph_traits< leda::GRAPH<vtype,etype> >
+ ::out_edge_iterator Iter;
+ return std::make_pair( Iter(g.first_adj_edge(u,0),&g), Iter(0,&g) );
+ }
+
+ template <class vtype, class etype>
+ inline std::pair<
+ typename graph_traits< leda::GRAPH<vtype,etype> >::in_edge_iterator,
+ typename graph_traits< leda::GRAPH<vtype,etype> >::in_edge_iterator >
+ in_edges(
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor u,
+ const leda::GRAPH<vtype,etype>& g)
+ {
+ typedef typename graph_traits< leda::GRAPH<vtype,etype> >
+ ::in_edge_iterator Iter;
+ return std::make_pair( Iter(g.first_adj_edge(u,1),&g), Iter(0,&g) );
+ }
+
+ template <class vtype, class etype>
+ inline std::pair<
+ typename graph_traits< leda::GRAPH<vtype,etype> >::adjacency_iterator,
+ typename graph_traits< leda::GRAPH<vtype,etype> >::adjacency_iterator >
+ adjacent_vertices(
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor u,
+ const leda::GRAPH<vtype,etype>& g)
+ {
+ typedef typename graph_traits< leda::GRAPH<vtype,etype> >
+ ::adjacency_iterator Iter;
+ return std::make_pair( Iter(g.first_adj_edge(u,0),&g), Iter(0,&g) );
+ }
+
+ template <class vtype, class etype>
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertices_size_type
+ num_vertices(const leda::GRAPH<vtype,etype>& g)
+ {
+ return g.number_of_nodes();
+ }
+
+ template <class vtype, class etype>
+ typename graph_traits< leda::GRAPH<vtype,etype> >::edges_size_type
+ num_edges(const leda::GRAPH<vtype,etype>& g)
+ {
+ return g.number_of_edges();
+ }
+
+ template <class vtype, class etype>
+ typename graph_traits< leda::GRAPH<vtype,etype> >::degree_size_type
+ out_degree(
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor u,
+ const leda::GRAPH<vtype,etype>& g)
+ {
+ return g.outdeg(u);
+ }
+
+ template <class vtype, class etype>
+ typename graph_traits< leda::GRAPH<vtype,etype> >::degree_size_type
+ in_degree(
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor u,
+ const leda::GRAPH<vtype,etype>& g)
+ {
+ return g.indeg(u);
+ }
+
+ template <class vtype, class etype>
+ typename graph_traits< leda::GRAPH<vtype,etype> >::degree_size_type
+ degree(
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor u,
+ const leda::GRAPH<vtype,etype>& g)
+ {
+ return g.outdeg(u) + g.indeg(u);
+ }
+
+ template <class vtype, class etype>
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor
+ add_vertex(leda::GRAPH<vtype,etype>& g)
+ {
+ return g.new_node();
+ }
+
+ template <class vtype, class etype>
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor
+ add_vertex(const vtype& vp, leda::GRAPH<vtype,etype>& g)
+ {
+ return g.new_node(vp);
+ }
+
+ template <class vtype, class etype>
+ void clear_vertex(
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor u,
+ leda::GRAPH<vtype,etype>& g)
+ {
+ typename graph_traits< leda::GRAPH<vtype,etype> >::out_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end)=out_edges(u,g); ei!=ei_end; ei++)
+ remove_edge(*ei);
+
+ typename graph_traits< leda::GRAPH<vtype,etype> >::in_edge_iterator iei, iei_end;
+ for (tie(iei, iei_end)=in_edges(u,g); iei!=iei_end; iei++)
+ remove_edge(*iei);
+ }
+
+ template <class vtype, class etype>
+ void remove_vertex(
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor u,
+ leda::GRAPH<vtype,etype>& g)
+ {
+ g.del_node(u);
+ }
+
+ template <class vtype, class etype>
+ std::pair<
+ typename graph_traits< leda::GRAPH<vtype,etype> >::edge_descriptor,
+ bool>
+ add_edge(
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor u,
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor v,
+ leda::GRAPH<vtype,etype>& g)
+ {
+ return std::make_pair(g.new_edge(u, v), true);
+ }
+
+ template <class vtype, class etype>
+ std::pair<
+ typename graph_traits< leda::GRAPH<vtype,etype> >::edge_descriptor,
+ bool>
+ add_edge(
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor u,
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor v,
+ const etype& et,
+ leda::GRAPH<vtype,etype>& g)
+ {
+ return std::make_pair(g.new_edge(u, v, et), true);
+ }
+
+ template <class vtype, class etype>
+ void
+ remove_edge(
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor u,
+ typename graph_traits< leda::GRAPH<vtype,etype> >::vertex_descriptor v,
+ leda::GRAPH<vtype,etype>& g)
+ {
+ typename graph_traits< leda::GRAPH<vtype,etype> >::out_edge_iterator
+ i,iend;
+ for (boost::tie(i,iend) = out_edges(u,g); i != iend; ++i)
+ if (target(*i,g) == v)
+ g.del_edge(*i);
+ }
+
+ template <class vtype, class etype>
+ void
+ remove_edge(
+ typename graph_traits< leda::GRAPH<vtype,etype> >::edge_descriptor e,
+ leda::GRAPH<vtype,etype>& g)
+ {
+ g.del_edge(e);
+ }
+
+ //===========================================================================
+ // functions for graph (non-templated version)
+
+ graph_traits<leda::graph>::vertex_descriptor
+ source(graph_traits<leda::graph>::edge_descriptor e,
+ const leda::graph& g)
+ {
+ return source(e);
+ }
+
+ graph_traits<leda::graph>::vertex_descriptor
+ target(graph_traits<leda::graph>::edge_descriptor e,
+ const leda::graph& g)
+ {
+ return target(e);
+ }
+
+ inline std::pair<
+ graph_traits<leda::graph>::vertex_iterator,
+ graph_traits<leda::graph>::vertex_iterator >
+ vertices(const leda::graph& g)
+ {
+ typedef graph_traits<leda::graph>::vertex_iterator
+ Iter;
+ return std::make_pair( Iter(g.first_node(),&g), Iter(0,&g) );
+ }
+
+ inline std::pair<
+ graph_traits<leda::graph>::edge_iterator,
+ graph_traits<leda::graph>::edge_iterator >
+ edges(const leda::graph& g)
+ {
+ typedef graph_traits<leda::graph>::edge_iterator
+ Iter;
+ return std::make_pair( Iter(g.first_edge(),&g), Iter(0,&g) );
+ }
+
+ inline std::pair<
+ graph_traits<leda::graph>::out_edge_iterator,
+ graph_traits<leda::graph>::out_edge_iterator >
+ out_edges(
+ graph_traits<leda::graph>::vertex_descriptor u, const leda::graph& g)
+ {
+ typedef graph_traits<leda::graph>::out_edge_iterator Iter;
+ return std::make_pair( Iter(g.first_adj_edge(u),&g), Iter(0,&g) );
+ }
+
+ inline std::pair<
+ graph_traits<leda::graph>::in_edge_iterator,
+ graph_traits<leda::graph>::in_edge_iterator >
+ in_edges(
+ graph_traits<leda::graph>::vertex_descriptor u,
+ const leda::graph& g)
+ {
+ typedef graph_traits<leda::graph>
+ ::in_edge_iterator Iter;
+ return std::make_pair( Iter(g.first_in_edge(u),&g), Iter(0,&g) );
+ }
+
+ inline std::pair<
+ graph_traits<leda::graph>::adjacency_iterator,
+ graph_traits<leda::graph>::adjacency_iterator >
+ adjacent_vertices(
+ graph_traits<leda::graph>::vertex_descriptor u,
+ const leda::graph& g)
+ {
+ typedef graph_traits<leda::graph>
+ ::adjacency_iterator Iter;
+ return std::make_pair( Iter(g.first_adj_edge(u),&g), Iter(0,&g) );
+ }
+
+ graph_traits<leda::graph>::vertices_size_type
+ num_vertices(const leda::graph& g)
+ {
+ return g.number_of_nodes();
+ }
+
+ graph_traits<leda::graph>::edges_size_type
+ num_edges(const leda::graph& g)
+ {
+ return g.number_of_edges();
+ }
+
+ graph_traits<leda::graph>::degree_size_type
+ out_degree(
+ graph_traits<leda::graph>::vertex_descriptor u,
+ const leda::graph& g)
+ {
+ return g.outdeg(u);
+ }
+
+ graph_traits<leda::graph>::degree_size_type
+ in_degree(
+ graph_traits<leda::graph>::vertex_descriptor u,
+ const leda::graph& g)
+ {
+ return g.indeg(u);
+ }
+
+ graph_traits<leda::graph>::degree_size_type
+ degree(
+ graph_traits<leda::graph>::vertex_descriptor u,
+ const leda::graph& g)
+ {
+ return g.outdeg(u) + g.indeg(u);
+ }
+
+ graph_traits<leda::graph>::vertex_descriptor
+ add_vertex(leda::graph& g)
+ {
+ return g.new_node();
+ }
+
+ void
+ remove_edge(
+ graph_traits<leda::graph>::vertex_descriptor u,
+ graph_traits<leda::graph>::vertex_descriptor v,
+ leda::graph& g)
+ {
+ graph_traits<leda::graph>::out_edge_iterator
+ i,iend;
+ for (boost::tie(i,iend) = out_edges(u,g); i != iend; ++i)
+ if (target(*i,g) == v)
+ g.del_edge(*i);
+ }
+
+ void
+ remove_edge(
+ graph_traits<leda::graph>::edge_descriptor e,
+ leda::graph& g)
+ {
+ g.del_edge(e);
+ }
+
+ void clear_vertex(
+ graph_traits<leda::graph>::vertex_descriptor u,
+ leda::graph& g)
+ {
+ graph_traits<leda::graph>::out_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end)=out_edges(u,g); ei!=ei_end; ei++)
+ remove_edge(*ei, g);
+
+ graph_traits<leda::graph>::in_edge_iterator iei, iei_end;
+ for (tie(iei, iei_end)=in_edges(u,g); iei!=iei_end; iei++)
+ remove_edge(*iei, g);
+ }
+
+ void remove_vertex(
+ graph_traits<leda::graph>::vertex_descriptor u,
+ leda::graph& g)
+ {
+ g.del_node(u);
+ }
+
+ std::pair<
+ graph_traits<leda::graph>::edge_descriptor,
+ bool>
+ add_edge(
+ graph_traits<leda::graph>::vertex_descriptor u,
+ graph_traits<leda::graph>::vertex_descriptor v,
+ leda::graph& g)
+ {
+ return std::make_pair(g.new_edge(u, v), true);
+ }
+
+
+ //===========================================================================
+ // property maps for GRAPH<vtype,etype>
+
+ class leda_graph_id_map
+ : public put_get_helper<int, leda_graph_id_map>
+ {
+ public:
+ typedef readable_property_map_tag category;
+ typedef int value_type;
+ typedef int reference;
+ typedef leda::node key_type;
+ leda_graph_id_map() { }
+ template <class T>
+ long operator[](T x) const { return x->id(); }
+ };
+ template <class vtype, class etype>
+ inline leda_graph_id_map
+ get(vertex_index_t, const leda::GRAPH<vtype, etype>& g) {
+ return leda_graph_id_map();
+ }
+ template <class vtype, class etype>
+ inline leda_graph_id_map
+ get(edge_index_t, const leda::GRAPH<vtype, etype>& g) {
+ return leda_graph_id_map();
+ }
+
+ template <class Tag>
+ struct leda_property_map { };
+
+ template <>
+ struct leda_property_map<vertex_index_t> {
+ template <class vtype, class etype>
+ struct bind_ {
+ typedef leda_graph_id_map type;
+ typedef leda_graph_id_map const_type;
+ };
+ };
+ template <>
+ struct leda_property_map<edge_index_t> {
+ template <class vtype, class etype>
+ struct bind_ {
+ typedef leda_graph_id_map type;
+ typedef leda_graph_id_map const_type;
+ };
+ };
+
+
+ template <class Data, class DataRef, class GraphPtr>
+ class leda_graph_data_map
+ : public put_get_helper<DataRef,
+ leda_graph_data_map<Data,DataRef,GraphPtr> >
+ {
+ public:
+ typedef Data value_type;
+ typedef DataRef reference;
+ typedef void key_type;
+ typedef lvalue_property_map_tag category;
+ leda_graph_data_map(GraphPtr g) : m_g(g) { }
+ template <class NodeOrEdge>
+ DataRef operator[](NodeOrEdge x) const { return (*m_g)[x]; }
+ protected:
+ GraphPtr m_g;
+ };
+
+ template <>
+ struct leda_property_map<vertex_all_t> {
+ template <class vtype, class etype>
+ struct bind_ {
+ typedef leda_graph_data_map<vtype, vtype&, leda::GRAPH<vtype, etype>*> type;
+ typedef leda_graph_data_map<vtype, const vtype&,
+ const leda::GRAPH<vtype, etype>*> const_type;
+ };
+ };
+ template <class vtype, class etype >
+ inline typename property_map< leda::GRAPH<vtype, etype>, vertex_all_t>::type
+ get(vertex_all_t, leda::GRAPH<vtype, etype>& g) {
+ typedef typename property_map< leda::GRAPH<vtype, etype>, vertex_all_t>::type
+ pmap_type;
+ return pmap_type(&g);
+ }
+ template <class vtype, class etype >
+ inline typename property_map< leda::GRAPH<vtype, etype>, vertex_all_t>::const_type
+ get(vertex_all_t, const leda::GRAPH<vtype, etype>& g) {
+ typedef typename property_map< leda::GRAPH<vtype, etype>,
+ vertex_all_t>::const_type pmap_type;
+ return pmap_type(&g);
+ }
+
+ template <>
+ struct leda_property_map<edge_all_t> {
+ template <class vtype, class etype>
+ struct bind_ {
+ typedef leda_graph_data_map<etype, etype&, leda::GRAPH<vtype, etype>*> type;
+ typedef leda_graph_data_map<etype, const etype&,
+ const leda::GRAPH<vtype, etype>*> const_type;
+ };
+ };
+ template <class vtype, class etype >
+ inline typename property_map< leda::GRAPH<vtype, etype>, edge_all_t>::type
+ get(edge_all_t, leda::GRAPH<vtype, etype>& g) {
+ typedef typename property_map< leda::GRAPH<vtype, etype>, edge_all_t>::type
+ pmap_type;
+ return pmap_type(&g);
+ }
+ template <class vtype, class etype >
+ inline typename property_map< leda::GRAPH<vtype, etype>, edge_all_t>::const_type
+ get(edge_all_t, const leda::GRAPH<vtype, etype>& g) {
+ typedef typename property_map< leda::GRAPH<vtype, etype>,
+ edge_all_t>::const_type pmap_type;
+ return pmap_type(&g);
+ }
+
+ // property map interface to the LEDA node_array class
+
+ template <class E, class ERef, class NodeMapPtr>
+ class leda_node_property_map
+ : public put_get_helper<ERef, leda_node_property_map<E, ERef, NodeMapPtr> >
+ {
+ public:
+ typedef E value_type;
+ typedef ERef reference;
+ typedef leda::node key_type;
+ typedef lvalue_property_map_tag category;
+ leda_node_property_map(NodeMapPtr a) : m_array(a) { }
+ ERef operator[](leda::node n) const { return (*m_array)[n]; }
+ protected:
+ NodeMapPtr m_array;
+ };
+ template <class E>
+ leda_node_property_map<E, const E&, const leda::node_array<E>*>
+ make_leda_node_property_map(const leda::node_array<E>& a)
+ {
+ typedef leda_node_property_map<E, const E&, const leda::node_array<E>*>
+ pmap_type;
+ return pmap_type(&a);
+ }
+ template <class E>
+ leda_node_property_map<E, E&, leda::node_array<E>*>
+ make_leda_node_property_map(leda::node_array<E>& a)
+ {
+ typedef leda_node_property_map<E, E&, leda::node_array<E>*> pmap_type;
+ return pmap_type(&a);
+ }
+
+ template <class E>
+ leda_node_property_map<E, const E&, const leda::node_map<E>*>
+ make_leda_node_property_map(const leda::node_map<E>& a)
+ {
+ typedef leda_node_property_map<E,const E&,const leda::node_map<E>*>
+ pmap_type;
+ return pmap_type(&a);
+ }
+ template <class E>
+ leda_node_property_map<E, E&, leda::node_map<E>*>
+ make_leda_node_property_map(leda::node_map<E>& a)
+ {
+ typedef leda_node_property_map<E, E&, leda::node_map<E>*> pmap_type;
+ return pmap_type(&a);
+ }
+
+ // g++ 'enumeral_type' in template unification not implemented workaround
+ template <class vtype, class etype, class Tag>
+ struct property_map<leda::GRAPH<vtype, etype>, Tag> {
+ typedef typename
+ leda_property_map<Tag>::template bind_<vtype, etype> map_gen;
+ typedef typename map_gen::type type;
+ typedef typename map_gen::const_type const_type;
+ };
+
+ template <class vtype, class etype, class PropertyTag, class Key>
+ inline
+ typename boost::property_traits<
+ typename boost::property_map<leda::GRAPH<vtype, etype>,PropertyTag>::const_type
+::value_type
+ get(PropertyTag p, const leda::GRAPH<vtype, etype>& g, const Key& key) {
+ return get(get(p, g), key);
+ }
+
+ template <class vtype, class etype, class PropertyTag, class Key,class Value>
+ inline void
+ put(PropertyTag p, leda::GRAPH<vtype, etype>& g,
+ const Key& key, const Value& value)
+ {
+ typedef typename property_map<leda::GRAPH<vtype, etype>, PropertyTag>::type Map;
+ Map pmap = get(p, g);
+ put(pmap, key, value);
+ }
+
+ // property map interface to the LEDA edge_array class
+
+ template <class E, class ERef, class EdgeMapPtr>
+ class leda_edge_property_map
+ : public put_get_helper<ERef, leda_edge_property_map<E, ERef, EdgeMapPtr> >
+ {
+ public:
+ typedef E value_type;
+ typedef ERef reference;
+ typedef leda::edge key_type;
+ typedef lvalue_property_map_tag category;
+ leda_edge_property_map(EdgeMapPtr a) : m_array(a) { }
+ ERef operator[](leda::edge n) const { return (*m_array)[n]; }
+ protected:
+ EdgeMapPtr m_array;
+ };
+ template <class E>
+ leda_edge_property_map<E, const E&, const leda::edge_array<E>*>
+ make_leda_node_property_map(const leda::node_array<E>& a)
+ {
+ typedef leda_edge_property_map<E, const E&, const leda::node_array<E>*>
+ pmap_type;
+ return pmap_type(&a);
+ }
+ template <class E>
+ leda_edge_property_map<E, E&, leda::edge_array<E>*>
+ make_leda_edge_property_map(leda::edge_array<E>& a)
+ {
+ typedef leda_edge_property_map<E, E&, leda::edge_array<E>*> pmap_type;
+ return pmap_type(&a);
+ }
+
+ template <class E>
+ leda_edge_property_map<E, const E&, const leda::edge_map<E>*>
+ make_leda_edge_property_map(const leda::edge_map<E>& a)
+ {
+ typedef leda_edge_property_map<E,const E&,const leda::edge_map<E>*>
+ pmap_type;
+ return pmap_type(&a);
+ }
+ template <class E>
+ leda_edge_property_map<E, E&, leda::edge_map<E>*>
+ make_leda_edge_property_map(leda::edge_map<E>& a)
+ {
+ typedef leda_edge_property_map<E, E&, leda::edge_map<E>*> pmap_type;
+ return pmap_type(&a);
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_LEDA_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/make_biconnected_planar.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/make_biconnected_planar.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,121 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// 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)
+//=======================================================================
+#ifndef __MAKE_BICONNECTED_PLANAR_HPP__
+#define __MAKE_BICONNECTED_PLANAR_HPP__
+
+#include <boost/config.hpp>
+#include <boost/tuple/tuple.hpp> //for tie
+#include <boost/graph/biconnected_components.hpp>
+#include <boost/property_map.hpp>
+#include <vector>
+#include <iterator>
+#include <algorithm>
+
+#include <boost/graph/planar_detail/add_edge_visitors.hpp>
+
+
+namespace boost
+{
+
+
+
+ template <typename Graph,
+ typename PlanarEmbedding,
+ typename EdgeIndexMap,
+ typename AddEdgeVisitor
+ >
+ void make_biconnected_planar(Graph& g,
+ PlanarEmbedding embedding,
+ EdgeIndexMap em,
+ AddEdgeVisitor& vis
+ )
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ typedef typename graph_traits<Graph>::edges_size_type edge_size_t;
+ typedef typename
+ property_traits<PlanarEmbedding>::value_type embedding_value_t;
+ typedef typename embedding_value_t::const_iterator embedding_iterator_t;
+ typedef iterator_property_map
+ <std::vector<std::size_t>::iterator, EdgeIndexMap> component_map_t;
+
+ edge_size_t n_edges(num_edges(g));
+ std::vector<vertex_t> articulation_points;
+ std::vector<edge_size_t> component_vector(n_edges);
+ component_map_t component_map(component_vector.begin(), em);
+
+ biconnected_components(g, component_map,
+ std::back_inserter(articulation_points));
+
+ typename std::vector<vertex_t>::iterator ap, ap_end;
+ ap_end = articulation_points.end();
+ for(ap = articulation_points.begin(); ap != ap_end; ++ap)
+ {
+ vertex_t v(*ap);
+ embedding_iterator_t pi = embedding[v].begin();
+ embedding_iterator_t pi_end = embedding[v].end();
+ edge_size_t previous_component(n_edges + 1);
+ vertex_t previous_vertex = graph_traits<Graph>::null_vertex();
+
+ for(; pi != pi_end; ++pi)
+ {
+ edge_t e(*pi);
+ vertex_t e_source(source(e,g));
+ vertex_t e_target(target(e,g));
+
+ //Skip self-loops and parallel edges
+ if (e_source == e_target || previous_vertex == e_target)
+ continue;
+
+ vertex_t current_vertex = e_source == v ? e_target : e_source;
+ edge_size_t current_component = component_map[e];
+ if (previous_vertex != graph_traits<Graph>::null_vertex() &&
+ current_component != previous_component)
+ {
+ vis.visit_vertex_pair(current_vertex, previous_vertex, g);
+ }
+ previous_vertex = current_vertex;
+ previous_component = current_component;
+ }
+ }
+
+ }
+
+
+
+
+ template <typename Graph,
+ typename PlanarEmbedding,
+ typename EdgeIndexMap
+ >
+ inline void make_biconnected_planar(Graph& g,
+ PlanarEmbedding embedding,
+ EdgeIndexMap em
+ )
+ {
+ default_add_edge_visitor vis;
+ make_biconnected_planar(g, embedding, em, vis);
+ }
+
+
+
+
+ template <typename Graph,
+ typename PlanarEmbedding
+ >
+ inline void make_biconnected_planar(Graph& g, PlanarEmbedding embedding)
+ {
+ make_biconnected_planar(g, embedding, get(edge_index,g));
+ }
+
+
+} // namespace boost
+
+
+
+#endif //__MAKE_BICONNECTED_PLANAR_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/make_connected.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/make_connected.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,99 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// 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)
+//=======================================================================
+#ifndef __MAKE_CONNECTED_HPP__
+#define __MAKE_CONNECTED_HPP__
+
+#include <boost/config.hpp>
+#include <boost/utility.hpp> //for next
+#include <boost/tuple/tuple.hpp> //for tie
+#include <boost/graph/connected_components.hpp>
+#include <boost/property_map.hpp>
+#include <vector>
+
+#include <boost/graph/planar_detail/add_edge_visitors.hpp>
+#include <boost/graph/planar_detail/bucket_sort.hpp>
+
+
+namespace boost
+{
+
+
+ template <typename Graph,
+ typename VertexIndexMap,
+ typename AddEdgeVisitor
+ >
+ void make_connected(Graph& g, VertexIndexMap vm, AddEdgeVisitor& vis)
+ {
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
+ typedef iterator_property_map< typename std::vector<v_size_t>::iterator,
+ VertexIndexMap
+ > vertex_to_v_size_map_t;
+
+ std::vector<v_size_t> component_vector(num_vertices(g));
+ vertex_to_v_size_map_t component(component_vector.begin(), vm);
+ std::vector<vertex_t> vertices_by_component(num_vertices(g));
+
+ v_size_t num_components = connected_components(g, component);
+
+ if (num_components < 2)
+ return;
+
+ vertex_iterator_t vi, vi_end;
+ tie(vi,vi_end) = vertices(g);
+ std::copy(vi, vi_end, vertices_by_component.begin());
+
+ bucket_sort(vertices_by_component.begin(),
+ vertices_by_component.end(),
+ component,
+ num_components
+ );
+
+ typedef typename std::vector<vertex_t>::iterator vec_of_vertices_itr_t;
+
+ vec_of_vertices_itr_t ci_end = vertices_by_component.end();
+ vec_of_vertices_itr_t ci_prev = vertices_by_component.begin();
+ if (ci_prev == ci_end)
+ return;
+
+ for(vec_of_vertices_itr_t ci = next(ci_prev);
+ ci != ci_end; ci_prev = ci, ++ci
+ )
+ {
+ if (component[*ci_prev] != component[*ci])
+ vis.visit_vertex_pair(*ci_prev, *ci, g);
+ }
+
+ }
+
+
+
+
+ template <typename Graph, typename VertexIndexMap>
+ inline void make_connected(Graph& g, VertexIndexMap vm)
+ {
+ default_add_edge_visitor vis;
+ make_connected(g, vm, vis);
+ }
+
+
+
+
+ template <typename Graph>
+ inline void make_connected(Graph& g)
+ {
+ make_connected(g, get(vertex_index,g));
+ }
+
+
+
+
+} // namespace boost
+
+#endif //__MAKE_CONNECTED_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/make_maximal_planar.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/make_maximal_planar.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,275 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// 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)
+//=======================================================================
+#ifndef __MAKE_MAXIMAL_PLANAR_HPP__
+#define __MAKE_MAXIMAL_PLANAR_HPP__
+
+#include <boost/config.hpp>
+#include <boost/tuple/tuple.hpp> //for tie
+#include <boost/graph/biconnected_components.hpp>
+#include <boost/property_map.hpp>
+#include <vector>
+#include <iterator>
+#include <algorithm>
+
+#include <boost/graph/planar_face_traversal.hpp>
+#include <boost/graph/planar_detail/add_edge_visitors.hpp>
+
+
+namespace boost
+{
+
+
+ template <typename Graph, typename VertexIndexMap, typename AddEdgeVisitor>
+ struct triangulation_visitor : public planar_face_traversal_visitor
+ {
+
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
+ typedef typename graph_traits<Graph>::degree_size_type degree_size_t;
+ typedef typename graph_traits<Graph>::edge_iterator edge_iterator_t;
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits<Graph>::adjacency_iterator
+ adjacency_iterator_t;
+ typedef typename std::vector<vertex_t> vertex_vector_t;
+ typedef typename std::vector<v_size_t> v_size_vector_t;
+ typedef typename std::vector<degree_size_t> degree_size_vector_t;
+ typedef iterator_property_map
+ < typename v_size_vector_t::iterator, VertexIndexMap >
+ vertex_to_v_size_map_t;
+ typedef iterator_property_map
+ < typename degree_size_vector_t::iterator, VertexIndexMap >
+ vertex_to_degree_size_map_t;
+ typedef typename vertex_vector_t::iterator face_iterator;
+
+
+ triangulation_visitor(Graph& arg_g,
+ VertexIndexMap arg_vm,
+ AddEdgeVisitor arg_add_edge_visitor
+ ) :
+ g(arg_g),
+ vm(arg_vm),
+ add_edge_visitor(arg_add_edge_visitor),
+ timestamp(0),
+ marked_vector(num_vertices(g), timestamp),
+ degree_vector(num_vertices(g), 0),
+ marked(marked_vector.begin(), vm),
+ degree(degree_vector.begin(), vm)
+ {
+ vertex_iterator_t vi, vi_end;
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(degree, *vi, out_degree(*vi, g));
+ }
+
+ template <typename Vertex>
+ void next_vertex(Vertex v)
+ {
+ // Self-loops will appear as consecutive vertices in the list of
+ // vertices on a face. We want to skip these.
+ if (!vertices_on_face.empty() &&
+ (vertices_on_face.back() == v || vertices_on_face.front() == v)
+ )
+ return;
+
+ vertices_on_face.push_back(v);
+ }
+
+ void end_face()
+ {
+ ++timestamp;
+
+ if (vertices_on_face.size() <= 3)
+ {
+ // At most three vertices on this face - don't need to triangulate
+ vertices_on_face.clear();
+ return;
+ }
+
+ // Find vertex on face of minimum degree
+ degree_size_t min_degree = num_vertices(g);
+ typename vertex_vector_t::iterator min_degree_vertex_itr;
+ face_iterator fi_end = vertices_on_face.end();
+ for(face_iterator fi = vertices_on_face.begin(); fi != fi_end; ++fi)
+ {
+ degree_size_t deg = get(degree,*fi);
+ if (deg < min_degree)
+ {
+ min_degree_vertex_itr = fi;
+ min_degree = deg;
+ }
+ }
+
+ // To simplify some of the manipulations, we'll re-arrange
+ // vertices_on_face so that it still contains the same
+ // (counter-clockwise) order of the vertices on this face, but now the
+ // min_degree_vertex is the first element in vertices_on_face.
+ vertex_vector_t temp_vector;
+ std::copy(min_degree_vertex_itr, vertices_on_face.end(),
+ std::back_inserter(temp_vector));
+ std::copy(vertices_on_face.begin(), min_degree_vertex_itr,
+ std::back_inserter(temp_vector));
+ vertices_on_face.swap(temp_vector);
+
+ // Mark all of the min degree vertex's neighbors
+ adjacency_iterator_t ai, ai_end;
+ for(tie(ai,ai_end) = adjacent_vertices(vertices_on_face.front(),g);
+ ai != ai_end; ++ai
+ )
+ {
+ put(marked, *ai, timestamp);
+ }
+
+ typename vertex_vector_t::iterator marked_neighbor
+ = vertices_on_face.end();
+
+ // The iterator manipulations on the next two lines are safe because
+ // vertices_on_face.size() > 3 (from the first test in this function)
+ fi_end = prior(vertices_on_face.end());
+ for(face_iterator fi = next(next(vertices_on_face.begin()));
+ fi != fi_end; ++fi
+ )
+ {
+ if (get(marked, *fi) == timestamp)
+ {
+ marked_neighbor = fi;
+ break;
+ }
+ }
+
+ if (marked_neighbor == vertices_on_face.end())
+ {
+ add_edge_range(
+ vertices_on_face[0],
+ next(next(vertices_on_face.begin())),
+ prior(vertices_on_face.end())
+ );
+ }
+ else
+ {
+ add_edge_range(
+ vertices_on_face[1],
+ next(marked_neighbor),
+ vertices_on_face.end()
+ );
+
+ add_edge_range(
+ *next(marked_neighbor),
+ next(next(vertices_on_face.begin())),
+ marked_neighbor
+ );
+ }
+
+ //reset for the next face
+ vertices_on_face.clear();
+
+ }
+
+ private:
+
+
+ void add_edge_range(vertex_t anchor,
+ face_iterator fi,
+ face_iterator fi_end
+ )
+ {
+ for (; fi != fi_end; ++fi)
+ {
+ vertex_t v(*fi);
+ add_edge_visitor.visit_vertex_pair(anchor, v, g);
+ put(degree, anchor, get(degree, anchor) + 1);
+ put(degree, v, get(degree, v) + 1);
+ }
+ }
+
+
+ Graph& g;
+ VertexIndexMap vm;
+ AddEdgeVisitor add_edge_visitor;
+ v_size_t timestamp;
+ vertex_vector_t vertices_on_face;
+ v_size_vector_t marked_vector;
+ degree_size_vector_t degree_vector;
+ vertex_to_v_size_map_t marked;
+ vertex_to_degree_size_map_t degree;
+
+ };
+
+
+
+
+ template <typename Graph,
+ typename PlanarEmbedding,
+ typename VertexIndexMap,
+ typename EdgeIndexMap,
+ typename AddEdgeVisitor
+ >
+ void make_maximal_planar(Graph& g,
+ PlanarEmbedding embedding,
+ VertexIndexMap vm,
+ EdgeIndexMap em,
+ AddEdgeVisitor& vis)
+ {
+ triangulation_visitor<Graph,VertexIndexMap,AddEdgeVisitor>
+ visitor(g, vm, vis);
+ planar_face_traversal(g, embedding, visitor, em);
+ }
+
+
+
+
+ template <typename Graph,
+ typename PlanarEmbedding,
+ typename VertexIndexMap,
+ typename EdgeIndexMap
+ >
+ void make_maximal_planar(Graph& g,
+ PlanarEmbedding embedding,
+ VertexIndexMap vm,
+ EdgeIndexMap em
+ )
+ {
+ default_add_edge_visitor vis;
+ make_maximal_planar(g, embedding, vm, em, vis);
+ }
+
+
+
+
+ template <typename Graph,
+ typename PlanarEmbedding,
+ typename VertexIndexMap
+ >
+ void make_maximal_planar(Graph& g,
+ PlanarEmbedding embedding,
+ VertexIndexMap vm
+ )
+ {
+ make_maximal_planar(g, embedding, vm, get(edge_index,g));
+ }
+
+
+
+
+ template <typename Graph,
+ typename PlanarEmbedding
+ >
+ void make_maximal_planar(Graph& g,
+ PlanarEmbedding embedding
+ )
+ {
+ make_maximal_planar(g, embedding, get(vertex_index,g));
+ }
+
+
+
+
+} // namespace boost
+
+
+
+#endif //__MAKE_MAXIMAL_PLANAR_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/matrix_as_graph.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/matrix_as_graph.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,127 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_MATRIX2GRAPH_HPP
+#define BOOST_GRAPH_MATRIX2GRAPH_HPP
+
+#include <utility>
+#include <boost/config.hpp>
+#include <boost/operators.hpp>
+#include <boost/int_iterator.hpp>
+#include <boost/graph/graph_traits.hpp>
+
+namespace boost {
+
+ template <class Iter, class Vertex>
+ class matrix_adj_iterator;
+
+ template <class Iter, class Vertex>
+ class matrix_incidence_iterator;
+
+}
+
+#define BOOST_GRAPH_ADAPT_MATRIX_TO_GRAPH(Matrix) \
+namespace boost { \
+ template <> \
+ struct graph_traits< Matrix > { \
+ typedef Matrix::OneD::const_iterator Iter; \
+ typedef Matrix::size_type V; \
+ typedef V vertex_descriptor; \
+ typedef Iter E; \
+ typedef E edge_descriptor; \
+ typedef boost::matrix_incidence_iterator<Iter, V> out_edge_iterator; \
+ typedef boost::matrix_adj_iterator<Iter, V> adjacency_iterator; \
+ typedef Matrix::size_type size_type; \
+ typedef boost::int_iterator<size_type> vertex_iterator; \
+ \
+ friend std::pair<vertex_iterator, vertex_iterator> \
+ vertices(const Matrix& g) { \
+ typedef vertex_iterator VIter; \
+ return std::make_pair(VIter(0), VIter(g.nrows())); \
+ } \
+ \
+ friend std::pair<out_edge_iterator, out_edge_iterator> \
+ out_edges(V v, const Matrix& g) { \
+ typedef out_edge_iterator IncIter; \
+ return std::make_pair(IncIter(g[v].begin()), \
+ IncIter(g[v].end())); \
+ } \
+ friend std::pair<adjacency_iterator, adjacency_iterator> \
+ adjacent_vertices(V v, const Matrix& g) { \
+ typedef adjacency_iterator AdjIter; \
+ return std::make_pair(AdjIter(g[v].begin()), \
+ AdjIter(g[v].end())); \
+ } \
+ friend vertex_descriptor \
+ source(E e, const Matrix& g) { \
+ return e.row(); \
+ } \
+ friend vertex_descriptor \
+ target(E e, const Matrix& g) { \
+ return e.column(); \
+ } \
+ friend size_type \
+ num_vertices(const Matrix& g) { \
+ return g.nrows(); \
+ } \
+ friend size_type \
+ num_edges(const Matrix& g) { \
+ return g.nnz(); \
+ } \
+ friend size_type \
+ out_degree(V i, const Matrix& g) { \
+ return g[i].nnz(); \
+ } \
+ }; \
+}
+
+namespace boost {
+
+ template <class Iter, class Vertex>
+ class matrix_adj_iterator
+ : public std::iterator<std::input_iterator_tag, Vertex >
+ {
+ typedef matrix_adj_iterator self;
+ public:
+ matrix_adj_iterator() { }
+ matrix_adj_iterator(Iter i) : _iter(i) { }
+ matrix_adj_iterator(const self& x) : _iter(x._iter) { }
+ self& operator=(const self& x) { _iter = x._iter; return *this; }
+ Vertex operator*() { return _iter.column(); }
+ self& operator++() { ++_iter; return *this; }
+ self operator++(int) { self t = *this; ++_iter; return t; }
+ bool operator==(const self& x) const { return _iter == x._iter; }
+ bool operator!=(const self& x) const { return _iter != x._iter; }
+ protected:
+ Iter _iter;
+ };
+
+ template <class Iter, class Vertex>
+ class matrix_incidence_iterator
+ : public std::iterator<std::input_iterator_tag, Iter >
+ {
+ typedef matrix_incidence_iterator self;
+ public:
+ matrix_incidence_iterator() { }
+ matrix_incidence_iterator(Iter i) : _iter(i) { }
+ matrix_incidence_iterator(const self& x) : _iter(x._iter) { }
+ self& operator=(const self& x) { _iter = x._iter; return *this; }
+ Iter operator*() { return _iter; }
+ self& operator++() { ++_iter; return *this; }
+ self operator++(int) { self t = *this; ++_iter; return t; }
+ bool operator==(const self& x) const { return _iter == x._iter; }
+ bool operator!=(const self& x) const { return _iter != x._iter; }
+ protected:
+ Iter _iter;
+ };
+
+} /* namespace boost */
+
+#endif /* BOOST_GRAPH_MATRIX2GRAPH_HPP*/
Added: branches/CMake/release/libs/graph/include/boost/graph/max_cardinality_matching.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/max_cardinality_matching.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,883 @@
+//=======================================================================
+// Copyright (c) 2005 Aaron Windsor
+//
+// 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)
+//
+//=======================================================================
+
+#ifndef BOOST_GRAPH_MAXIMUM_CARDINALITY_MATCHING_HPP
+#define BOOST_GRAPH_MAXIMUM_CARDINALITY_MATCHING_HPP
+
+#include <vector>
+#include <list>
+#include <deque>
+#include <algorithm> // for std::sort and std::stable_sort
+#include <utility> // for std::pair
+#include <boost/property_map.hpp>
+#include <boost/utility.hpp> // for boost::tie
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/graph/filtered_graph.hpp>
+#include <boost/pending/disjoint_sets.hpp>
+#include <boost/assert.hpp>
+
+
+namespace boost
+{
+ namespace graph { namespace detail {
+ enum { V_EVEN, V_ODD, V_UNREACHED };
+ } } // end namespace graph::detail
+
+ template <typename Graph, typename MateMap, typename VertexIndexMap>
+ typename graph_traits<Graph>::vertices_size_type
+ matching_size(const Graph& g, MateMap mate, VertexIndexMap vm)
+ {
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits<Graph>::vertex_descriptor
+ vertex_descriptor_t;
+ typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
+
+ v_size_t size_of_matching = 0;
+ vertex_iterator_t vi, vi_end;
+
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_descriptor_t v = *vi;
+ if (get(mate,v) != graph_traits<Graph>::null_vertex()
+ && get(vm,v) < get(vm,get(mate,v)))
+ ++size_of_matching;
+ }
+ return size_of_matching;
+ }
+
+
+
+
+ template <typename Graph, typename MateMap>
+ inline typename graph_traits<Graph>::vertices_size_type
+ matching_size(const Graph& g, MateMap mate)
+ {
+ return matching_size(g, mate, get(vertex_index,g));
+ }
+
+
+
+
+ template <typename Graph, typename MateMap, typename VertexIndexMap>
+ bool is_a_matching(const Graph& g, MateMap mate, VertexIndexMap vm)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor
+ vertex_descriptor_t;
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
+
+ vertex_iterator_t vi, vi_end;
+ for( tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_descriptor_t v = *vi;
+ if (get(mate,v) != graph_traits<Graph>::null_vertex()
+ && v != get(mate,get(mate,v)))
+ return false;
+ }
+ return true;
+ }
+
+
+
+
+ template <typename Graph, typename MateMap>
+ inline bool is_a_matching(const Graph& g, MateMap mate)
+ {
+ return is_a_matching(g, mate, get(vertex_index,g));
+ }
+
+
+
+
+ //***************************************************************************
+ //***************************************************************************
+ // Maximum Cardinality Matching Functors
+ //***************************************************************************
+ //***************************************************************************
+
+ template <typename Graph, typename MateMap,
+ typename VertexIndexMap = dummy_property_map>
+ struct no_augmenting_path_finder
+ {
+ no_augmenting_path_finder(const Graph& g, MateMap mate, VertexIndexMap vm)
+ { }
+
+ inline bool augment_matching() { return false; }
+
+ template <typename PropertyMap>
+ void get_current_matching(PropertyMap p) {}
+ };
+
+
+
+
+ template <typename Graph, typename MateMap, typename VertexIndexMap>
+ class edmonds_augmenting_path_finder
+ {
+ // This implementation of Edmonds' matching algorithm closely
+ // follows Tarjan's description of the algorithm in "Data
+ // Structures and Network Algorithms."
+
+ public:
+
+ //generates the type of an iterator property map from vertices to type X
+ template <typename X>
+ struct map_vertex_to_
+ {
+ typedef boost::iterator_property_map<typename std::vector<X>::iterator,
+ VertexIndexMap> type;
+ };
+
+ typedef typename graph_traits<Graph>::vertex_descriptor
+ vertex_descriptor_t;
+ typedef typename std::pair< vertex_descriptor_t, vertex_descriptor_t >
+ vertex_pair_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor_t;
+ typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
+ typedef typename graph_traits<Graph>::edges_size_type e_size_t;
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits<Graph>::out_edge_iterator
+ out_edge_iterator_t;
+ typedef typename std::deque<vertex_descriptor_t> vertex_list_t;
+ typedef typename std::vector<edge_descriptor_t> edge_list_t;
+ typedef typename map_vertex_to_<vertex_descriptor_t>::type
+ vertex_to_vertex_map_t;
+ typedef typename map_vertex_to_<int>::type vertex_to_int_map_t;
+ typedef typename map_vertex_to_<vertex_pair_t>::type
+ vertex_to_vertex_pair_map_t;
+ typedef typename map_vertex_to_<v_size_t>::type vertex_to_vsize_map_t;
+ typedef typename map_vertex_to_<e_size_t>::type vertex_to_esize_map_t;
+
+
+
+
+ edmonds_augmenting_path_finder(const Graph& arg_g, MateMap arg_mate,
+ VertexIndexMap arg_vm) :
+ g(arg_g),
+ vm(arg_vm),
+ n_vertices(num_vertices(arg_g)),
+
+ mate_vector(n_vertices),
+ ancestor_of_v_vector(n_vertices),
+ ancestor_of_w_vector(n_vertices),
+ vertex_state_vector(n_vertices),
+ origin_vector(n_vertices),
+ pred_vector(n_vertices),
+ bridge_vector(n_vertices),
+ ds_parent_vector(n_vertices),
+ ds_rank_vector(n_vertices),
+
+ mate(mate_vector.begin(), vm),
+ ancestor_of_v(ancestor_of_v_vector.begin(), vm),
+ ancestor_of_w(ancestor_of_w_vector.begin(), vm),
+ vertex_state(vertex_state_vector.begin(), vm),
+ origin(origin_vector.begin(), vm),
+ pred(pred_vector.begin(), vm),
+ bridge(bridge_vector.begin(), vm),
+ ds_parent_map(ds_parent_vector.begin(), vm),
+ ds_rank_map(ds_rank_vector.begin(), vm),
+
+ ds(ds_rank_map, ds_parent_map)
+ {
+ vertex_iterator_t vi, vi_end;
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ mate[*vi] = get(arg_mate, *vi);
+ }
+
+
+
+
+ bool augment_matching()
+ {
+ //As an optimization, some of these values can be saved from one
+ //iteration to the next instead of being re-initialized each
+ //iteration, allowing for "lazy blossom expansion." This is not
+ //currently implemented.
+
+ e_size_t timestamp = 0;
+ even_edges.clear();
+
+ vertex_iterator_t vi, vi_end;
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_descriptor_t u = *vi;
+
+ origin[u] = u;
+ pred[u] = u;
+ ancestor_of_v[u] = 0;
+ ancestor_of_w[u] = 0;
+ ds.make_set(u);
+
+ if (mate[u] == graph_traits<Graph>::null_vertex())
+ {
+ vertex_state[u] = graph::detail::V_EVEN;
+ out_edge_iterator_t ei, ei_end;
+ for(tie(ei,ei_end) = out_edges(u,g); ei != ei_end; ++ei)
+ even_edges.push_back( *ei );
+ }
+ else
+ vertex_state[u] = graph::detail::V_UNREACHED;
+ }
+
+ //end initializations
+
+ vertex_descriptor_t v,w,w_free_ancestor,v_free_ancestor;
+ w_free_ancestor = graph_traits<Graph>::null_vertex();
+ v_free_ancestor = graph_traits<Graph>::null_vertex();
+ bool found_alternating_path = false;
+
+ while(!even_edges.empty() && !found_alternating_path)
+ {
+ // since we push even edges onto the back of the list as
+ // they're discovered, taking them off the back will search
+ // for augmenting paths depth-first.
+ edge_descriptor_t current_edge = even_edges.back();
+ even_edges.pop_back();
+
+ v = source(current_edge,g);
+ w = target(current_edge,g);
+
+ vertex_descriptor_t v_prime = origin[ds.find_set(v)];
+ vertex_descriptor_t w_prime = origin[ds.find_set(w)];
+
+ // because of the way we put all of the edges on the queue,
+ // v_prime should be labeled V_EVEN; the following is a
+ // little paranoid but it could happen...
+ if (vertex_state[v_prime] != graph::detail::V_EVEN)
+ {
+ std::swap(v_prime,w_prime);
+ std::swap(v,w);
+ }
+
+ if (vertex_state[w_prime] == graph::detail::V_UNREACHED)
+ {
+ vertex_state[w_prime] = graph::detail::V_ODD;
+ vertex_state[mate[w_prime]] = graph::detail::V_EVEN;
+ out_edge_iterator_t ei, ei_end;
+ for( tie(ei,ei_end) = out_edges(mate[w_prime], g); ei != ei_end; ++ei)
+ even_edges.push_back(*ei);
+ pred[w_prime] = v;
+ }
+
+ //w_prime == v_prime can happen below if we get an edge that has been
+ //shrunk into a blossom
+ else if (vertex_state[w_prime] == graph::detail::V_EVEN && w_prime != v_prime)
+ {
+ vertex_descriptor_t w_up = w_prime;
+ vertex_descriptor_t v_up = v_prime;
+ vertex_descriptor_t nearest_common_ancestor
+ = graph_traits<Graph>::null_vertex();
+ w_free_ancestor = graph_traits<Graph>::null_vertex();
+ v_free_ancestor = graph_traits<Graph>::null_vertex();
+
+ // We now need to distinguish between the case that
+ // w_prime and v_prime share an ancestor under the
+ // "parent" relation, in which case we've found a
+ // blossom and should shrink it, or the case that
+ // w_prime and v_prime both have distinct ancestors that
+ // are free, in which case we've found an alternating
+ // path between those two ancestors.
+
+ ++timestamp;
+
+ while (nearest_common_ancestor == graph_traits<Graph>::null_vertex() &&
+ (v_free_ancestor == graph_traits<Graph>::null_vertex() ||
+ w_free_ancestor == graph_traits<Graph>::null_vertex()
+ )
+ )
+ {
+ ancestor_of_w[w_up] = timestamp;
+ ancestor_of_v[v_up] = timestamp;
+
+ if (w_free_ancestor == graph_traits<Graph>::null_vertex())
+ w_up = parent(w_up);
+ if (v_free_ancestor == graph_traits<Graph>::null_vertex())
+ v_up = parent(v_up);
+
+ if (mate[v_up] == graph_traits<Graph>::null_vertex())
+ v_free_ancestor = v_up;
+ if (mate[w_up] == graph_traits<Graph>::null_vertex())
+ w_free_ancestor = w_up;
+
+ if (ancestor_of_w[v_up] == timestamp)
+ nearest_common_ancestor = v_up;
+ else if (ancestor_of_v[w_up] == timestamp)
+ nearest_common_ancestor = w_up;
+ else if (v_free_ancestor == w_free_ancestor &&
+ v_free_ancestor != graph_traits<Graph>::null_vertex())
+ nearest_common_ancestor = v_up;
+ }
+
+ if (nearest_common_ancestor == graph_traits<Graph>::null_vertex())
+ found_alternating_path = true; //to break out of the loop
+ else
+ {
+ //shrink the blossom
+ link_and_set_bridges(w_prime, nearest_common_ancestor, std::make_pair(w,v));
+ link_and_set_bridges(v_prime, nearest_common_ancestor, std::make_pair(v,w));
+ }
+ }
+ }
+
+ if (!found_alternating_path)
+ return false;
+
+ // retrieve the augmenting path and put it in aug_path
+ reversed_retrieve_augmenting_path(v, v_free_ancestor);
+ retrieve_augmenting_path(w, w_free_ancestor);
+
+ // augment the matching along aug_path
+ vertex_descriptor_t a,b;
+ while (!aug_path.empty())
+ {
+ a = aug_path.front();
+ aug_path.pop_front();
+ b = aug_path.front();
+ aug_path.pop_front();
+ mate[a] = b;
+ mate[b] = a;
+ }
+
+ return true;
+
+ }
+
+
+
+
+ template <typename PropertyMap>
+ void get_current_matching(PropertyMap pm)
+ {
+ vertex_iterator_t vi,vi_end;
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(pm, *vi, mate[*vi]);
+ }
+
+
+
+
+ template <typename PropertyMap>
+ void get_vertex_state_map(PropertyMap pm)
+ {
+ vertex_iterator_t vi,vi_end;
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(pm, *vi, vertex_state[origin[ds.find_set(*vi)]]);
+ }
+
+
+
+
+ private:
+
+ vertex_descriptor_t parent(vertex_descriptor_t x)
+ {
+ if (vertex_state[x] == graph::detail::V_EVEN
+ && mate[x] != graph_traits<Graph>::null_vertex())
+ return mate[x];
+ else if (vertex_state[x] == graph::detail::V_ODD)
+ return origin[ds.find_set(pred[x])];
+ else
+ return x;
+ }
+
+
+
+
+ void link_and_set_bridges(vertex_descriptor_t x,
+ vertex_descriptor_t stop_vertex,
+ vertex_pair_t the_bridge)
+ {
+ for(vertex_descriptor_t v = x; v != stop_vertex; v = parent(v))
+ {
+ ds.union_set(v, stop_vertex);
+ origin[ds.find_set(stop_vertex)] = stop_vertex;
+
+ if (vertex_state[v] == graph::detail::V_ODD)
+ {
+ bridge[v] = the_bridge;
+ out_edge_iterator_t oei, oei_end;
+ for(tie(oei, oei_end) = out_edges(v,g); oei != oei_end; ++oei)
+ even_edges.push_back(*oei);
+ }
+ }
+ }
+
+
+ // Since none of the STL containers support both constant-time
+ // concatenation and reversal, the process of expanding an
+ // augmenting path once we know one exists is a little more
+ // complicated than it has to be. If we know the path is from v to
+ // w, then the augmenting path is recursively defined as:
+ //
+ // path(v,w) = [v], if v = w
+ // = concat([v, mate[v]], path(pred[mate[v]], w),
+ // if v != w and vertex_state[v] == graph::detail::V_EVEN
+ // = concat([v], reverse(path(x,mate[v])), path(y,w)),
+ // if v != w, vertex_state[v] == graph::detail::V_ODD, and bridge[v] = (x,y)
+ //
+ // These next two mutually recursive functions implement this definition.
+
+ void retrieve_augmenting_path(vertex_descriptor_t v, vertex_descriptor_t w)
+ {
+ if (v == w)
+ aug_path.push_back(v);
+ else if (vertex_state[v] == graph::detail::V_EVEN)
+ {
+ aug_path.push_back(v);
+ aug_path.push_back(mate[v]);
+ retrieve_augmenting_path(pred[mate[v]], w);
+ }
+ else //vertex_state[v] == graph::detail::V_ODD
+ {
+ aug_path.push_back(v);
+ reversed_retrieve_augmenting_path(bridge[v].first, mate[v]);
+ retrieve_augmenting_path(bridge[v].second, w);
+ }
+ }
+
+
+ void reversed_retrieve_augmenting_path(vertex_descriptor_t v,
+ vertex_descriptor_t w)
+ {
+
+ if (v == w)
+ aug_path.push_back(v);
+ else if (vertex_state[v] == graph::detail::V_EVEN)
+ {
+ reversed_retrieve_augmenting_path(pred[mate[v]], w);
+ aug_path.push_back(mate[v]);
+ aug_path.push_back(v);
+ }
+ else //vertex_state[v] == graph::detail::V_ODD
+ {
+ reversed_retrieve_augmenting_path(bridge[v].second, w);
+ retrieve_augmenting_path(bridge[v].first, mate[v]);
+ aug_path.push_back(v);
+ }
+ }
+
+
+
+
+ //private data members
+
+ const Graph& g;
+ VertexIndexMap vm;
+ v_size_t n_vertices;
+
+ //storage for the property maps below
+ std::vector<vertex_descriptor_t> mate_vector;
+ std::vector<e_size_t> ancestor_of_v_vector;
+ std::vector<e_size_t> ancestor_of_w_vector;
+ std::vector<int> vertex_state_vector;
+ std::vector<vertex_descriptor_t> origin_vector;
+ std::vector<vertex_descriptor_t> pred_vector;
+ std::vector<vertex_pair_t> bridge_vector;
+ std::vector<vertex_descriptor_t> ds_parent_vector;
+ std::vector<v_size_t> ds_rank_vector;
+
+ //iterator property maps
+ vertex_to_vertex_map_t mate;
+ vertex_to_esize_map_t ancestor_of_v;
+ vertex_to_esize_map_t ancestor_of_w;
+ vertex_to_int_map_t vertex_state;
+ vertex_to_vertex_map_t origin;
+ vertex_to_vertex_map_t pred;
+ vertex_to_vertex_pair_map_t bridge;
+ vertex_to_vertex_map_t ds_parent_map;
+ vertex_to_vsize_map_t ds_rank_map;
+
+ vertex_list_t aug_path;
+ edge_list_t even_edges;
+ disjoint_sets< vertex_to_vsize_map_t, vertex_to_vertex_map_t > ds;
+
+ };
+
+
+
+
+ //***************************************************************************
+ //***************************************************************************
+ // Initial Matching Functors
+ //***************************************************************************
+ //***************************************************************************
+
+ template <typename Graph, typename MateMap>
+ struct greedy_matching
+ {
+ typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor_t;
+ typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
+
+ static void find_matching(const Graph& g, MateMap mate)
+ {
+ vertex_iterator_t vi, vi_end;
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(mate, *vi, graph_traits<Graph>::null_vertex());
+
+ edge_iterator_t ei, ei_end;
+ for( tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_descriptor_t e = *ei;
+ vertex_descriptor_t u = source(e,g);
+ vertex_descriptor_t v = target(e,g);
+
+ if (get(mate,u) == get(mate,v))
+ //only way equality can hold is if
+ // mate[u] == mate[v] == null_vertex
+ {
+ put(mate,u,v);
+ put(mate,v,u);
+ }
+ }
+ }
+ };
+
+
+
+
+ template <typename Graph, typename MateMap>
+ struct extra_greedy_matching
+ {
+ // The "extra greedy matching" is formed by repeating the
+ // following procedure as many times as possible: Choose the
+ // unmatched vertex v of minimum non-zero degree. Choose the
+ // neighbor w of v which is unmatched and has minimum degree over
+ // all of v's neighbors. Add (u,v) to the matching. Ties for
+ // either choice are broken arbitrarily. This procedure takes time
+ // O(m log n), where m is the number of edges in the graph and n
+ // is the number of vertices.
+
+ typedef typename graph_traits< Graph >::vertex_descriptor
+ vertex_descriptor_t;
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor_t;
+ typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
+ typedef std::pair<vertex_descriptor_t, vertex_descriptor_t> vertex_pair_t;
+
+ struct select_first
+ {
+ inline static vertex_descriptor_t select_vertex(const vertex_pair_t p)
+ {return p.first;}
+ };
+
+ struct select_second
+ {
+ inline static vertex_descriptor_t select_vertex(const vertex_pair_t p)
+ {return p.second;}
+ };
+
+ template <class PairSelector>
+ class less_than_by_degree
+ {
+ public:
+ less_than_by_degree(const Graph& g): m_g(g) {}
+ bool operator() (const vertex_pair_t x, const vertex_pair_t y)
+ {
+ return
+ out_degree(PairSelector::select_vertex(x), m_g)
+ < out_degree(PairSelector::select_vertex(y), m_g);
+ }
+ private:
+ const Graph& m_g;
+ };
+
+
+ static void find_matching(const Graph& g, MateMap mate)
+ {
+ typedef std::vector<std::pair<vertex_descriptor_t, vertex_descriptor_t> >
+ directed_edges_vector_t;
+
+ directed_edges_vector_t edge_list;
+ vertex_iterator_t vi, vi_end;
+ for(tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(mate, *vi, graph_traits<Graph>::null_vertex());
+
+ edge_iterator_t ei, ei_end;
+ for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_descriptor_t e = *ei;
+ vertex_descriptor_t u = source(e,g);
+ vertex_descriptor_t v = target(e,g);
+ edge_list.push_back(std::make_pair(u,v));
+ edge_list.push_back(std::make_pair(v,u));
+ }
+
+ //sort the edges by the degree of the target, then (using a
+ //stable sort) by degree of the source
+ std::sort(edge_list.begin(), edge_list.end(),
+ less_than_by_degree<select_second>(g));
+ std::stable_sort(edge_list.begin(), edge_list.end(),
+ less_than_by_degree<select_first>(g));
+
+ //construct the extra greedy matching
+ for(typename directed_edges_vector_t::const_iterator itr = edge_list.begin(); itr != edge_list.end(); ++itr)
+ {
+ if (get(mate,itr->first) == get(mate,itr->second))
+ //only way equality can hold is if mate[itr->first] == mate[itr->second] == null_vertex
+ {
+ put(mate, itr->first, itr->second);
+ put(mate, itr->second, itr->first);
+ }
+ }
+ }
+ };
+
+
+
+
+ template <typename Graph, typename MateMap>
+ struct empty_matching
+ {
+ typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
+
+ static void find_matching(const Graph& g, MateMap mate)
+ {
+ vertex_iterator_t vi, vi_end;
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ put(mate, *vi, graph_traits<Graph>::null_vertex());
+ }
+ };
+
+
+
+
+ //***************************************************************************
+ //***************************************************************************
+ // Matching Verifiers
+ //***************************************************************************
+ //***************************************************************************
+
+ namespace detail
+ {
+
+ template <typename SizeType>
+ class odd_components_counter : public dfs_visitor<>
+ // This depth-first search visitor will count the number of connected
+ // components with an odd number of vertices. It's used by
+ // maximum_matching_verifier.
+ {
+ public:
+ odd_components_counter(SizeType& c_count):
+ m_count(c_count)
+ {
+ m_count = 0;
+ }
+
+ template <class Vertex, class Graph>
+ void start_vertex(Vertex v, Graph&)
+ {
+ m_parity = false;
+ }
+
+ template <class Vertex, class Graph>
+ void discover_vertex(Vertex u, Graph&)
+ {
+ m_parity = !m_parity;
+ m_parity ? ++m_count : --m_count;
+ }
+
+ protected:
+ SizeType& m_count;
+
+ private:
+ bool m_parity;
+
+ };
+
+ }//namespace detail
+
+
+
+
+ template <typename Graph, typename MateMap,
+ typename VertexIndexMap = dummy_property_map>
+ struct no_matching_verifier
+ {
+ inline static bool
+ verify_matching(const Graph& g, MateMap mate, VertexIndexMap vm)
+ { return true;}
+ };
+
+
+
+
+ template <typename Graph, typename MateMap, typename VertexIndexMap>
+ struct maximum_cardinality_matching_verifier
+ {
+
+ template <typename X>
+ struct map_vertex_to_
+ {
+ typedef boost::iterator_property_map<typename std::vector<X>::iterator,
+ VertexIndexMap> type;
+ };
+
+ typedef typename graph_traits<Graph>::vertex_descriptor
+ vertex_descriptor_t;
+ typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
+ typedef typename map_vertex_to_<int>::type vertex_to_int_map_t;
+ typedef typename map_vertex_to_<vertex_descriptor_t>::type
+ vertex_to_vertex_map_t;
+
+
+ template <typename VertexStateMap>
+ struct non_odd_vertex {
+ //this predicate is used to create a filtered graph that
+ //excludes vertices labeled "graph::detail::V_ODD"
+ non_odd_vertex() : vertex_state(0) { }
+
+ non_odd_vertex(VertexStateMap* arg_vertex_state)
+ : vertex_state(arg_vertex_state) { }
+
+ template <typename Vertex>
+ bool operator()(const Vertex& v) const
+ {
+ BOOST_ASSERT(vertex_state);
+ return get(*vertex_state, v) != graph::detail::V_ODD;
+ }
+
+ VertexStateMap* vertex_state;
+ };
+
+
+ static bool verify_matching(const Graph& g, MateMap mate, VertexIndexMap vm)
+ {
+ //For any graph G, let o(G) be the number of connected
+ //components in G of odd size. For a subset S of G's vertex set
+ //V(G), let (G - S) represent the subgraph of G induced by
+ //removing all vertices in S from G. Let M(G) be the size of the
+ //maximum cardinality matching in G. Then the Tutte-Berge
+ //formula guarantees that
+ //
+ // 2 * M(G) = min ( |V(G)| + |U| + o(G - U) )
+ //
+ //where the minimum is taken over all subsets U of
+ //V(G). Edmonds' algorithm finds a set U that achieves the
+ //minimum in the above formula, namely the vertices labeled
+ //"ODD." This function runs one iteration of Edmonds' algorithm
+ //to find U, then verifies that the size of the matching given
+ //by mate satisfies the Tutte-Berge formula.
+
+ //first, make sure it's a valid matching
+ if (!is_a_matching(g,mate,vm))
+ return false;
+
+ //We'll try to augment the matching once. This serves two
+ //purposes: first, if we find some augmenting path, the matching
+ //is obviously non-maximum. Second, running edmonds' algorithm
+ //on a graph with no augmenting path will create the
+ //Edmonds-Gallai decomposition that we need as a certificate of
+ //maximality - we can get it by looking at the vertex_state map
+ //that results.
+ edmonds_augmenting_path_finder<Graph,MateMap,VertexIndexMap>
+ augmentor(g,mate,vm);
+ if (augmentor.augment_matching())
+ return false;
+
+ std::vector<int> vertex_state_vector(num_vertices(g));
+ vertex_to_int_map_t vertex_state(vertex_state_vector.begin(), vm);
+ augmentor.get_vertex_state_map(vertex_state);
+
+ //count the number of graph::detail::V_ODD vertices
+ v_size_t num_odd_vertices = 0;
+ vertex_iterator_t vi, vi_end;
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ if (vertex_state[*vi] == graph::detail::V_ODD)
+ ++num_odd_vertices;
+
+ //count the number of connected components with odd cardinality
+ //in the graph without graph::detail::V_ODD vertices
+ non_odd_vertex<vertex_to_int_map_t> filter(&vertex_state);
+ filtered_graph<Graph, keep_all, non_odd_vertex<vertex_to_int_map_t> > fg(g, keep_all(), filter);
+
+ v_size_t num_odd_components;
+ detail::odd_components_counter<v_size_t> occ(num_odd_components);
+ depth_first_search(fg, visitor(occ).vertex_index_map(vm));
+
+ if (2 * matching_size(g,mate,vm) == num_vertices(g) + num_odd_vertices - num_odd_components)
+ return true;
+ else
+ return false;
+ }
+ };
+
+
+
+
+ template <typename Graph,
+ typename MateMap,
+ typename VertexIndexMap,
+ template <typename, typename, typename> class AugmentingPathFinder,
+ template <typename, typename> class InitialMatchingFinder,
+ template <typename, typename, typename> class MatchingVerifier>
+ bool matching(const Graph& g, MateMap mate, VertexIndexMap vm)
+ {
+
+ InitialMatchingFinder<Graph,MateMap>::find_matching(g,mate);
+
+ AugmentingPathFinder<Graph,MateMap,VertexIndexMap> augmentor(g,mate,vm);
+ bool not_maximum_yet = true;
+ while(not_maximum_yet)
+ {
+ not_maximum_yet = augmentor.augment_matching();
+ }
+ augmentor.get_current_matching(mate);
+
+ return MatchingVerifier<Graph,MateMap,VertexIndexMap>::verify_matching(g,mate,vm);
+
+ }
+
+
+
+
+ template <typename Graph, typename MateMap, typename VertexIndexMap>
+ inline bool checked_edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate, VertexIndexMap vm)
+ {
+ return matching
+ < Graph, MateMap, VertexIndexMap,
+ edmonds_augmenting_path_finder, extra_greedy_matching, maximum_cardinality_matching_verifier>
+ (g, mate, vm);
+ }
+
+
+
+
+ template <typename Graph, typename MateMap>
+ inline bool checked_edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate)
+ {
+ return checked_edmonds_maximum_cardinality_matching(g, mate, get(vertex_index,g));
+ }
+
+
+
+
+ template <typename Graph, typename MateMap, typename VertexIndexMap>
+ inline void edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate, VertexIndexMap vm)
+ {
+ matching < Graph, MateMap, VertexIndexMap,
+ edmonds_augmenting_path_finder, extra_greedy_matching, no_matching_verifier>
+ (g, mate, vm);
+ }
+
+
+
+
+ template <typename Graph, typename MateMap>
+ inline void edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate)
+ {
+ edmonds_maximum_cardinality_matching(g, mate, get(vertex_index,g));
+ }
+
+}//namespace boost
+
+#endif //BOOST_GRAPH_MAXIMUM_CARDINALITY_MATCHING_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/minimum_degree_ordering.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/minimum_degree_ordering.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,655 @@
+//-*-c++-*-
+//=======================================================================
+// Copyright 1997-2001 University of Notre Dame.
+// Authors: Lie-Quan Lee, Jeremy Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef MINIMUM_DEGREE_ORDERING_HPP
+#define MINIMUM_DEGREE_ORDERING_HPP
+
+#include <vector>
+#include <cassert>
+#include <boost/config.hpp>
+#include <boost/pending/bucket_sorter.hpp>
+#include <boost/detail/numeric_traits.hpp> // for integer_traits
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map.hpp>
+
+namespace boost {
+
+ namespace detail {
+
+ //
+ // Given a set of n integers (where the integer values range from
+ // zero to n-1), we want to keep track of a collection of stacks
+ // of integers. It so happens that an integer will appear in at
+ // most one stack at a time, so the stacks form disjoint sets.
+ // Because of these restrictions, we can use one big array to
+ // store all the stacks, intertwined with one another.
+ // No allocation/deallocation happens in the push()/pop() methods
+ // so this is faster than using std::stack's.
+ //
+ template <class SignedInteger>
+ class Stacks {
+ typedef SignedInteger value_type;
+ typedef typename std::vector<value_type>::size_type size_type;
+ public:
+ Stacks(size_type n) : data(n) {}
+
+ //: stack
+ class stack {
+ typedef typename std::vector<value_type>::iterator Iterator;
+ public:
+ stack(Iterator _data, const value_type& head)
+ : data(_data), current(head) {}
+
+ // did not use default argument here to avoid internal compiler error
+ // in g++.
+ stack(Iterator _data)
+ : data(_data), current(-(std::numeric_limits<value_type>::max)()) {}
+
+ void pop() {
+ assert(! empty());
+ current = data[current];
+ }
+ void push(value_type v) {
+ data[v] = current;
+ current = v;
+ }
+ bool empty() {
+ return current == -(std::numeric_limits<value_type>::max)();
+ }
+ value_type& top() { return current; }
+ private:
+ Iterator data;
+ value_type current;
+ };
+
+ // To return a stack object
+ stack make_stack()
+ { return stack(data.begin()); }
+ protected:
+ std::vector<value_type> data;
+ };
+
+
+ // marker class, a generalization of coloring.
+ //
+ // This class is to provide a generalization of coloring which has
+ // complexity of amortized constant time to set all vertices' color
+ // back to be untagged. It implemented by increasing a tag.
+ //
+ // The colors are:
+ // not tagged
+ // tagged
+ // multiple_tagged
+ // done
+ //
+ template <class SignedInteger, class Vertex, class VertexIndexMap>
+ class Marker {
+ typedef SignedInteger value_type;
+ typedef typename std::vector<value_type>::size_type size_type;
+
+ static value_type done()
+ { return (std::numeric_limits<value_type>::max)()/2; }
+ public:
+ Marker(size_type _num, VertexIndexMap index_map)
+ : tag(1 - (std::numeric_limits<value_type>::max)()),
+ data(_num, - (std::numeric_limits<value_type>::max)()),
+ id(index_map) {}
+
+ void mark_done(Vertex node) { data[get(id, node)] = done(); }
+
+ bool is_done(Vertex node) { return data[get(id, node)] == done(); }
+
+ void mark_tagged(Vertex node) { data[get(id, node)] = tag; }
+
+ void mark_multiple_tagged(Vertex node) { data[get(id, node)] = multiple_tag; }
+
+ bool is_tagged(Vertex node) const { return data[get(id, node)] >= tag; }
+
+ bool is_not_tagged(Vertex node) const { return data[get(id, node)] < tag; }
+
+ bool is_multiple_tagged(Vertex node) const
+ { return data[get(id, node)] >= multiple_tag; }
+
+ void increment_tag() {
+ const size_type num = data.size();
+ ++tag;
+ if ( tag >= done() ) {
+ tag = 1 - (std::numeric_limits<value_type>::max)();
+ for (size_type i = 0; i < num; ++i)
+ if ( data[i] < done() )
+ data[i] = - (std::numeric_limits<value_type>::max)();
+ }
+ }
+
+ void set_multiple_tag(value_type mdeg0)
+ {
+ const size_type num = data.size();
+ multiple_tag = tag + mdeg0;
+
+ if ( multiple_tag >= done() ) {
+ tag = 1-(std::numeric_limits<value_type>::max)();
+
+ for (size_type i=0; i<num; i++)
+ if ( data[i] < done() )
+ data[i] = -(std::numeric_limits<value_type>::max)();
+
+ multiple_tag = tag + mdeg0;
+ }
+ }
+
+ void set_tag_as_multiple_tag() { tag = multiple_tag; }
+
+ protected:
+ value_type tag;
+ value_type multiple_tag;
+ std::vector<value_type> data;
+ VertexIndexMap id;
+ };
+
+ template< class Iterator, class SignedInteger,
+ class Vertex, class VertexIndexMap, int offset = 1 >
+ class Numbering {
+ typedef SignedInteger number_type;
+ number_type num; //start from 1 instead of zero
+ Iterator data;
+ number_type max_num;
+ VertexIndexMap id;
+ public:
+ Numbering(Iterator _data, number_type _max_num, VertexIndexMap id)
+ : num(1), data(_data), max_num(_max_num), id(id) {}
+ void operator()(Vertex node) { data[get(id, node)] = -num; }
+ bool all_done(number_type i = 0) const { return num + i > max_num; }
+ void increment(number_type i = 1) { num += i; }
+ bool is_numbered(Vertex node) const {
+ return data[get(id, node)] < 0;
+ }
+ void indistinguishable(Vertex i, Vertex j) {
+ data[get(id, i)] = - (get(id, j) + offset);
+ }
+ };
+
+ template <class SignedInteger, class Vertex, class VertexIndexMap>
+ class degreelists_marker {
+ public:
+ typedef SignedInteger value_type;
+ typedef typename std::vector<value_type>::size_type size_type;
+ degreelists_marker(size_type n, VertexIndexMap id)
+ : marks(n, 0), id(id) {}
+ void mark_need_update(Vertex i) { marks[get(id, i)] = 1; }
+ bool need_update(Vertex i) { return marks[get(id, i)] == 1; }
+ bool outmatched_or_done (Vertex i) { return marks[get(id, i)] == -1; }
+ void mark(Vertex i) { marks[get(id, i)] = -1; }
+ void unmark(Vertex i) { marks[get(id, i)] = 0; }
+ private:
+ std::vector<value_type> marks;
+ VertexIndexMap id;
+ };
+
+ // Helper function object for edge removal
+ template <class Graph, class MarkerP, class NumberD, class Stack,
+ class VertexIndexMap>
+ class predicateRemoveEdge1 {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ public:
+ predicateRemoveEdge1(Graph& _g, MarkerP& _marker,
+ NumberD _numbering, Stack& n_e, VertexIndexMap id)
+ : g(&_g), marker(&_marker), numbering(_numbering),
+ neighbor_elements(&n_e), id(id) {}
+
+ bool operator()(edge_t e) {
+ vertex_t dist = target(e, *g);
+ if ( marker->is_tagged(dist) )
+ return true;
+ marker->mark_tagged(dist);
+ if (numbering.is_numbered(dist)) {
+ neighbor_elements->push(get(id, dist));
+ return true;
+ }
+ return false;
+ }
+ private:
+ Graph* g;
+ MarkerP* marker;
+ NumberD numbering;
+ Stack* neighbor_elements;
+ VertexIndexMap id;
+ };
+
+ // Helper function object for edge removal
+ template <class Graph, class MarkerP>
+ class predicate_remove_tagged_edges
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ public:
+ predicate_remove_tagged_edges(Graph& _g, MarkerP& _marker)
+ : g(&_g), marker(&_marker) {}
+
+ bool operator()(edge_t e) {
+ vertex_t dist = target(e, *g);
+ if ( marker->is_tagged(dist) )
+ return true;
+ return false;
+ }
+ private:
+ Graph* g;
+ MarkerP* marker;
+ };
+
+ template<class Graph, class DegreeMap,
+ class InversePermutationMap,
+ class PermutationMap,
+ class SuperNodeMap,
+ class VertexIndexMap>
+ class mmd_impl
+ {
+ // Typedefs
+ typedef graph_traits<Graph> Traits;
+ typedef typename Traits::vertices_size_type size_type;
+ typedef typename detail::integer_traits<size_type>::difference_type
+ diff_t;
+ typedef typename Traits::vertex_descriptor vertex_t;
+ typedef typename Traits::adjacency_iterator adj_iter;
+ typedef iterator_property_map<vertex_t*,
+ identity_property_map, vertex_t, vertex_t&> IndexVertexMap;
+ typedef detail::Stacks<diff_t> Workspace;
+ typedef bucket_sorter<size_type, vertex_t, DegreeMap, VertexIndexMap>
+ DegreeLists;
+ typedef Numbering<InversePermutationMap, diff_t, vertex_t,VertexIndexMap>
+ NumberingD;
+ typedef degreelists_marker<diff_t, vertex_t, VertexIndexMap>
+ DegreeListsMarker;
+ typedef Marker<diff_t, vertex_t, VertexIndexMap> MarkerP;
+
+ // Data Members
+
+ // input parameters
+ Graph& G;
+ int delta;
+ DegreeMap degree;
+ InversePermutationMap inverse_perm;
+ PermutationMap perm;
+ SuperNodeMap supernode_size;
+ VertexIndexMap vertex_index_map;
+
+ // internal data-structures
+ std::vector<vertex_t> index_vertex_vec;
+ size_type n;
+ IndexVertexMap index_vertex_map;
+ DegreeLists degreelists;
+ NumberingD numbering;
+ DegreeListsMarker degree_lists_marker;
+ MarkerP marker;
+ Workspace work_space;
+ public:
+ mmd_impl(Graph& g, size_type n_, int delta, DegreeMap degree,
+ InversePermutationMap inverse_perm,
+ PermutationMap perm,
+ SuperNodeMap supernode_size,
+ VertexIndexMap id)
+ : G(g), delta(delta), degree(degree),
+ inverse_perm(inverse_perm),
+ perm(perm),
+ supernode_size(supernode_size),
+ vertex_index_map(id),
+ index_vertex_vec(n_),
+ n(n_),
+ degreelists(n_ + 1, n_, degree, id),
+ numbering(inverse_perm, n_, vertex_index_map),
+ degree_lists_marker(n_, vertex_index_map),
+ marker(n_, vertex_index_map),
+ work_space(n_)
+ {
+ typename graph_traits<Graph>::vertex_iterator v, vend;
+ size_type vid = 0;
+ for (tie(v, vend) = vertices(G); v != vend; ++v, ++vid)
+ index_vertex_vec[vid] = *v;
+ index_vertex_map = IndexVertexMap(&index_vertex_vec[0]);
+
+ // Initialize degreelists. Degreelists organizes the nodes
+ // according to their degree.
+ for (tie(v, vend) = vertices(G); v != vend; ++v) {
+ put(degree, *v, out_degree(*v, G));
+ degreelists.push(*v);
+ }
+ }
+
+ void do_mmd()
+ {
+ // Eliminate the isolated nodes -- these are simply the nodes
+ // with no neighbors, which are accessible as a list (really, a
+ // stack) at location 0. Since these don't affect any other
+ // nodes, we can eliminate them without doing degree updates.
+ typename DegreeLists::stack list_isolated = degreelists[0];
+ while (!list_isolated.empty()) {
+ vertex_t node = list_isolated.top();
+ marker.mark_done(node);
+ numbering(node);
+ numbering.increment();
+ list_isolated.pop();
+ }
+ size_type min_degree = 1;
+ typename DegreeLists::stack list_min_degree = degreelists[min_degree];
+
+ while (list_min_degree.empty()) {
+ ++min_degree;
+ list_min_degree = degreelists[min_degree];
+ }
+
+ // check if the whole eliminating process is done
+ while (!numbering.all_done()) {
+
+ size_type min_degree_limit = min_degree + delta; // WARNING
+ typename Workspace::stack llist = work_space.make_stack();
+
+ // multiple elimination
+ while (delta >= 0) {
+
+ // Find the next non-empty degree
+ for (list_min_degree = degreelists[min_degree];
+ list_min_degree.empty() && min_degree <= min_degree_limit;
+ ++min_degree, list_min_degree = degreelists[min_degree])
+ ;
+ if (min_degree > min_degree_limit)
+ break;
+
+ const vertex_t node = list_min_degree.top();
+ const size_type node_id = get(vertex_index_map, node);
+ list_min_degree.pop();
+ numbering(node);
+
+ // check if node is the last one
+ if (numbering.all_done(supernode_size[node])) {
+ numbering.increment(supernode_size[node]);
+ break;
+ }
+ marker.increment_tag();
+ marker.mark_tagged(node);
+
+ this->eliminate(node);
+
+ numbering.increment(supernode_size[node]);
+ llist.push(node_id);
+ } // multiple elimination
+
+ if (numbering.all_done())
+ break;
+
+ this->update( llist, min_degree);
+ }
+
+ } // do_mmd()
+
+ void eliminate(vertex_t node)
+ {
+ typename Workspace::stack element_neighbor = work_space.make_stack();
+
+ // Create two function objects for edge removal
+ typedef typename Workspace::stack WorkStack;
+ predicateRemoveEdge1<Graph, MarkerP, NumberingD,
+ WorkStack, VertexIndexMap>
+ p(G, marker, numbering, element_neighbor, vertex_index_map);
+
+ predicate_remove_tagged_edges<Graph, MarkerP> p2(G, marker);
+
+ // Reconstruct the adjacent node list, push element neighbor in a List.
+ remove_out_edge_if(node, p, G);
+ //during removal element neighbors are collected.
+
+ while (!element_neighbor.empty()) {
+ // element absorb
+ size_type e_id = element_neighbor.top();
+ vertex_t element = get(index_vertex_map, e_id);
+ adj_iter i, i_end;
+ for (tie(i, i_end) = adjacent_vertices(element, G); i != i_end; ++i){
+ vertex_t i_node = *i;
+ if (!marker.is_tagged(i_node) && !numbering.is_numbered(i_node)) {
+ marker.mark_tagged(i_node);
+ add_edge(node, i_node, G);
+ }
+ }
+ element_neighbor.pop();
+ }
+ adj_iter v, ve;
+ for (tie(v, ve) = adjacent_vertices(node, G); v != ve; ++v) {
+ vertex_t v_node = *v;
+ if (!degree_lists_marker.need_update(v_node)
+ && !degree_lists_marker.outmatched_or_done(v_node)) {
+ degreelists.remove(v_node);
+ }
+ //update out edges of v_node
+ remove_out_edge_if(v_node, p2, G);
+
+ if ( out_degree(v_node, G) == 0 ) { // indistinguishable nodes
+ supernode_size[node] += supernode_size[v_node];
+ supernode_size[v_node] = 0;
+ numbering.indistinguishable(v_node, node);
+ marker.mark_done(v_node);
+ degree_lists_marker.mark(v_node);
+ } else { // not indistinguishable nodes
+ add_edge(v_node, node, G);
+ degree_lists_marker.mark_need_update(v_node);
+ }
+ }
+ } // eliminate()
+
+
+ template <class Stack>
+ void update(Stack llist, size_type& min_degree)
+ {
+ size_type min_degree0 = min_degree + delta + 1;
+
+ while (! llist.empty()) {
+ size_type deg, deg0 = 0;
+
+ marker.set_multiple_tag(min_degree0);
+ typename Workspace::stack q2list = work_space.make_stack();
+ typename Workspace::stack qxlist = work_space.make_stack();
+
+ vertex_t current = get(index_vertex_map, llist.top());
+ adj_iter i, ie;
+ for (tie(i,ie) = adjacent_vertices(current, G); i != ie; ++i) {
+ vertex_t i_node = *i;
+ const size_type i_id = get(vertex_index_map, i_node);
+ if (supernode_size[i_node] != 0) {
+ deg0 += supernode_size[i_node];
+ marker.mark_multiple_tagged(i_node);
+ if (degree_lists_marker.need_update(i_node)) {
+ if (out_degree(i_node, G) == 2)
+ q2list.push(i_id);
+ else
+ qxlist.push(i_id);
+ }
+ }
+ }
+
+ while (!q2list.empty()) {
+ const size_type u_id = q2list.top();
+ vertex_t u_node = get(index_vertex_map, u_id);
+ // if u_id is outmatched by others, no need to update degree
+ if (degree_lists_marker.outmatched_or_done(u_node)) {
+ q2list.pop();
+ continue;
+ }
+ marker.increment_tag();
+ deg = deg0;
+
+ adj_iter nu = adjacent_vertices(u_node, G).first;
+ vertex_t neighbor = *nu;
+ if (neighbor == u_node) {
+ ++nu;
+ neighbor = *nu;
+ }
+ if (numbering.is_numbered(neighbor)) {
+ adj_iter i, ie;
+ for (tie(i,ie) = adjacent_vertices(neighbor, G);
+ i != ie; ++i) {
+ const vertex_t i_node = *i;
+ if (i_node == u_node || supernode_size[i_node] == 0)
+ continue;
+ if (marker.is_tagged(i_node)) {
+ if (degree_lists_marker.need_update(i_node)) {
+ if ( out_degree(i_node, G) == 2 ) { // is indistinguishable
+ supernode_size[u_node] += supernode_size[i_node];
+ supernode_size[i_node] = 0;
+ numbering.indistinguishable(i_node, u_node);
+ marker.mark_done(i_node);
+ degree_lists_marker.mark(i_node);
+ } else // is outmatched
+ degree_lists_marker.mark(i_node);
+ }
+ } else {
+ marker.mark_tagged(i_node);
+ deg += supernode_size[i_node];
+ }
+ }
+ } else
+ deg += supernode_size[neighbor];
+
+ deg -= supernode_size[u_node];
+ degree[u_node] = deg; //update degree
+ degreelists[deg].push(u_node);
+ //u_id has been pushed back into degreelists
+ degree_lists_marker.unmark(u_node);
+ if (min_degree > deg)
+ min_degree = deg;
+ q2list.pop();
+ } // while (!q2list.empty())
+
+ while (!qxlist.empty()) {
+ const size_type u_id = qxlist.top();
+ const vertex_t u_node = get(index_vertex_map, u_id);
+
+ // if u_id is outmatched by others, no need to update degree
+ if (degree_lists_marker.outmatched_or_done(u_node)) {
+ qxlist.pop();
+ continue;
+ }
+ marker.increment_tag();
+ deg = deg0;
+ adj_iter i, ie;
+ for (tie(i, ie) = adjacent_vertices(u_node, G); i != ie; ++i) {
+ vertex_t i_node = *i;
+ if (marker.is_tagged(i_node))
+ continue;
+ marker.mark_tagged(i_node);
+
+ if (numbering.is_numbered(i_node)) {
+ adj_iter j, je;
+ for (tie(j, je) = adjacent_vertices(i_node, G); j != je; ++j) {
+ const vertex_t j_node = *j;
+ if (marker.is_not_tagged(j_node)) {
+ marker.mark_tagged(j_node);
+ deg += supernode_size[j_node];
+ }
+ }
+ } else
+ deg += supernode_size[i_node];
+ } // for adjacent vertices of u_node
+ deg -= supernode_size[u_node];
+ degree[u_node] = deg;
+ degreelists[deg].push(u_node);
+ // u_id has been pushed back into degreelists
+ degree_lists_marker.unmark(u_node);
+ if (min_degree > deg)
+ min_degree = deg;
+ qxlist.pop();
+ } // while (!qxlist.empty()) {
+
+ marker.set_tag_as_multiple_tag();
+ llist.pop();
+ } // while (! llist.empty())
+
+ } // update()
+
+
+ void build_permutation(InversePermutationMap next,
+ PermutationMap prev)
+ {
+ // collect the permutation info
+ size_type i;
+ for (i = 0; i < n; ++i) {
+ diff_t size = supernode_size[get(index_vertex_map, i)];
+ if ( size <= 0 ) {
+ prev[i] = next[i];
+ supernode_size[get(index_vertex_map, i)]
+ = next[i] + 1; // record the supernode info
+ } else
+ prev[i] = - next[i];
+ }
+ for (i = 1; i < n + 1; ++i) {
+ if ( prev[i-1] > 0 )
+ continue;
+ diff_t parent = i;
+ while ( prev[parent - 1] < 0 ) {
+ parent = - prev[parent - 1];
+ }
+
+ diff_t root = parent;
+ diff_t num = prev[root - 1] + 1;
+ next[i-1] = - num;
+ prev[root-1] = num;
+
+ parent = i;
+ diff_t next_node = - prev[parent - 1];
+ while (next_node > 0) {
+ prev[parent-1] = - root;
+ parent = next_node;
+ next_node = - prev[parent - 1];
+ }
+ }
+ for (i = 0; i < n; i++) {
+ diff_t num = - next[i] - 1;
+ next[i] = num;
+ prev[num] = i;
+ }
+ } // build_permutation()
+ };
+
+ } //namespace detail
+
+
+ // MMD algorithm
+ //
+ //The implementation presently includes the enhancements for mass
+ //elimination, incomplete degree update, multiple elimination, and
+ //external degree.
+ //
+ //Important Note: This implementation requires the BGL graph to be
+ //directed. Therefore, nonzero entry (i, j) in a symmetrical matrix
+ //A coresponds to two directed edges (i->j and j->i).
+ //
+ //see Alan George and Joseph W. H. Liu, The Evolution of the Minimum
+ //Degree Ordering Algorithm, SIAM Review, 31, 1989, Page 1-19
+ template<class Graph, class DegreeMap,
+ class InversePermutationMap,
+ class PermutationMap,
+ class SuperNodeMap, class VertexIndexMap>
+ void minimum_degree_ordering
+ (Graph& G,
+ DegreeMap degree,
+ InversePermutationMap inverse_perm,
+ PermutationMap perm,
+ SuperNodeMap supernode_size,
+ int delta,
+ VertexIndexMap vertex_index_map)
+ {
+ detail::mmd_impl<Graph,DegreeMap,InversePermutationMap,
+ PermutationMap, SuperNodeMap, VertexIndexMap>
+ impl(G, num_vertices(G), delta, degree, inverse_perm,
+ perm, supernode_size, vertex_index_map);
+ impl.do_mmd();
+ impl.build_permutation(inverse_perm, perm);
+ }
+
+} // namespace boost
+
+#endif // MINIMUM_DEGREE_ORDERING_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/named_function_params.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/named_function_params.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,795 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP
+#define BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP
+
+#include <boost/graph/properties.hpp>
+
+namespace boost {
+
+ struct distance_compare_t { };
+ struct distance_combine_t { };
+ struct distance_inf_t { };
+ struct distance_zero_t { };
+ struct buffer_param_t { };
+ struct edge_copy_t { };
+ struct vertex_copy_t { };
+ struct vertex_isomorphism_t { };
+ struct vertex_invariant_t { };
+ struct vertex_invariant1_t { };
+ struct vertex_invariant2_t { };
+ struct edge_compare_t { };
+ struct vertex_max_invariant_t { };
+ struct orig_to_copy_t { };
+ struct root_vertex_t { };
+ struct attractive_force_t { };
+ struct repulsive_force_t { };
+ struct force_pairs_t { };
+ struct cooling_t { };
+ struct vertex_displacement_t { };
+ struct iterations_t { };
+ struct diameter_range_t { };
+ struct learning_constant_range_t { };
+
+ namespace detail {
+ template <class T>
+ struct wrap_ref {
+ wrap_ref(T& r) : ref(r) {}
+ T& ref;
+ };
+ }
+
+ template <typename T, typename Tag, typename Base = no_property>
+ struct bgl_named_params : public Base
+ {
+ typedef bgl_named_params self;
+ typedef Base next_type;
+ typedef Tag tag_type;
+ typedef T value_type;
+ bgl_named_params(T v) : m_value(v) { }
+ bgl_named_params(T v, const Base& b) : Base(b), m_value(v) { }
+ T m_value;
+
+ template <typename WeightMap>
+ bgl_named_params<WeightMap, edge_weight_t, self>
+ weight_map(const WeightMap& pmap) const {
+ typedef bgl_named_params<WeightMap, edge_weight_t, self> Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename WeightMap>
+ bgl_named_params<WeightMap, edge_weight2_t, self>
+ weight_map2(const WeightMap& pmap) const {
+ typedef bgl_named_params<WeightMap, edge_weight2_t, self> Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename DistanceMap>
+ bgl_named_params<DistanceMap, vertex_distance_t, self>
+ distance_map(const DistanceMap& pmap) const {
+ typedef bgl_named_params<DistanceMap, vertex_distance_t, self> Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename PredecessorMap>
+ bgl_named_params<PredecessorMap, vertex_predecessor_t, self>
+ predecessor_map(const PredecessorMap& pmap) const {
+ typedef bgl_named_params<PredecessorMap, vertex_predecessor_t, self>
+ Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename RankMap>
+ bgl_named_params<RankMap, vertex_rank_t, self>
+ rank_map(const RankMap& pmap) const {
+ typedef bgl_named_params<RankMap, vertex_rank_t, self>
+ Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename RootMap>
+ bgl_named_params<RootMap, vertex_root_t, self>
+ root_map(const RootMap& pmap) const {
+ typedef bgl_named_params<RootMap, vertex_root_t, self>
+ Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename Vertex>
+ bgl_named_params<Vertex, root_vertex_t, self>
+ root_vertex(const Vertex& r) const {
+ typedef bgl_named_params<Vertex, root_vertex_t, self> Params;
+ return Params(r, *this);
+ }
+
+ template <typename EdgeCentralityMap>
+ bgl_named_params<EdgeCentralityMap, edge_centrality_t, self>
+ edge_centrality_map(const EdgeCentralityMap& r) const {
+ typedef bgl_named_params<EdgeCentralityMap, edge_centrality_t, self> Params;
+ return Params(r, *this);
+ }
+
+ template <typename CentralityMap>
+ bgl_named_params<CentralityMap, vertex_centrality_t, self>
+ centrality_map(const CentralityMap& r) const {
+ typedef bgl_named_params<CentralityMap, vertex_centrality_t, self> Params;
+ return Params(r, *this);
+ }
+
+ template <typename ColorMap>
+ bgl_named_params<ColorMap, vertex_color_t, self>
+ color_map(const ColorMap& pmap) const {
+ typedef bgl_named_params<ColorMap, vertex_color_t, self> Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename ColorMap>
+ bgl_named_params<ColorMap, vertex_color_t, self>
+ vertex_color_map(const ColorMap& pmap) const {
+ typedef bgl_named_params<ColorMap, vertex_color_t, self> Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename ColorMap>
+ bgl_named_params<ColorMap, edge_color_t, self>
+ edge_color_map(const ColorMap& pmap) const {
+ typedef bgl_named_params<ColorMap, edge_color_t, self> Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename CapacityMap>
+ bgl_named_params<CapacityMap, edge_capacity_t, self>
+ capacity_map(CapacityMap pmap) {
+ typedef bgl_named_params<CapacityMap, edge_capacity_t, self> Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename Residual_CapacityMap>
+ bgl_named_params<Residual_CapacityMap, edge_residual_capacity_t, self>
+ residual_capacity_map(Residual_CapacityMap pmap) {
+ typedef bgl_named_params<Residual_CapacityMap,
+ edge_residual_capacity_t, self>
+ Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename ReverseMap>
+ bgl_named_params<ReverseMap, edge_reverse_t, self>
+ reverse_edge_map(ReverseMap pmap) {
+ typedef bgl_named_params<ReverseMap,
+ edge_reverse_t, self>
+ Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename DiscoverTimeMap>
+ bgl_named_params<DiscoverTimeMap, vertex_discover_time_t, self>
+ discover_time_map(const DiscoverTimeMap& pmap) const {
+ typedef bgl_named_params<DiscoverTimeMap, vertex_discover_time_t, self>
+ Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename LowPointMap>
+ bgl_named_params<LowPointMap, vertex_lowpoint_t, self>
+ lowpoint_map(const LowPointMap& pmap) const {
+ typedef bgl_named_params<LowPointMap, vertex_lowpoint_t, self>
+ Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename IndexMap>
+ bgl_named_params<IndexMap, vertex_index_t, self>
+ vertex_index_map(const IndexMap& pmap) const {
+ typedef bgl_named_params<IndexMap, vertex_index_t, self> Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename IndexMap>
+ bgl_named_params<IndexMap, vertex_index1_t, self>
+ vertex_index1_map(const IndexMap& pmap) const {
+ typedef bgl_named_params<IndexMap, vertex_index1_t, self> Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename IndexMap>
+ bgl_named_params<IndexMap, vertex_index2_t, self>
+ vertex_index2_map(const IndexMap& pmap) const {
+ typedef bgl_named_params<IndexMap, vertex_index2_t, self> Params;
+ return Params(pmap, *this);
+ }
+
+ template <typename Visitor>
+ bgl_named_params<Visitor, graph_visitor_t, self>
+ visitor(const Visitor& vis) const {
+ typedef bgl_named_params<Visitor, graph_visitor_t, self> Params;
+ return Params(vis, *this);
+ }
+
+ template <typename Compare>
+ bgl_named_params<Compare, distance_compare_t, self>
+ distance_compare(Compare cmp) const {
+ typedef bgl_named_params<Compare, distance_compare_t, self> Params;
+ return Params(cmp, *this);
+ }
+
+ template <typename Combine>
+ bgl_named_params<Combine, distance_combine_t, self>
+ distance_combine(Combine cmb) const {
+ typedef bgl_named_params<Combine, distance_combine_t, self> Params;
+ return Params(cmb, *this);
+ }
+
+ template <typename Init>
+ bgl_named_params<Init, distance_inf_t, self>
+ distance_inf(Init init) const {
+ typedef bgl_named_params<Init, distance_inf_t, self> Params;
+ return Params(init, *this);
+ }
+
+ template <typename Init>
+ bgl_named_params<Init, distance_zero_t, self>
+ distance_zero(Init init) const {
+ typedef bgl_named_params<Init, distance_zero_t, self> Params;
+ return Params(init, *this);
+ }
+
+ template <typename Buffer>
+ bgl_named_params<detail::wrap_ref<Buffer>, buffer_param_t, self>
+ buffer(Buffer& b) const {
+ typedef bgl_named_params<detail::wrap_ref<Buffer>, buffer_param_t, self>
+ Params;
+ return Params(detail::wrap_ref<Buffer>(b), *this);
+ }
+
+ template <typename Copier>
+ bgl_named_params<Copier, edge_copy_t, self>
+ edge_copy(const Copier& c) const {
+ typedef bgl_named_params<Copier, edge_copy_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template <typename Copier>
+ bgl_named_params<Copier, vertex_copy_t, self>
+ vertex_copy(const Copier& c) const {
+ typedef bgl_named_params<Copier, vertex_copy_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template <typename Orig2CopyMap>
+ bgl_named_params<Orig2CopyMap, orig_to_copy_t, self>
+ orig_to_copy(const Orig2CopyMap& c) const {
+ typedef bgl_named_params<Orig2CopyMap, orig_to_copy_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template <typename IsoMap>
+ bgl_named_params<IsoMap, vertex_isomorphism_t, self>
+ isomorphism_map(const IsoMap& c) const {
+ typedef bgl_named_params<IsoMap, vertex_isomorphism_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template <typename VertexInvar>
+ bgl_named_params<VertexInvar, vertex_invariant_t, self>
+ vertex_invariant(const VertexInvar& c) const {
+ typedef bgl_named_params<VertexInvar, vertex_invariant_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template <typename VertexInvar>
+ bgl_named_params<VertexInvar, vertex_invariant1_t, self>
+ vertex_invariant1(const VertexInvar& c) const {
+ typedef bgl_named_params<VertexInvar, vertex_invariant1_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template <typename VertexInvar>
+ bgl_named_params<VertexInvar, vertex_invariant2_t, self>
+ vertex_invariant2(const VertexInvar& c) const {
+ typedef bgl_named_params<VertexInvar, vertex_invariant2_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template <typename VertexMaxInvar>
+ bgl_named_params<VertexMaxInvar, vertex_max_invariant_t, self>
+ vertex_max_invariant(const VertexMaxInvar& c) const {
+ typedef bgl_named_params<VertexMaxInvar, vertex_max_invariant_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template <typename VertexDisplacement>
+ bgl_named_params<VertexDisplacement, vertex_displacement_t, self>
+ displacement_map(const VertexDisplacement& c) const {
+ typedef bgl_named_params<VertexDisplacement, vertex_displacement_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template <typename AttractiveForce>
+ bgl_named_params<AttractiveForce, attractive_force_t, self>
+ attractive_force(const AttractiveForce& c) {
+ typedef bgl_named_params<AttractiveForce, attractive_force_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template <typename RepulsiveForce>
+ bgl_named_params<RepulsiveForce, repulsive_force_t, self>
+ repulsive_force(const RepulsiveForce& c) {
+ typedef bgl_named_params<RepulsiveForce, repulsive_force_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template <typename ForcePairs>
+ bgl_named_params<ForcePairs, force_pairs_t, self>
+ force_pairs(const ForcePairs& c) {
+ typedef bgl_named_params<ForcePairs, force_pairs_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template <typename Cooling>
+ bgl_named_params<Cooling, cooling_t, self>
+ cooling(const Cooling& c) {
+ typedef bgl_named_params<Cooling, cooling_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template <typename TP>
+ bgl_named_params<TP, iterations_t, self>
+ iterations(const TP& c) {
+ typedef bgl_named_params<TP, iterations_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template<typename TP>
+ bgl_named_params<std::pair<TP, TP>, diameter_range_t, self>
+ diameter_range(const std::pair<TP, TP>& c) {
+ typedef bgl_named_params<std::pair<TP, TP>, diameter_range_t, self> Params;
+ return Params(c, *this);
+ }
+
+ template<typename TP>
+ bgl_named_params<std::pair<TP, TP>, learning_constant_range_t, self>
+ learning_constant_range(const std::pair<TP, TP>& c) {
+ typedef bgl_named_params<std::pair<TP, TP>, learning_constant_range_t, self>
+ Params;
+ return Params(c, *this);
+ }
+ };
+
+ template <typename WeightMap>
+ bgl_named_params<WeightMap, edge_weight_t>
+ weight_map(WeightMap pmap) {
+ typedef bgl_named_params<WeightMap, edge_weight_t> Params;
+ return Params(pmap);
+ }
+
+ template <typename WeightMap>
+ bgl_named_params<WeightMap, edge_weight2_t>
+ weight_map2(WeightMap pmap) {
+ typedef bgl_named_params<WeightMap, edge_weight2_t> Params;
+ return Params(pmap);
+ }
+
+ template <typename DistanceMap>
+ bgl_named_params<DistanceMap, vertex_distance_t>
+ distance_map(DistanceMap pmap) {
+ typedef bgl_named_params<DistanceMap, vertex_distance_t> Params;
+ return Params(pmap);
+ }
+
+ template <typename PredecessorMap>
+ bgl_named_params<PredecessorMap, vertex_predecessor_t>
+ predecessor_map(PredecessorMap pmap) {
+ typedef bgl_named_params<PredecessorMap, vertex_predecessor_t> Params;
+ return Params(pmap);
+ }
+
+ template <typename RankMap>
+ bgl_named_params<RankMap, vertex_rank_t>
+ rank_map(RankMap pmap) {
+ typedef bgl_named_params<RankMap, vertex_rank_t> Params;
+ return Params(pmap);
+ }
+
+ template <typename RootMap>
+ bgl_named_params<RootMap, vertex_root_t>
+ root_map(RootMap pmap) {
+ typedef bgl_named_params<RootMap, vertex_root_t> Params;
+ return Params(pmap);
+ }
+
+ template <typename Vertex>
+ bgl_named_params<Vertex, root_vertex_t>
+ root_vertex(const Vertex& r) {
+ typedef bgl_named_params<Vertex, root_vertex_t> Params;
+ return Params(r);
+ }
+
+ template <typename EdgeCentralityMap>
+ bgl_named_params<EdgeCentralityMap, edge_centrality_t>
+ edge_centrality_map(const EdgeCentralityMap& r) {
+ typedef bgl_named_params<EdgeCentralityMap, edge_centrality_t> Params;
+ return Params(r);
+ }
+
+ template <typename CentralityMap>
+ bgl_named_params<CentralityMap, vertex_centrality_t>
+ centrality_map(const CentralityMap& r) {
+ typedef bgl_named_params<CentralityMap, vertex_centrality_t> Params;
+ return Params(r);
+ }
+
+ template <typename ColorMap>
+ bgl_named_params<ColorMap, vertex_color_t>
+ color_map(ColorMap pmap) {
+ typedef bgl_named_params<ColorMap, vertex_color_t> Params;
+ return Params(pmap);
+ }
+
+ template <typename CapacityMap>
+ bgl_named_params<CapacityMap, edge_capacity_t>
+ capacity_map(CapacityMap pmap) {
+ typedef bgl_named_params<CapacityMap, edge_capacity_t> Params;
+ return Params(pmap);
+ }
+
+ template <typename Residual_CapacityMap>
+ bgl_named_params<Residual_CapacityMap, edge_residual_capacity_t>
+ residual_capacity_map(Residual_CapacityMap pmap) {
+ typedef bgl_named_params<Residual_CapacityMap, edge_residual_capacity_t>
+ Params;
+ return Params(pmap);
+ }
+
+ template <typename ReverseMap>
+ bgl_named_params<ReverseMap, edge_reverse_t>
+ reverse_edge_map(ReverseMap pmap) {
+ typedef bgl_named_params<ReverseMap, edge_reverse_t>
+ Params;
+ return Params(pmap);
+ }
+
+ template <typename DiscoverTimeMap>
+ bgl_named_params<DiscoverTimeMap, vertex_discover_time_t>
+ discover_time_map(DiscoverTimeMap pmap) {
+ typedef bgl_named_params<DiscoverTimeMap, vertex_discover_time_t> Params;
+ return Params(pmap);
+ }
+
+ template <typename LowPointMap>
+ bgl_named_params<LowPointMap, vertex_lowpoint_t>
+ lowpoint_map(LowPointMap pmap) {
+ typedef bgl_named_params<LowPointMap, vertex_lowpoint_t> Params;
+ return Params(pmap);
+ }
+
+ template <typename IndexMap>
+ bgl_named_params<IndexMap, vertex_index_t>
+ vertex_index_map(IndexMap pmap) {
+ typedef bgl_named_params<IndexMap, vertex_index_t> Params;
+ return Params(pmap);
+ }
+
+ template <typename IndexMap>
+ bgl_named_params<IndexMap, vertex_index1_t>
+ vertex_index1_map(const IndexMap& pmap) {
+ typedef bgl_named_params<IndexMap, vertex_index1_t> Params;
+ return Params(pmap);
+ }
+
+ template <typename IndexMap>
+ bgl_named_params<IndexMap, vertex_index2_t>
+ vertex_index2_map(const IndexMap& pmap) {
+ typedef bgl_named_params<IndexMap, vertex_index2_t> Params;
+ return Params(pmap);
+ }
+
+ template <typename Visitor>
+ bgl_named_params<Visitor, graph_visitor_t>
+ visitor(const Visitor& vis) {
+ typedef bgl_named_params<Visitor, graph_visitor_t> Params;
+ return Params(vis);
+ }
+
+ template <typename Compare>
+ bgl_named_params<Compare, distance_compare_t>
+ distance_compare(Compare cmp) {
+ typedef bgl_named_params<Compare, distance_compare_t> Params;
+ return Params(cmp);
+ }
+
+ template <typename Combine>
+ bgl_named_params<Combine, distance_combine_t>
+ distance_combine(Combine cmb) {
+ typedef bgl_named_params<Combine, distance_combine_t> Params;
+ return Params(cmb);
+ }
+
+ template <typename Init>
+ bgl_named_params<Init, distance_inf_t>
+ distance_inf(Init init) {
+ typedef bgl_named_params<Init, distance_inf_t> Params;
+ return Params(init);
+ }
+
+ template <typename Init>
+ bgl_named_params<Init, distance_zero_t>
+ distance_zero(Init init) {
+ typedef bgl_named_params<Init, distance_zero_t> Params;
+ return Params(init);
+ }
+
+ template <typename Buffer>
+ bgl_named_params<detail::wrap_ref<Buffer>, buffer_param_t>
+ buffer(Buffer& b) {
+ typedef bgl_named_params<detail::wrap_ref<Buffer>, buffer_param_t> Params;
+ return Params(detail::wrap_ref<Buffer>(b));
+ }
+
+ template <typename Copier>
+ bgl_named_params<Copier, edge_copy_t>
+ edge_copy(const Copier& c) {
+ typedef bgl_named_params<Copier, edge_copy_t> Params;
+ return Params(c);
+ }
+
+ template <typename Copier>
+ bgl_named_params<Copier, vertex_copy_t>
+ vertex_copy(const Copier& c) {
+ typedef bgl_named_params<Copier, vertex_copy_t> Params;
+ return Params(c);
+ }
+
+ template <typename Orig2CopyMap>
+ bgl_named_params<Orig2CopyMap, orig_to_copy_t>
+ orig_to_copy(const Orig2CopyMap& c) {
+ typedef bgl_named_params<Orig2CopyMap, orig_to_copy_t> Params;
+ return Params(c);
+ }
+
+ template <typename IsoMap>
+ bgl_named_params<IsoMap, vertex_isomorphism_t>
+ isomorphism_map(const IsoMap& c) {
+ typedef bgl_named_params<IsoMap, vertex_isomorphism_t> Params;
+ return Params(c);
+ }
+
+ template <typename VertexInvar>
+ bgl_named_params<VertexInvar, vertex_invariant_t>
+ vertex_invariant(const VertexInvar& c) {
+ typedef bgl_named_params<VertexInvar, vertex_invariant_t> Params;
+ return Params(c);
+ }
+
+ template <typename VertexInvar>
+ bgl_named_params<VertexInvar, vertex_invariant1_t>
+ vertex_invariant1(const VertexInvar& c) {
+ typedef bgl_named_params<VertexInvar, vertex_invariant1_t> Params;
+ return Params(c);
+ }
+
+ template <typename VertexInvar>
+ bgl_named_params<VertexInvar, vertex_invariant2_t>
+ vertex_invariant2(const VertexInvar& c) {
+ typedef bgl_named_params<VertexInvar, vertex_invariant2_t> Params;
+ return Params(c);
+ }
+
+ template <typename VertexMaxInvar>
+ bgl_named_params<VertexMaxInvar, vertex_max_invariant_t>
+ vertex_max_invariant(const VertexMaxInvar& c) {
+ typedef bgl_named_params<VertexMaxInvar, vertex_max_invariant_t> Params;
+ return Params(c);
+ }
+
+ template <typename VertexDisplacement>
+ bgl_named_params<VertexDisplacement, vertex_displacement_t>
+ displacement_map(const VertexDisplacement& c) {
+ typedef bgl_named_params<VertexDisplacement, vertex_displacement_t> Params;
+ return Params(c);
+ }
+
+ template <typename AttractiveForce>
+ bgl_named_params<AttractiveForce, attractive_force_t>
+ attractive_force(const AttractiveForce& c) {
+ typedef bgl_named_params<AttractiveForce, attractive_force_t> Params;
+ return Params(c);
+ }
+
+ template <typename RepulsiveForce>
+ bgl_named_params<RepulsiveForce, repulsive_force_t>
+ repulsive_force(const RepulsiveForce& c) {
+ typedef bgl_named_params<RepulsiveForce, repulsive_force_t> Params;
+ return Params(c);
+ }
+
+ template <typename ForcePairs>
+ bgl_named_params<ForcePairs, force_pairs_t>
+ force_pairs(const ForcePairs& c) {
+ typedef bgl_named_params<ForcePairs, force_pairs_t> Params;
+ return Params(c);
+ }
+
+ template <typename Cooling>
+ bgl_named_params<Cooling, cooling_t>
+ cooling(const Cooling& c) {
+ typedef bgl_named_params<Cooling, cooling_t> Params;
+ return Params(c);
+ }
+
+ template <typename T>
+ bgl_named_params<T, iterations_t>
+ iterations(const T& c) {
+ typedef bgl_named_params<T, iterations_t> Params;
+ return Params(c);
+ }
+
+ template<typename T>
+ bgl_named_params<std::pair<T, T>, diameter_range_t>
+ diameter_range(const std::pair<T, T>& c) {
+ typedef bgl_named_params<std::pair<T, T>, diameter_range_t> Params;
+ return Params(c);
+ }
+
+ template<typename T>
+ bgl_named_params<std::pair<T, T>, learning_constant_range_t>
+ learning_constant_range(const std::pair<T, T>& c) {
+ typedef bgl_named_params<std::pair<T, T>, learning_constant_range_t>
+ Params;
+ return Params(c);
+ }
+
+ //===========================================================================
+ // Functions for extracting parameters from bgl_named_params
+
+ template <class Tag1, class Tag2, class T1, class Base>
+ inline
+ typename property_value< bgl_named_params<T1,Tag1,Base>, Tag2>::type
+ get_param(const bgl_named_params<T1,Tag1,Base>& p, Tag2 tag2)
+ {
+ enum { match = detail::same_property<Tag1,Tag2>::value };
+ typedef typename
+ property_value< bgl_named_params<T1,Tag1,Base>, Tag2>::type T2;
+ T2* t2 = 0;
+ typedef detail::property_value_dispatch<match> Dispatcher;
+ return Dispatcher::const_get_value(p, t2, tag2);
+ }
+
+
+ namespace detail {
+ // MSVC++ workaround
+ template <class Param>
+ struct choose_param_helper {
+ template <class Default> struct result { typedef Param type; };
+ template <typename Default>
+ static const Param& apply(const Param& p, const Default&) { return p; }
+ };
+ template <>
+ struct choose_param_helper<error_property_not_found> {
+ template <class Default> struct result { typedef Default type; };
+ template <typename Default>
+ static const Default& apply(const error_property_not_found&, const Default& d)
+ { return d; }
+ };
+ } // namespace detail
+
+ template <class P, class Default>
+ const typename detail::choose_param_helper<P>::template result<Default>::type&
+ choose_param(const P& param, const Default& d) {
+ return detail::choose_param_helper<P>::apply(param, d);
+ }
+
+ template <typename T>
+ inline bool is_default_param(const T&) { return false; }
+
+ inline bool is_default_param(const detail::error_property_not_found&)
+ { return true; }
+
+ namespace detail {
+
+ struct choose_parameter {
+ template <class P, class Graph, class Tag>
+ struct bind_ {
+ typedef const P& const_result_type;
+ typedef const P& result_type;
+ typedef P type;
+ };
+
+ template <class P, class Graph, class Tag>
+ static typename bind_<P, Graph, Tag>::const_result_type
+ const_apply(const P& p, const Graph&, Tag&)
+ { return p; }
+
+ template <class P, class Graph, class Tag>
+ static typename bind_<P, Graph, Tag>::result_type
+ apply(const P& p, Graph&, Tag&)
+ { return p; }
+ };
+
+ struct choose_default_param {
+ template <class P, class Graph, class Tag>
+ struct bind_ {
+ typedef typename property_map<Graph, Tag>::type
+ result_type;
+ typedef typename property_map<Graph, Tag>::const_type
+ const_result_type;
+ typedef typename property_map<Graph, Tag>::const_type
+ type;
+ };
+
+ template <class P, class Graph, class Tag>
+ static typename bind_<P, Graph, Tag>::const_result_type
+ const_apply(const P&, const Graph& g, Tag tag) {
+ return get(tag, g);
+ }
+ template <class P, class Graph, class Tag>
+ static typename bind_<P, Graph, Tag>::result_type
+ apply(const P&, Graph& g, Tag tag) {
+ return get(tag, g);
+ }
+ };
+
+ template <class Param>
+ struct choose_property_map {
+ typedef choose_parameter type;
+ };
+ template <>
+ struct choose_property_map<detail::error_property_not_found> {
+ typedef choose_default_param type;
+ };
+
+ template <class Param, class Graph, class Tag>
+ struct choose_pmap_helper {
+ typedef typename choose_property_map<Param>::type Selector;
+ typedef typename Selector:: template bind_<Param, Graph, Tag> Bind;
+ typedef Bind type;
+ typedef typename Bind::result_type result_type;
+ typedef typename Bind::const_result_type const_result_type;
+ typedef typename Bind::type result;
+ };
+
+ // used in the max-flow algorithms
+ template <class Graph, class P, class T, class R>
+ struct edge_capacity_value
+ {
+ typedef bgl_named_params<P, T, R> Params;
+ typedef typename property_value< Params, edge_capacity_t>::type Param;
+ typedef typename detail::choose_pmap_helper<Param, Graph,
+ edge_capacity_t>::result CapacityEdgeMap;
+ typedef typename property_traits<CapacityEdgeMap>::value_type type;
+ };
+
+ } // namespace detail
+
+
+ // Use this function instead of choose_param() when you want
+ // to avoid requiring get(tag, g) when it is not used.
+ template <typename Param, typename Graph, typename PropertyTag>
+ typename
+ detail::choose_pmap_helper<Param,Graph,PropertyTag>::const_result_type
+ choose_const_pmap(const Param& p, const Graph& g, PropertyTag tag)
+ {
+ typedef typename
+ detail::choose_pmap_helper<Param,Graph,PropertyTag>::Selector Choice;
+ return Choice::const_apply(p, g, tag);
+ }
+
+ template <typename Param, typename Graph, typename PropertyTag>
+ typename detail::choose_pmap_helper<Param,Graph,PropertyTag>::result_type
+ choose_pmap(const Param& p, Graph& g, PropertyTag tag)
+ {
+ typedef typename
+ detail::choose_pmap_helper<Param,Graph,PropertyTag>::Selector Choice;
+ return Choice::apply(p, g, tag);
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/neighbor_bfs.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/neighbor_bfs.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,323 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
+#define BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
+
+/*
+ Neighbor Breadth First Search
+ Like BFS, but traverses in-edges as well as out-edges.
+ (for directed graphs only. use normal BFS for undirected graphs)
+*/
+#include <boost/config.hpp>
+#include <vector>
+#include <boost/pending/queue.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/named_function_params.hpp>
+
+namespace boost {
+
+ template <class Visitor, class Graph>
+ struct NeighborBFSVisitorConcept {
+ void constraints() {
+ function_requires< CopyConstructibleConcept<Visitor> >();
+ vis.initialize_vertex(u, g);
+ vis.discover_vertex(u, g);
+ vis.examine_vertex(u, g);
+ vis.examine_out_edge(e, g);
+ vis.examine_in_edge(e, g);
+ vis.tree_out_edge(e, g);
+ vis.tree_in_edge(e, g);
+ vis.non_tree_out_edge(e, g);
+ vis.non_tree_in_edge(e, g);
+ vis.gray_target(e, g);
+ vis.black_target(e, g);
+ vis.gray_source(e, g);
+ vis.black_source(e, g);
+ vis.finish_vertex(u, g);
+ }
+ Visitor vis;
+ Graph g;
+ typename graph_traits<Graph>::vertex_descriptor u;
+ typename graph_traits<Graph>::edge_descriptor e;
+ };
+
+ template <class Visitors = null_visitor>
+ class neighbor_bfs_visitor {
+ public:
+ neighbor_bfs_visitor(Visitors vis = Visitors()) : m_vis(vis) { }
+
+ template <class Vertex, class Graph>
+ void initialize_vertex(Vertex u, Graph& g) {
+ invoke_visitors(m_vis, u, g, on_initialize_vertex());
+ }
+ template <class Vertex, class Graph>
+ void discover_vertex(Vertex u, Graph& g) {
+ invoke_visitors(m_vis, u, g, on_discover_vertex());
+ }
+ template <class Vertex, class Graph>
+ void examine_vertex(Vertex u, Graph& g) {
+ invoke_visitors(m_vis, u, g, on_examine_vertex());
+ }
+ template <class Edge, class Graph>
+ void examine_out_edge(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, on_examine_edge());
+ }
+ template <class Edge, class Graph>
+ void tree_out_edge(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, on_tree_edge());
+ }
+ template <class Edge, class Graph>
+ void non_tree_out_edge(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, on_non_tree_edge());
+ }
+ template <class Edge, class Graph>
+ void gray_target(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, on_gray_target());
+ }
+ template <class Edge, class Graph>
+ void black_target(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, on_black_target());
+ }
+ template <class Edge, class Graph>
+ void examine_in_edge(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, on_examine_edge());
+ }
+ template <class Edge, class Graph>
+ void tree_in_edge(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, on_tree_edge());
+ }
+ template <class Edge, class Graph>
+ void non_tree_in_edge(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, on_non_tree_edge());
+ }
+ template <class Edge, class Graph>
+ void gray_source(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, on_gray_target());
+ }
+ template <class Edge, class Graph>
+ void black_source(Edge e, Graph& g) {
+ invoke_visitors(m_vis, e, g, on_black_target());
+ }
+ template <class Vertex, class Graph>
+ void finish_vertex(Vertex u, Graph& g) {
+ invoke_visitors(m_vis, u, g, on_finish_vertex());
+ }
+ protected:
+ Visitors m_vis;
+ };
+
+ template <class Visitors>
+ neighbor_bfs_visitor<Visitors>
+ make_neighbor_bfs_visitor(Visitors vis) {
+ return neighbor_bfs_visitor<Visitors>(vis);
+ }
+
+ namespace detail {
+
+ template <class BidirectionalGraph, class Buffer, class BFSVisitor,
+ class ColorMap>
+ void neighbor_bfs_impl
+ (const BidirectionalGraph& g,
+ typename graph_traits<BidirectionalGraph>::vertex_descriptor s,
+ Buffer& Q, BFSVisitor vis, ColorMap color)
+
+ {
+ function_requires< BidirectionalGraphConcept<BidirectionalGraph> >();
+ typedef graph_traits<BidirectionalGraph> GTraits;
+ typedef typename GTraits::vertex_descriptor Vertex;
+ typedef typename GTraits::edge_descriptor Edge;
+ function_requires<
+ NeighborBFSVisitorConcept<BFSVisitor, BidirectionalGraph> >();
+ function_requires< ReadWritePropertyMapConcept<ColorMap, Vertex> >();
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+
+ put(color, s, Color::gray());
+ vis.discover_vertex(s, g);
+ Q.push(s);
+ while (! Q.empty()) {
+ Vertex u = Q.top();
+ Q.pop(); // pop before push to avoid problem if Q is priority_queue.
+ vis.examine_vertex(u, g);
+
+ typename GTraits::out_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
+ Edge e = *ei;
+ vis.examine_out_edge(e, g);
+ Vertex v = target(e, g);
+ ColorValue v_color = get(color, v);
+ if (v_color == Color::white()) {
+ vis.tree_out_edge(e, g);
+ put(color, v, Color::gray());
+ vis.discover_vertex(v, g);
+ Q.push(v);
+ } else {
+ vis.non_tree_out_edge(e, g);
+ if (v_color == Color::gray())
+ vis.gray_target(e, g);
+ else
+ vis.black_target(e, g);
+ }
+ } // for out-edges
+
+ typename GTraits::in_edge_iterator in_ei, in_ei_end;
+ for (tie(in_ei, in_ei_end) = in_edges(u, g);
+ in_ei != in_ei_end; ++in_ei) {
+ Edge e = *in_ei;
+ vis.examine_in_edge(e, g);
+ Vertex v = source(e, g);
+ ColorValue v_color = get(color, v);
+ if (v_color == Color::white()) {
+ vis.tree_in_edge(e, g);
+ put(color, v, Color::gray());
+ vis.discover_vertex(v, g);
+ Q.push(v);
+ } else {
+ vis.non_tree_in_edge(e, g);
+ if (v_color == Color::gray())
+ vis.gray_source(e, g);
+ else
+ vis.black_source(e, g);
+ }
+ } // for in-edges
+
+ put(color, u, Color::black());
+ vis.finish_vertex(u, g);
+ } // while
+ }
+
+
+ template <class VertexListGraph, class ColorMap, class BFSVisitor,
+ class P, class T, class R>
+ void neighbor_bfs_helper
+ (VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ ColorMap color,
+ BFSVisitor vis,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef graph_traits<VertexListGraph> Traits;
+ // Buffer default
+ typedef typename Traits::vertex_descriptor Vertex;
+ typedef boost::queue<Vertex> queue_t;
+ queue_t Q;
+ detail::wrap_ref<queue_t> Qref(Q);
+ // Initialization
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+ typename boost::graph_traits<VertexListGraph>::vertex_iterator i, i_end;
+ for (tie(i, i_end) = vertices(g); i != i_end; ++i) {
+ put(color, *i, Color::white());
+ vis.initialize_vertex(*i, g);
+ }
+ neighbor_bfs_impl
+ (g, s,
+ choose_param(get_param(params, buffer_param_t()), Qref).ref,
+ vis, color);
+ }
+
+ //-------------------------------------------------------------------------
+ // Choose between default color and color parameters. Using
+ // function dispatching so that we don't require vertex index if
+ // the color default is not being used.
+
+ template <class ColorMap>
+ struct neighbor_bfs_dispatch {
+ template <class VertexListGraph, class P, class T, class R>
+ static void apply
+ (VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ const bgl_named_params<P, T, R>& params,
+ ColorMap color)
+ {
+ neighbor_bfs_helper
+ (g, s, color,
+ choose_param(get_param(params, graph_visitor),
+ make_neighbor_bfs_visitor(null_visitor())),
+ params);
+ }
+ };
+
+ template <>
+ struct neighbor_bfs_dispatch<detail::error_property_not_found> {
+ template <class VertexListGraph, class P, class T, class R>
+ static void apply
+ (VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ const bgl_named_params<P, T, R>& params,
+ detail::error_property_not_found)
+ {
+ std::vector<default_color_type> color_vec(num_vertices(g));
+ null_visitor null_vis;
+
+ neighbor_bfs_helper
+ (g, s,
+ make_iterator_property_map
+ (color_vec.begin(),
+ choose_const_pmap(get_param(params, vertex_index),
+ g, vertex_index), color_vec[0]),
+ choose_param(get_param(params, graph_visitor),
+ make_neighbor_bfs_visitor(null_vis)),
+ params);
+ }
+ };
+
+ } // namespace detail
+
+
+ // Named Parameter Variant
+ template <class VertexListGraph, class P, class T, class R>
+ void neighbor_breadth_first_search
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ const bgl_named_params<P, T, R>& params)
+ {
+ // The graph is passed by *const* reference so that graph adaptors
+ // (temporaries) can be passed into this function. However, the
+ // graph is not really const since we may write to property maps
+ // of the graph.
+ VertexListGraph& ng = const_cast<VertexListGraph&>(g);
+ typedef typename property_value< bgl_named_params<P,T,R>,
+ vertex_color_t>::type C;
+ detail::neighbor_bfs_dispatch<C>::apply(ng, s, params,
+ get_param(params, vertex_color));
+ }
+
+
+ // This version does not initialize colors, user has to.
+
+ template <class IncidenceGraph, class P, class T, class R>
+ void neighbor_breadth_first_visit
+ (IncidenceGraph& g,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor s,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef graph_traits<IncidenceGraph> Traits;
+ // Buffer default
+ typedef boost::queue<typename Traits::vertex_descriptor> queue_t;
+ queue_t Q;
+ detail::wrap_ref<queue_t> Qref(Q);
+
+ detail::neighbor_bfs_impl
+ (g, s,
+ choose_param(get_param(params, buffer_param_t()), Qref).ref,
+ choose_param(get_param(params, graph_visitor),
+ make_neighbor_bfs_visitor(null_visitor())),
+ choose_pmap(get_param(params, vertex_color), g, vertex_color)
+ );
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
+
Added: branches/CMake/release/libs/graph/include/boost/graph/page_rank.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/page_rank.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,153 @@
+// Copyright 2004-5 The Trustees of Indiana University.
+// Copyright 2002 Brad King and Douglas Gregor
+
+// 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)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+
+#ifndef BOOST_GRAPH_PAGE_RANK_HPP
+#define BOOST_GRAPH_PAGE_RANK_HPP
+
+#include <boost/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/iteration_macros.hpp>
+#include <vector>
+
+namespace boost { namespace graph {
+
+struct n_iterations
+{
+ explicit n_iterations(std::size_t n) : n(n) { }
+
+ template<typename RankMap, typename Graph>
+ bool
+ operator()(const RankMap&, const Graph&)
+ {
+ return n-- == 0;
+ }
+
+ private:
+ std::size_t n;
+};
+
+namespace detail {
+ template<typename Graph, typename RankMap, typename RankMap2>
+ void page_rank_step(const Graph& g, RankMap from_rank, RankMap2 to_rank,
+ typename property_traits<RankMap>::value_type damping,
+ incidence_graph_tag)
+ {
+ typedef typename property_traits<RankMap>::value_type rank_type;
+
+ // Set new rank maps
+ BGL_FORALL_VERTICES_T(v, g, Graph) put(to_rank, v, rank_type(1 - damping));
+
+ BGL_FORALL_VERTICES_T(u, g, Graph) {
+ rank_type u_rank_out = damping * get(from_rank, u) / out_degree(u, g);
+ BGL_FORALL_ADJ_T(u, v, g, Graph)
+ put(to_rank, v, get(to_rank, v) + u_rank_out);
+ }
+ }
+
+ template<typename Graph, typename RankMap, typename RankMap2>
+ void page_rank_step(const Graph& g, RankMap from_rank, RankMap2 to_rank,
+ typename property_traits<RankMap>::value_type damping,
+ bidirectional_graph_tag)
+ {
+ typedef typename property_traits<RankMap>::value_type damping_type;
+ BGL_FORALL_VERTICES_T(v, g, Graph) {
+ typename property_traits<RankMap>::value_type rank(0);
+ BGL_FORALL_INEDGES_T(v, e, g, Graph)
+ rank += get(from_rank, source(e, g)) / out_degree(source(e, g), g);
+ put(to_rank, v, (damping_type(1) - damping) + damping * rank);
+ }
+ }
+} // end namespace detail
+
+template<typename Graph, typename RankMap, typename Done, typename RankMap2>
+void
+page_rank(const Graph& g, RankMap rank_map, Done done,
+ typename property_traits<RankMap>::value_type damping,
+ typename graph_traits<Graph>::vertices_size_type n,
+ RankMap2 rank_map2)
+{
+ typedef typename property_traits<RankMap>::value_type rank_type;
+
+ rank_type initial_rank = rank_type(rank_type(1) / n);
+ BGL_FORALL_VERTICES_T(v, g, Graph) put(rank_map, v, initial_rank);
+
+ bool to_map_2 = true;
+ while ((to_map_2 && !done(rank_map, g)) ||
+ (!to_map_2 && !done(rank_map2, g))) {
+ typedef typename graph_traits<Graph>::traversal_category category;
+
+ if (to_map_2) {
+ detail::page_rank_step(g, rank_map, rank_map2, damping, category());
+ } else {
+ detail::page_rank_step(g, rank_map2, rank_map, damping, category());
+ }
+ to_map_2 = !to_map_2;
+ }
+
+ if (!to_map_2) {
+ BGL_FORALL_VERTICES_T(v, g, Graph) put(rank_map, v, get(rank_map2, v));
+ }
+}
+
+template<typename Graph, typename RankMap, typename Done>
+void
+page_rank(const Graph& g, RankMap rank_map, Done done,
+ typename property_traits<RankMap>::value_type damping,
+ typename graph_traits<Graph>::vertices_size_type n)
+{
+ typedef typename property_traits<RankMap>::value_type rank_type;
+
+ std::vector<rank_type> ranks2(num_vertices(g));
+ page_rank(g, rank_map, done, damping, n,
+ make_iterator_property_map(ranks2.begin(), get(vertex_index, g)));
+}
+
+template<typename Graph, typename RankMap, typename Done>
+inline void
+page_rank(const Graph& g, RankMap rank_map, Done done,
+ typename property_traits<RankMap>::value_type damping = 0.85)
+{
+ page_rank(g, rank_map, done, damping, num_vertices(g));
+}
+
+template<typename Graph, typename RankMap>
+inline void
+page_rank(const Graph& g, RankMap rank_map)
+{
+ page_rank(g, rank_map, n_iterations(20));
+}
+
+// TBD: this could be _much_ more efficient, using a queue to store
+// the vertices that should be reprocessed and keeping track of which
+// vertices are in the queue with a property map. Baah, this only
+// applies when we have a bidirectional graph.
+template<typename MutableGraph>
+void
+remove_dangling_links(MutableGraph& g)
+{
+ typename graph_traits<MutableGraph>::vertices_size_type old_n;
+ do {
+ old_n = num_vertices(g);
+
+ typename graph_traits<MutableGraph>::vertex_iterator vi, vi_end;
+ for (tie(vi, vi_end) = vertices(g); vi != vi_end; /* in loop */) {
+ typename graph_traits<MutableGraph>::vertex_descriptor v = *vi++;
+ if (out_degree(v, g) == 0) {
+ clear_vertex(v, g);
+ remove_vertex(v, g);
+ }
+ }
+ } while (num_vertices(g) < old_n);
+}
+
+} } // end namespace boost::graph
+
+#endif // BOOST_GRAPH_PAGE_RANK_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/planar_canonical_ordering.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/planar_canonical_ordering.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,211 @@
+//=======================================================================
+// Copyright (c) Aaron Windsor 2007
+//
+// 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)
+//=======================================================================
+
+#ifndef __PLANAR_CANONICAL_ORDERING_HPP__
+#define __PLANAR_CANONICAL_ORDERING_HPP__
+
+#include <vector>
+#include <list>
+#include <boost/config.hpp>
+#include <boost/utility.hpp> //for next and prior
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map.hpp>
+
+
+namespace boost
+{
+
+
+ template<typename Graph,
+ typename PlanarEmbedding,
+ typename OutputIterator,
+ typename VertexIndexMap>
+ void planar_canonical_ordering(const Graph& g,
+ PlanarEmbedding embedding,
+ OutputIterator ordering,
+ VertexIndexMap vm)
+ {
+
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits<Graph>::adjacency_iterator
+ adjacency_iterator_t;
+ typedef typename std::pair<vertex_t, vertex_t> vertex_pair_t;
+ typedef typename property_traits<PlanarEmbedding>::value_type
+ embedding_value_t;
+ typedef typename embedding_value_t::const_iterator embedding_iterator_t;
+ typedef iterator_property_map
+ <typename std::vector<vertex_t>::iterator, VertexIndexMap>
+ vertex_to_vertex_map_t;
+ typedef iterator_property_map
+ <typename std::vector<std::size_t>::iterator, VertexIndexMap>
+ vertex_to_size_t_map_t;
+
+ enum {PROCESSED,
+ UNPROCESSED,
+ ONE_NEIGHBOR_PROCESSED,
+ READY_TO_BE_PROCESSED};
+
+ std::vector<vertex_t> processed_neighbor_vector(num_vertices(g));
+ vertex_to_vertex_map_t processed_neighbor
+ (processed_neighbor_vector.begin(), vm);
+
+ std::vector<std::size_t> status_vector(num_vertices(g), UNPROCESSED);
+ vertex_to_size_t_map_t status(status_vector.begin(), vm);
+
+ std::list<vertex_t> ready_to_be_processed;
+
+ vertex_t first_vertex = *vertices(g).first;
+ vertex_t second_vertex;
+ adjacency_iterator_t ai, ai_end;
+ for(tie(ai,ai_end) = adjacent_vertices(first_vertex,g); ai != ai_end; ++ai)
+ {
+ if (*ai == first_vertex)
+ continue;
+ second_vertex = *ai;
+ break;
+ }
+
+ ready_to_be_processed.push_back(first_vertex);
+ status[first_vertex] = READY_TO_BE_PROCESSED;
+ ready_to_be_processed.push_back(second_vertex);
+ status[second_vertex] = READY_TO_BE_PROCESSED;
+
+ while(!ready_to_be_processed.empty())
+ {
+ vertex_t u = ready_to_be_processed.front();
+ ready_to_be_processed.pop_front();
+
+ if (status[u] != READY_TO_BE_PROCESSED && u != second_vertex)
+ continue;
+
+ embedding_iterator_t ei, ei_start, ei_end;
+ embedding_iterator_t next_edge_itr, prior_edge_itr;
+
+ ei_start = embedding[u].begin();
+ ei_end = embedding[u].end();
+ prior_edge_itr = prior(ei_end);
+ while(source(*prior_edge_itr, g) == target(*prior_edge_itr,g))
+ prior_edge_itr = prior(prior_edge_itr);
+
+ for(ei = ei_start; ei != ei_end; ++ei)
+ {
+
+ edge_t e(*ei); // e = (u,v)
+ next_edge_itr = next(ei) == ei_end ? ei_start : next(ei);
+ vertex_t v = source(e,g) == u ? target(e,g) : source(e,g);
+
+ vertex_t prior_vertex = source(*prior_edge_itr, g) == u ?
+ target(*prior_edge_itr, g) : source(*prior_edge_itr, g);
+ vertex_t next_vertex = source(*next_edge_itr, g) == u ?
+ target(*next_edge_itr, g) : source(*next_edge_itr, g);
+
+ // Need prior_vertex, u, v, and next_vertex to all be
+ // distinct. This is possible, since the input graph is
+ // triangulated. It'll be true all the time in a simple
+ // graph, but loops and parallel edges cause some complications.
+ if (prior_vertex == v || prior_vertex == u)
+ {
+ prior_edge_itr = ei;
+ continue;
+ }
+
+ //Skip any self-loops
+ if (u == v)
+ continue;
+
+ // Move next_edge_itr (and next_vertex) forwards
+ // past any loops or parallel edges
+ while (next_vertex == v || next_vertex == u)
+ {
+ next_edge_itr = next(next_edge_itr) == ei_end ?
+ ei_start : next(next_edge_itr);
+ next_vertex = source(*next_edge_itr, g) == u ?
+ target(*next_edge_itr, g) : source(*next_edge_itr, g);
+ }
+
+
+ if (status[v] == UNPROCESSED)
+ {
+ status[v] = ONE_NEIGHBOR_PROCESSED;
+ processed_neighbor[v] = u;
+ }
+ else if (status[v] == ONE_NEIGHBOR_PROCESSED)
+ {
+ vertex_t x = processed_neighbor[v];
+ //are edges (v,u) and (v,x) adjacent in the planar
+ //embedding? if so, set status[v] = 1. otherwise, set
+ //status[v] = 2.
+
+ if ((next_vertex == x &&
+ !(first_vertex == u && second_vertex == x)
+ )
+ ||
+ (prior_vertex == x &&
+ !(first_vertex == x && second_vertex == u)
+ )
+ )
+ {
+ status[v] = READY_TO_BE_PROCESSED;
+ }
+ else
+ {
+ status[v] = READY_TO_BE_PROCESSED + 1;
+ }
+ }
+ else if (status[v] > ONE_NEIGHBOR_PROCESSED)
+ {
+ //check the two edges before and after (v,u) in the planar
+ //embedding, and update status[v] accordingly
+
+ bool processed_before = false;
+ if (status[prior_vertex] == PROCESSED)
+ processed_before = true;
+
+ bool processed_after = false;
+ if (status[next_vertex] == PROCESSED)
+ processed_after = true;
+
+ if (!processed_before && !processed_after)
+ ++status[v];
+
+ else if (processed_before && processed_after)
+ --status[v];
+
+ }
+
+ if (status[v] == READY_TO_BE_PROCESSED)
+ ready_to_be_processed.push_back(v);
+
+ prior_edge_itr = ei;
+
+ }
+
+ status[u] = PROCESSED;
+ *ordering = u;
+ ++ordering;
+
+ }
+
+ }
+
+
+ template<typename Graph, typename PlanarEmbedding, typename OutputIterator>
+ void planar_canonical_ordering(const Graph& g,
+ PlanarEmbedding embedding,
+ OutputIterator ordering
+ )
+ {
+ planar_canonical_ordering(g, embedding, ordering, get(vertex_index,g));
+ }
+
+
+} //namespace boost
+
+#endif //__PLANAR_CANONICAL_ORDERING_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/planar_detail/add_edge_visitors.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/planar_detail/add_edge_visitors.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,59 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// 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)
+//=======================================================================
+#ifndef __ADD_EDGE_VISITORS_HPP__
+#define __ADD_EDGE_VISITORS_HPP__
+
+#include <boost/property_map.hpp>
+
+namespace boost
+{
+
+ struct default_add_edge_visitor
+ {
+
+ template <typename Graph, typename Vertex>
+ void visit_vertex_pair(Vertex u, Vertex v, Graph& g)
+ {
+ add_edge(u,v,g);
+ }
+
+ };
+
+ template<typename EdgeIndexMap>
+ struct edge_index_update_visitor
+ {
+
+ typedef typename
+ property_traits<EdgeIndexMap>::value_type edge_index_value_t;
+
+ edge_index_update_visitor(EdgeIndexMap em,
+ edge_index_value_t next_index_available
+ ) :
+ m_em(em),
+ m_next_index(next_index_available)
+ {}
+
+ template <typename Graph, typename Vertex>
+ void visit_vertex_pair(Vertex u, Vertex v, Graph& g)
+ {
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ std::pair<edge_t, bool> return_value = add_edge(u,v,g);
+ if (return_value.second)
+ put( m_em, return_value.first, m_next_index++);
+ }
+
+ private:
+
+ EdgeIndexMap m_em;
+ edge_index_value_t m_next_index;
+
+ };
+
+} // namespace boost
+
+#endif //__ADD_EDGE_VISITORS_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/planar_detail/boyer_myrvold_impl.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/planar_detail/boyer_myrvold_impl.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,2010 @@
+//=======================================================================
+// Copyright (c) Aaron Windsor 2007
+//
+// 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)
+//=======================================================================
+#ifndef __BOYER_MYRVOLD_IMPL_HPP__
+#define __BOYER_MYRVOLD_IMPL_HPP__
+
+#include <vector>
+#include <list>
+#include <boost/utility.hpp> //for boost::next
+#include <boost/config.hpp> //for std::min macros
+#include <boost/shared_ptr.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/graph/planar_detail/face_handles.hpp>
+#include <boost/graph/planar_detail/face_iterators.hpp>
+#include <boost/graph/planar_detail/bucket_sort.hpp>
+
+
+
+namespace boost
+{
+
+ template<typename LowPointMap, typename DFSParentMap,
+ typename DFSNumberMap, typename LeastAncestorMap,
+ typename DFSParentEdgeMap, typename SizeType>
+ struct planar_dfs_visitor : public dfs_visitor<>
+ {
+ planar_dfs_visitor(LowPointMap lpm, DFSParentMap dfs_p,
+ DFSNumberMap dfs_n, LeastAncestorMap lam,
+ DFSParentEdgeMap dfs_edge)
+ : low(lpm),
+ parent(dfs_p),
+ df_number(dfs_n),
+ least_ancestor(lam),
+ df_edge(dfs_edge),
+ count(0)
+ {}
+
+
+ template <typename Vertex, typename Graph>
+ void start_vertex(const Vertex& u, Graph&)
+ {
+ put(parent, u, u);
+ put(least_ancestor, u, count);
+ }
+
+
+ template <typename Vertex, typename Graph>
+ void discover_vertex(const Vertex& u, Graph&)
+ {
+ put(low, u, count);
+ put(df_number, u, count);
+ ++count;
+ }
+
+ template <typename Edge, typename Graph>
+ void tree_edge(const Edge& e, Graph& g)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ vertex_t s(source(e,g));
+ vertex_t t(target(e,g));
+
+ put(parent, t, s);
+ put(df_edge, t, e);
+ put(least_ancestor, t, get(df_number, s));
+ }
+
+ template <typename Edge, typename Graph>
+ void back_edge(const Edge& e, Graph& g)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
+
+ vertex_t s(source(e,g));
+ vertex_t t(target(e,g));
+ BOOST_USING_STD_MIN();
+
+ if ( t != get(parent, s) ) {
+ v_size_t s_low_df_number = get(low, s);
+ v_size_t t_df_number = get(df_number, t);
+ v_size_t s_least_ancestor_df_number = get(least_ancestor, s);
+
+ put(low, s,
+ min BOOST_PREVENT_MACRO_SUBSTITUTION(s_low_df_number,
+ t_df_number)
+ );
+
+ put(least_ancestor, s,
+ min BOOST_PREVENT_MACRO_SUBSTITUTION(s_least_ancestor_df_number,
+ t_df_number
+ )
+ );
+
+ }
+ }
+
+ template <typename Vertex, typename Graph>
+ void finish_vertex(const Vertex& u, Graph& g)
+ {
+ typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
+
+ Vertex u_parent = get(parent, u);
+ v_size_t u_parent_lowpoint = get(low, u_parent);
+ v_size_t u_lowpoint = get(low, u);
+ BOOST_USING_STD_MIN();
+
+ if (u_parent != u)
+ {
+ put(low, u_parent,
+ min BOOST_PREVENT_MACRO_SUBSTITUTION(u_lowpoint,
+ u_parent_lowpoint
+ )
+ );
+ }
+ }
+
+ LowPointMap low;
+ DFSParentMap parent;
+ DFSNumberMap df_number;
+ LeastAncestorMap least_ancestor;
+ DFSParentEdgeMap df_edge;
+ SizeType count;
+
+ };
+
+
+
+
+
+
+ template <typename Graph,
+ typename VertexIndexMap,
+ typename StoreOldHandlesPolicy = graph::detail::store_old_handles,
+ typename StoreEmbeddingPolicy = graph::detail::recursive_lazy_list
+ >
+ class boyer_myrvold_impl
+ {
+
+ typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits<Graph>::edge_iterator edge_iterator_t;
+ typedef typename graph_traits<Graph>::out_edge_iterator
+ out_edge_iterator_t;
+ typedef graph::detail::face_handle
+ <Graph, StoreOldHandlesPolicy, StoreEmbeddingPolicy> face_handle_t;
+ typedef std::vector<vertex_t> vertex_vector_t;
+ typedef std::vector<edge_t> edge_vector_t;
+ typedef std::list<vertex_t> vertex_list_t;
+ typedef std::list< face_handle_t > face_handle_list_t;
+ typedef boost::shared_ptr< face_handle_list_t > face_handle_list_ptr_t;
+ typedef boost::shared_ptr< vertex_list_t > vertex_list_ptr_t;
+ typedef boost::tuple<vertex_t, bool, bool> merge_stack_frame_t;
+ typedef std::vector<merge_stack_frame_t> merge_stack_t;
+
+ template <typename T>
+ struct map_vertex_to_
+ {
+ typedef iterator_property_map
+ <typename std::vector<T>::iterator, VertexIndexMap> type;
+ };
+
+ typedef typename map_vertex_to_<v_size_t>::type vertex_to_v_size_map_t;
+ typedef typename map_vertex_to_<vertex_t>::type vertex_to_vertex_map_t;
+ typedef typename map_vertex_to_<edge_t>::type vertex_to_edge_map_t;
+ typedef typename map_vertex_to_<vertex_list_ptr_t>::type
+ vertex_to_vertex_list_ptr_map_t;
+ typedef typename map_vertex_to_< edge_vector_t >::type
+ vertex_to_edge_vector_map_t;
+ typedef typename map_vertex_to_<bool>::type vertex_to_bool_map_t;
+ typedef typename map_vertex_to_<face_handle_t>::type
+ vertex_to_face_handle_map_t;
+ typedef typename map_vertex_to_<face_handle_list_ptr_t>::type
+ vertex_to_face_handle_list_ptr_map_t;
+ typedef typename map_vertex_to_<typename vertex_list_t::iterator>::type
+ vertex_to_separated_node_map_t;
+
+ template <typename BicompSideToTraverse = single_side,
+ typename VisitorType = lead_visitor,
+ typename Time = current_iteration>
+ struct face_vertex_iterator
+ {
+ typedef face_iterator<Graph,
+ vertex_to_face_handle_map_t,
+ vertex_t,
+ BicompSideToTraverse,
+ VisitorType,
+ Time>
+ type;
+ };
+
+ template <typename BicompSideToTraverse = single_side,
+ typename Time = current_iteration>
+ struct face_edge_iterator
+ {
+ typedef face_iterator<Graph,
+ vertex_to_face_handle_map_t,
+ edge_t,
+ BicompSideToTraverse,
+ lead_visitor,
+ Time>
+ type;
+ };
+
+
+
+ public:
+
+
+
+ boyer_myrvold_impl(const Graph& arg_g, VertexIndexMap arg_vm):
+ g(arg_g),
+ vm(arg_vm),
+
+ low_point_vector(num_vertices(g)),
+ dfs_parent_vector(num_vertices(g)),
+ dfs_number_vector(num_vertices(g)),
+ least_ancestor_vector(num_vertices(g)),
+ pertinent_roots_vector(num_vertices(g)),
+ backedge_flag_vector(num_vertices(g), num_vertices(g) + 1),
+ visited_vector(num_vertices(g), num_vertices(g) + 1),
+ face_handles_vector(num_vertices(g)),
+ dfs_child_handles_vector(num_vertices(g)),
+ separated_dfs_child_list_vector(num_vertices(g)),
+ separated_node_in_parent_list_vector(num_vertices(g)),
+ canonical_dfs_child_vector(num_vertices(g)),
+ flipped_vector(num_vertices(g), false),
+ backedges_vector(num_vertices(g)),
+ dfs_parent_edge_vector(num_vertices(g)),
+
+ vertices_by_dfs_num(num_vertices(g)),
+
+ low_point(low_point_vector.begin(), vm),
+ dfs_parent(dfs_parent_vector.begin(), vm),
+ dfs_number(dfs_number_vector.begin(), vm),
+ least_ancestor(least_ancestor_vector.begin(), vm),
+ pertinent_roots(pertinent_roots_vector.begin(), vm),
+ backedge_flag(backedge_flag_vector.begin(), vm),
+ visited(visited_vector.begin(), vm),
+ face_handles(face_handles_vector.begin(), vm),
+ dfs_child_handles(dfs_child_handles_vector.begin(), vm),
+ separated_dfs_child_list(separated_dfs_child_list_vector.begin(), vm),
+ separated_node_in_parent_list
+ (separated_node_in_parent_list_vector.begin(), vm),
+ canonical_dfs_child(canonical_dfs_child_vector.begin(), vm),
+ flipped(flipped_vector.begin(), vm),
+ backedges(backedges_vector.begin(), vm),
+ dfs_parent_edge(dfs_parent_edge_vector.begin(), vm)
+
+ {
+
+ planar_dfs_visitor
+ <vertex_to_v_size_map_t, vertex_to_vertex_map_t,
+ vertex_to_v_size_map_t, vertex_to_v_size_map_t,
+ vertex_to_edge_map_t, v_size_t> vis
+ (low_point, dfs_parent, dfs_number, least_ancestor, dfs_parent_edge);
+
+ // Perform a depth-first search to find each vertex's low point, least
+ // ancestor, and dfs tree information
+ depth_first_search(g, visitor(vis).vertex_index_map(vm));
+
+ // Sort vertices by their lowpoint - need this later in the constructor
+ vertex_vector_t vertices_by_lowpoint(num_vertices(g));
+ std::copy( vertices(g).first, vertices(g).second,
+ vertices_by_lowpoint.begin()
+ );
+ bucket_sort(vertices_by_lowpoint.begin(),
+ vertices_by_lowpoint.end(),
+ low_point,
+ num_vertices(g)
+ );
+
+ // Sort vertices by their dfs number - need this to iterate by reverse
+ // DFS number in the main loop.
+ std::copy( vertices(g).first, vertices(g).second,
+ vertices_by_dfs_num.begin()
+ );
+ bucket_sort(vertices_by_dfs_num.begin(),
+ vertices_by_dfs_num.end(),
+ dfs_number,
+ num_vertices(g)
+ );
+
+ // Initialize face handles. A face handle is an abstraction that serves
+ // two uses in our implementation - it allows us to efficiently move
+ // along the outer face of embedded bicomps in a partially embedded
+ // graph, and it provides storage for the planar embedding. Face
+ // handles are implemented by a sequence of edges and are associated
+ // with a particular vertex - the sequence of edges represents the
+ // current embedding of edges around that vertex, and the first and
+ // last edges in the sequence represent the pair of edges on the outer
+ // face that are adjacent to the associated vertex. This lets us embed
+ // edges in the graph by just pushing them on the front or back of the
+ // sequence of edges held by the face handles.
+ //
+ // Our algorithm starts with a DFS tree of edges (where every vertex is
+ // an articulation point and every edge is a singleton bicomp) and
+ // repeatedly merges bicomps by embedding additional edges. Note that
+ // any bicomp at any point in the algorithm can be associated with a
+ // unique edge connecting the vertex of that bicomp with the lowest DFS
+ // number (which we refer to as the "root" of the bicomp) with its DFS
+ // child in the bicomp: the existence of two such edges would contradict
+ // the properties of a DFS tree. We refer to the DFS child of the root
+ // of a bicomp as the "canonical DFS child" of the bicomp. Note that a
+ // vertex can be the root of more than one bicomp.
+ //
+ // We move around the external faces of a bicomp using a few property
+ // maps, which we'll initialize presently:
+ //
+ // - face_handles: maps a vertex to a face handle that can be used to
+ // move "up" a bicomp. For a vertex that isn't an articulation point,
+ // this holds the face handles that can be used to move around that
+ // vertex's unique bicomp. For a vertex that is an articulation point,
+ // this holds the face handles associated with the unique bicomp that
+ // the vertex is NOT the root of. These handles can therefore be used
+ // to move from any point on the outer face of the tree of bicomps
+ // around the current outer face towards the root of the DFS tree.
+ //
+ // - dfs_child_handles: these are used to hold face handles for
+ // vertices that are articulation points - dfs_child_handles[v] holds
+ // the face handles corresponding to vertex u in the bicomp with root
+ // u and canonical DFS child v.
+ //
+ // - canonical_dfs_child: this property map allows one to determine the
+ // canonical DFS child of a bicomp while traversing the outer face.
+ // This property map is only valid when applied to one of the two
+ // vertices adjacent to the root of the bicomp on the outer face. To
+ // be more precise, if v is the canonical DFS child of a bicomp,
+ // canonical_dfs_child[dfs_child_handles[v].first_vertex()] == v and
+ // canonical_dfs_child[dfs_child_handles[v].second_vertex()] == v.
+ //
+ // - pertinent_roots: given a vertex v, pertinent_roots[v] contains a
+ // list of face handles pointing to the top of bicomps that need to
+ // be visited by the current walkdown traversal (since they lead to
+ // backedges that need to be embedded). These lists are populated by
+ // the walkup and consumed by the walkdown.
+
+ vertex_iterator_t vi, vi_end;
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_t v(*vi);
+ vertex_t parent = dfs_parent[v];
+
+ if (parent != v)
+ {
+ edge_t parent_edge = dfs_parent_edge[v];
+ add_to_embedded_edges(parent_edge, StoreOldHandlesPolicy());
+ face_handles[v] = face_handle_t(v, parent_edge, g);
+ dfs_child_handles[v] = face_handle_t(parent, parent_edge, g);
+ }
+ else
+ {
+ face_handles[v] = face_handle_t(v);
+ dfs_child_handles[v] = face_handle_t(parent);
+ }
+
+ canonical_dfs_child[v] = v;
+ pertinent_roots[v] = face_handle_list_ptr_t(new face_handle_list_t);
+ separated_dfs_child_list[v] = vertex_list_ptr_t(new vertex_list_t);
+
+ }
+
+ // We need to create a list of not-yet-merged depth-first children for
+ // each vertex that will be updated as bicomps get merged. We sort each
+ // list by ascending lowpoint, which allows the externally_active
+ // function to run in constant time, and we keep a pointer to each
+ // vertex's representation in its parent's list, which allows merging
+ //in constant time.
+
+ for(typename vertex_vector_t::iterator itr =
+ vertices_by_lowpoint.begin();
+ itr != vertices_by_lowpoint.end(); ++itr)
+ {
+ vertex_t v(*itr);
+ vertex_t parent(dfs_parent[v]);
+ if (v != parent)
+ {
+ separated_node_in_parent_list[v] =
+ separated_dfs_child_list[parent]->insert
+ (separated_dfs_child_list[parent]->end(), v);
+ }
+ }
+
+ // The merge stack holds path information during a walkdown iteration
+ merge_stack.reserve(num_vertices(g));
+
+ }
+
+
+
+
+
+
+ bool is_planar()
+ {
+
+ // This is the main algorithm: starting with a DFS tree of embedded
+ // edges (which, since it's a tree, is planar), iterate through all
+ // vertices by reverse DFS number, attempting to embed all backedges
+ // connecting the current vertex to vertices with higher DFS numbers.
+ //
+ // The walkup is a procedure that examines all such backedges and sets
+ // up the required data structures so that they can be searched by the
+ // walkdown in linear time. The walkdown does the actual work of
+ // embedding edges and flipping bicomps, and can identify when it has
+ // come across a kuratowski subgraph.
+ //
+ // store_old_face_handles caches face handles from the previous
+ // iteration - this is used only for the kuratowski subgraph isolation,
+ // and is therefore dispatched based on the StoreOldHandlesPolicy.
+ //
+ // clean_up_embedding does some clean-up and fills in values that have
+ // to be computed lazily during the actual execution of the algorithm
+ // (for instance, whether or not a bicomp is flipped in the final
+ // embedding). It's dispatched on the the StoreEmbeddingPolicy, since
+ // it's not needed if an embedding isn't desired.
+
+ typename vertex_vector_t::reverse_iterator vi, vi_end;
+
+ vi_end = vertices_by_dfs_num.rend();
+ for(vi = vertices_by_dfs_num.rbegin(); vi != vi_end; ++vi)
+ {
+
+ store_old_face_handles(StoreOldHandlesPolicy());
+
+ vertex_t v(*vi);
+
+ walkup(v);
+
+ if (!walkdown(v))
+ return false;
+
+ }
+
+ clean_up_embedding(StoreEmbeddingPolicy());
+
+ return true;
+
+ }
+
+
+
+
+
+
+ private:
+
+
+
+
+
+ void walkup(vertex_t v)
+ {
+
+ // The point of the walkup is to follow all backedges from v to
+ // vertices with higher DFS numbers, and update pertinent_roots
+ // for the bicomp roots on the path from backedge endpoints up
+ // to v. This will set the stage for the walkdown to efficiently
+ // traverse the graph of bicomps down from v.
+
+ typedef typename face_vertex_iterator<both_sides>::type walkup_iterator_t;
+
+ out_edge_iterator_t oi, oi_end;
+ for(tie(oi,oi_end) = out_edges(v,g); oi != oi_end; ++oi)
+ {
+ edge_t e(*oi);
+ vertex_t e_source(source(e,g));
+ vertex_t e_target(target(e,g));
+
+ if (e_source == e_target)
+ {
+ self_loops.push_back(e);
+ continue;
+ }
+
+ vertex_t w(e_source == v ? e_target : e_source);
+
+ //continue if not a back edge or already embedded
+ if (dfs_number[w] < dfs_number[v] || e == dfs_parent_edge[w])
+ continue;
+
+ backedges[w].push_back(e);
+
+ v_size_t timestamp = dfs_number[v];
+ backedge_flag[w] = timestamp;
+
+ walkup_iterator_t walkup_itr(w, face_handles);
+ walkup_iterator_t walkup_end;
+ vertex_t lead_vertex = w;
+
+ while (true)
+ {
+
+ // Move to the root of the current bicomp or the first visited
+ // vertex on the bicomp by going up each side in parallel
+
+ while(walkup_itr != walkup_end &&
+ visited[*walkup_itr] != timestamp
+ )
+ {
+ lead_vertex = *walkup_itr;
+ visited[lead_vertex] = timestamp;
+ ++walkup_itr;
+ }
+
+ // If we've found the root of a bicomp through a path we haven't
+ // seen before, update pertinent_roots with a handle to the
+ // current bicomp. Otherwise, we've just seen a path we've been
+ // up before, so break out of the main while loop.
+
+ if (walkup_itr == walkup_end)
+ {
+ vertex_t dfs_child = canonical_dfs_child[lead_vertex];
+ vertex_t parent = dfs_parent[dfs_child];
+
+ visited[dfs_child_handles[dfs_child].first_vertex()]
+ = timestamp;
+ visited[dfs_child_handles[dfs_child].second_vertex()]
+ = timestamp;
+
+ if (low_point[dfs_child] < dfs_number[v] ||
+ least_ancestor[dfs_child] < dfs_number[v]
+ )
+ {
+ pertinent_roots[parent]->push_back
+ (dfs_child_handles[dfs_child]);
+ }
+ else
+ {
+ pertinent_roots[parent]->push_front
+ (dfs_child_handles[dfs_child]);
+ }
+
+ if (parent != v && visited[parent] != timestamp)
+ {
+ walkup_itr = walkup_iterator_t(parent, face_handles);
+ lead_vertex = parent;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+
+ }
+
+ }
+
+
+
+
+
+
+
+ bool walkdown(vertex_t v)
+ {
+ // This procedure is where all of the action is - pertinent_roots
+ // has already been set up by the walkup, so we just need to move
+ // down bicomps from v until we find vertices that have been
+ // labeled as backedge endpoints. Once we find such a vertex, we
+ // embed the corresponding edge and glue together the bicomps on
+ // the path connecting the two vertices in the edge. This may
+ // involve flipping bicomps along the way.
+
+ vertex_t w; //the other endpoint of the edge we're embedding
+
+ while (!pertinent_roots[v]->empty())
+ {
+
+ face_handle_t root_face_handle = pertinent_roots[v]->front();
+ face_handle_t curr_face_handle = root_face_handle;
+ pertinent_roots[v]->pop_front();
+
+ merge_stack.clear();
+
+ while(true)
+ {
+
+ typename face_vertex_iterator<>::type
+ first_face_itr, second_face_itr, face_end;
+ vertex_t first_side_vertex
+ = graph_traits<Graph>::null_vertex();
+ vertex_t second_side_vertex;
+ vertex_t first_tail, second_tail;
+
+ first_tail = second_tail = curr_face_handle.get_anchor();
+ first_face_itr = typename face_vertex_iterator<>::type
+ (curr_face_handle, face_handles, first_side());
+ second_face_itr = typename face_vertex_iterator<>::type
+ (curr_face_handle, face_handles, second_side());
+
+ for(; first_face_itr != face_end; ++first_face_itr)
+ {
+ vertex_t face_vertex(*first_face_itr);
+ if (pertinent(face_vertex, v) ||
+ externally_active(face_vertex, v)
+ )
+ {
+ first_side_vertex = face_vertex;
+ second_side_vertex = face_vertex;
+ break;
+ }
+ first_tail = face_vertex;
+ }
+
+ if (first_side_vertex == graph_traits<Graph>::null_vertex() ||
+ first_side_vertex == curr_face_handle.get_anchor()
+ )
+ break;
+
+ for(;second_face_itr != face_end; ++second_face_itr)
+ {
+ vertex_t face_vertex(*second_face_itr);
+ if (pertinent(face_vertex, v) ||
+ externally_active(face_vertex, v)
+ )
+ {
+ second_side_vertex = face_vertex;
+ break;
+ }
+ second_tail = face_vertex;
+ }
+
+ vertex_t chosen;
+ bool chose_first_upper_path;
+ if (internally_active(first_side_vertex, v))
+ {
+ chosen = first_side_vertex;
+ chose_first_upper_path = true;
+ }
+ else if (internally_active(second_side_vertex, v))
+ {
+ chosen = second_side_vertex;
+ chose_first_upper_path = false;
+ }
+ else if (pertinent(first_side_vertex, v))
+ {
+ chosen = first_side_vertex;
+ chose_first_upper_path = true;
+ }
+ else if (pertinent(second_side_vertex, v))
+ {
+ chosen = second_side_vertex;
+ chose_first_upper_path = false;
+ }
+ else
+ {
+
+ // If there's a pertinent vertex on the lower face
+ // between the first_face_itr and the second_face_itr,
+ // this graph isn't planar.
+ for(;
+ *first_face_itr != second_side_vertex;
+ ++first_face_itr
+ )
+ {
+ vertex_t p(*first_face_itr);
+ if (pertinent(p,v))
+ {
+ //Found a Kuratowski subgraph
+ kuratowski_v = v;
+ kuratowski_x = first_side_vertex;
+ kuratowski_y = second_side_vertex;
+ return false;
+ }
+ }
+
+ // Otherwise, the fact that we didn't find a pertinent
+ // vertex on this face is fine - we should set the
+ // short-circuit edges and break out of this loop to
+ // start looking at a different pertinent root.
+
+ if (first_side_vertex == second_side_vertex)
+ {
+ if (first_tail != v)
+ {
+ vertex_t first
+ = face_handles[first_tail].first_vertex();
+ vertex_t second
+ = face_handles[first_tail].second_vertex();
+ tie(first_side_vertex, first_tail)
+ = make_tuple(first_tail,
+ first == first_side_vertex ?
+ second : first
+ );
+ }
+ else if (second_tail != v)
+ {
+ vertex_t first
+ = face_handles[second_tail].first_vertex();
+ vertex_t second
+ = face_handles[second_tail].second_vertex();
+ tie(second_side_vertex, second_tail)
+ = make_tuple(second_tail,
+ first == second_side_vertex ?
+ second : first);
+ }
+ else
+ break;
+ }
+
+ canonical_dfs_child[first_side_vertex]
+ = canonical_dfs_child[root_face_handle.first_vertex()];
+ canonical_dfs_child[second_side_vertex]
+ = canonical_dfs_child[root_face_handle.second_vertex()];
+ root_face_handle.set_first_vertex(first_side_vertex);
+ root_face_handle.set_second_vertex(second_side_vertex);
+
+ if (face_handles[first_side_vertex].first_vertex() ==
+ first_tail
+ )
+ face_handles[first_side_vertex].set_first_vertex(v);
+ else
+ face_handles[first_side_vertex].set_second_vertex(v);
+
+ if (face_handles[second_side_vertex].first_vertex() ==
+ second_tail
+ )
+ face_handles[second_side_vertex].set_first_vertex(v);
+ else
+ face_handles[second_side_vertex].set_second_vertex(v);
+
+ break;
+
+ }
+
+
+ // When we unwind the stack, we need to know which direction
+ // we came down from on the top face handle
+
+ bool chose_first_lower_path =
+ (chose_first_upper_path &&
+ face_handles[chosen].first_vertex() == first_tail)
+ ||
+ (!chose_first_upper_path &&
+ face_handles[chosen].first_vertex() == second_tail);
+
+ //If there's a backedge at the chosen vertex, embed it now
+ if (backedge_flag[chosen] == dfs_number[v])
+ {
+ w = chosen;
+
+ backedge_flag[chosen] = num_vertices(g) + 1;
+ add_to_merge_points(chosen, StoreOldHandlesPolicy());
+
+ typename edge_vector_t::iterator ei, ei_end;
+ ei_end = backedges[chosen].end();
+ for(ei = backedges[chosen].begin(); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ add_to_embedded_edges(e, StoreOldHandlesPolicy());
+
+ if (chose_first_lower_path)
+ face_handles[chosen].push_first(e, g);
+ else
+ face_handles[chosen].push_second(e, g);
+ }
+
+ }
+ else
+ {
+ merge_stack.push_back(make_tuple
+ (chosen, chose_first_upper_path, chose_first_lower_path)
+ );
+ curr_face_handle = *pertinent_roots[chosen]->begin();
+ continue;
+ }
+
+ //Unwind the merge stack to the root, merging all bicomps
+
+ bool bottom_path_follows_first;
+ bool top_path_follows_first;
+ bool next_bottom_follows_first = chose_first_upper_path;
+ face_handle_t top_handle, bottom_handle;
+
+ vertex_t merge_point = chosen;
+
+ while(!merge_stack.empty())
+ {
+
+ bottom_path_follows_first = next_bottom_follows_first;
+ tie(merge_point,
+ next_bottom_follows_first,
+ top_path_follows_first
+ ) = merge_stack.back();
+ merge_stack.pop_back();
+
+ face_handle_t top_handle(face_handles[merge_point]);
+ face_handle_t bottom_handle
+ (*pertinent_roots[merge_point]->begin());
+
+ vertex_t bottom_dfs_child = canonical_dfs_child
+ [pertinent_roots[merge_point]->begin()->first_vertex()];
+
+ remove_vertex_from_separated_dfs_child_list(
+ canonical_dfs_child
+ [pertinent_roots[merge_point]->begin()->first_vertex()]
+ );
+
+ pertinent_roots[merge_point]->pop_front();
+
+ add_to_merge_points(top_handle.get_anchor(),
+ StoreOldHandlesPolicy()
+ );
+
+ if (top_path_follows_first && bottom_path_follows_first)
+ {
+ bottom_handle.flip();
+ top_handle.glue_first_to_second(bottom_handle);
+ }
+ else if (!top_path_follows_first &&
+ bottom_path_follows_first
+ )
+ {
+ flipped[bottom_dfs_child] = true;
+ top_handle.glue_second_to_first(bottom_handle);
+ }
+ else if (top_path_follows_first &&
+ !bottom_path_follows_first
+ )
+ {
+ flipped[bottom_dfs_child] = true;
+ top_handle.glue_first_to_second(bottom_handle);
+ }
+ else //!top_path_follows_first && !bottom_path_follows_first
+ {
+ bottom_handle.flip();
+ top_handle.glue_second_to_first(bottom_handle);
+ }
+
+ }
+
+ //Finally, embed all edges (v,w) at their upper end points
+ canonical_dfs_child[w]
+ = canonical_dfs_child[root_face_handle.first_vertex()];
+
+ add_to_merge_points(root_face_handle.get_anchor(),
+ StoreOldHandlesPolicy()
+ );
+
+ typename edge_vector_t::iterator ei, ei_end;
+ ei_end = backedges[chosen].end();
+ for(ei = backedges[chosen].begin(); ei != ei_end; ++ei)
+ {
+ if (next_bottom_follows_first)
+ root_face_handle.push_first(*ei, g);
+ else
+ root_face_handle.push_second(*ei, g);
+ }
+
+ backedges[chosen].clear();
+ curr_face_handle = root_face_handle;
+
+ }//while(true)
+
+ }//while(!pertinent_roots[v]->empty())
+
+ return true;
+
+ }
+
+
+
+
+
+
+ void store_old_face_handles(graph::detail::no_old_handles) {}
+
+ void store_old_face_handles(graph::detail::store_old_handles)
+ {
+ for(typename std::vector<vertex_t>::iterator mp_itr
+ = current_merge_points.begin();
+ mp_itr != current_merge_points.end(); ++mp_itr)
+ {
+ face_handles[*mp_itr].store_old_face_handles();
+ }
+ current_merge_points.clear();
+ }
+
+
+ void add_to_merge_points(vertex_t v, graph::detail::no_old_handles) {}
+
+ void add_to_merge_points(vertex_t v, graph::detail::store_old_handles)
+ {
+ current_merge_points.push_back(v);
+ }
+
+
+ void add_to_embedded_edges(edge_t e, graph::detail::no_old_handles) {}
+
+ void add_to_embedded_edges(edge_t e, graph::detail::store_old_handles)
+ {
+ embedded_edges.push_back(e);
+ }
+
+
+
+
+ void clean_up_embedding(graph::detail::no_embedding) {}
+
+ void clean_up_embedding(graph::detail::store_embedding)
+ {
+
+ // If the graph isn't biconnected, we'll still have entries
+ // in the separated_dfs_child_list for some vertices. Since
+ // these represent articulation points, we can obtain a
+ // planar embedding no matter what order we embed them in.
+
+ vertex_iterator_t xi, xi_end;
+ for(tie(xi,xi_end) = vertices(g); xi != xi_end; ++xi)
+ {
+ if (!separated_dfs_child_list[*xi]->empty())
+ {
+ typename vertex_list_t::iterator yi, yi_end;
+ yi_end = separated_dfs_child_list[*xi]->end();
+ for(yi = separated_dfs_child_list[*xi]->begin();
+ yi != yi_end; ++yi
+ )
+ {
+ dfs_child_handles[*yi].flip();
+ face_handles[*xi].glue_first_to_second
+ (dfs_child_handles[*yi]);
+ }
+ }
+ }
+
+ // Up until this point, we've flipped bicomps lazily by setting
+ // flipped[v] to true if the bicomp rooted at v was flipped (the
+ // lazy aspect of this flip is that all descendents of that vertex
+ // need to have their orientations reversed as well). Now, we
+ // traverse the DFS tree by DFS number and perform the actual
+ // flipping as needed
+
+ typedef typename vertex_vector_t::iterator vertex_vector_itr_t;
+ vertex_vector_itr_t vi_end = vertices_by_dfs_num.end();
+ for(vertex_vector_itr_t vi = vertices_by_dfs_num.begin();
+ vi != vi_end; ++vi
+ )
+ {
+ vertex_t v(*vi);
+ bool v_flipped = flipped[v];
+ bool p_flipped = flipped[dfs_parent[v]];
+ if (v_flipped && !p_flipped)
+ {
+ face_handles[v].flip();
+ }
+ else if (p_flipped && !v_flipped)
+ {
+ face_handles[v].flip();
+ flipped[v] = true;
+ }
+ else
+ {
+ flipped[v] = false;
+ }
+ }
+
+ // If there are any self-loops in the graph, they were flagged
+ // during the walkup, and we should add them to the embedding now.
+ // Adding a self loop anywhere in the embedding could never
+ // invalidate the embedding, but they would complicate the traversal
+ // if they were added during the walkup/walkdown.
+
+ typename edge_vector_t::iterator ei, ei_end;
+ ei_end = self_loops.end();
+ for(ei = self_loops.begin(); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ face_handles[source(e,g)].push_second(e,g);
+ }
+
+ }
+
+
+
+
+
+ bool pertinent(vertex_t w, vertex_t v)
+ {
+ // w is pertinent with respect to v if there is a backedge (v,w) or if
+ // w is the root of a bicomp that contains a pertinent vertex.
+
+ return backedge_flag[w] == dfs_number[v] || !pertinent_roots[w]->empty();
+ }
+
+
+
+ bool externally_active(vertex_t w, vertex_t v)
+ {
+ // Let a be any proper depth-first search ancestor of v. w is externally
+ // active with respect to v if there exists a backedge (a,w) or a
+ // backedge (a,w_0) for some w_0 in a descendent bicomp of w.
+
+ v_size_t dfs_number_of_v = dfs_number[v];
+ return (least_ancestor[w] < dfs_number_of_v) ||
+ (!separated_dfs_child_list[w]->empty() &&
+ low_point[separated_dfs_child_list[w]->front()] < dfs_number_of_v);
+ }
+
+
+
+ bool internally_active(vertex_t w, vertex_t v)
+ {
+ return pertinent(w,v) && !externally_active(w,v);
+ }
+
+
+
+
+ void remove_vertex_from_separated_dfs_child_list(vertex_t v)
+ {
+ typename vertex_list_t::iterator to_delete
+ = separated_node_in_parent_list[v];
+ garbage.splice(garbage.end(),
+ *separated_dfs_child_list[dfs_parent[v]],
+ to_delete,
+ next(to_delete)
+ );
+ }
+
+
+
+
+
+ // End of the implementation of the basic Boyer-Myrvold Algorithm. The rest
+ // of the code below implements the isolation of a Kuratowski subgraph in
+ // the case that the input graph is not planar. This is by far the most
+ // complicated part of the implementation.
+
+
+
+
+ public:
+
+
+
+
+ template <typename EdgeToBoolPropertyMap, typename EdgeContainer>
+ vertex_t kuratowski_walkup(vertex_t v,
+ EdgeToBoolPropertyMap forbidden_edge,
+ EdgeToBoolPropertyMap goal_edge,
+ EdgeToBoolPropertyMap is_embedded,
+ EdgeContainer& path_edges
+ )
+ {
+ vertex_t current_endpoint;
+ bool seen_goal_edge = false;
+ out_edge_iterator_t oi, oi_end;
+
+ for(tie(oi,oi_end) = out_edges(v,g); oi != oi_end; ++oi)
+ forbidden_edge[*oi] = true;
+
+ for(tie(oi,oi_end) = out_edges(v,g); oi != oi_end; ++oi)
+ {
+ path_edges.clear();
+
+ edge_t e(*oi);
+ current_endpoint = target(*oi,g) == v ?
+ source(*oi,g) : target(*oi,g);
+
+ if (dfs_number[current_endpoint] < dfs_number[v] ||
+ is_embedded[e] ||
+ v == current_endpoint //self-loop
+ )
+ {
+ //Not a backedge
+ continue;
+ }
+
+ path_edges.push_back(e);
+ if (goal_edge[e])
+ {
+ return current_endpoint;
+ }
+
+ typedef typename face_edge_iterator<>::type walkup_itr_t;
+
+ walkup_itr_t
+ walkup_itr(current_endpoint, face_handles, first_side());
+ walkup_itr_t walkup_end;
+
+ seen_goal_edge = false;
+
+ while (true)
+ {
+
+ if (walkup_itr != walkup_end && forbidden_edge[*walkup_itr])
+ break;
+
+ while(walkup_itr != walkup_end &&
+ !goal_edge[*walkup_itr] &&
+ !forbidden_edge[*walkup_itr]
+ )
+ {
+ edge_t f(*walkup_itr);
+ forbidden_edge[f] = true;
+ path_edges.push_back(f);
+ current_endpoint =
+ source(f, g) == current_endpoint ?
+ target(f, g) :
+ source(f,g);
+ ++walkup_itr;
+ }
+
+ if (walkup_itr != walkup_end && goal_edge[*walkup_itr])
+ {
+ path_edges.push_back(*walkup_itr);
+ seen_goal_edge = true;
+ break;
+ }
+
+ walkup_itr
+ = walkup_itr_t(current_endpoint, face_handles, first_side());
+
+ }
+
+ if (seen_goal_edge)
+ break;
+
+ }
+
+ if (seen_goal_edge)
+ return current_endpoint;
+ else
+ return graph_traits<Graph>::null_vertex();
+
+ }
+
+
+
+
+
+
+
+
+ template <typename OutputIterator, typename EdgeIndexMap>
+ void extract_kuratowski_subgraph(OutputIterator o_itr, EdgeIndexMap em)
+ {
+
+ // If the main algorithm has failed to embed one of the back-edges from
+ // a vertex v, we can use the current state of the algorithm to isolate
+ // a Kuratowksi subgraph. The isolation process breaks down into five
+ // cases, A - E. The general configuration of all five cases is shown in
+ // figure 1. There is a vertex v from which the planar
+ // v embedding process could not proceed. This means that
+ // | there exists some bicomp containing three vertices
+ // ----- x,y, and z as shown such that x and y are externally
+ // | | active with respect to v (which means that there are
+ // x y two vertices x_0 and y_0 such that (1) both x_0 and
+ // | | y_0 are proper depth-first search ancestors of v and
+ // --z-- (2) there are two disjoint paths, one connecting x
+ // and x_0 and one connecting y and y_0, both consisting
+ // fig. 1 entirely of unembedded edges). Furthermore, there
+ // exists a vertex z_0 such that z is a depth-first
+ // search ancestor of z_0 and (v,z_0) is an unembedded back-edge from v.
+ // x,y and z all exist on the same bicomp, which consists entirely of
+ // embedded edges. The five subcases break down as follows, and are
+ // handled by the algorithm logically in the order A-E: First, if v is
+ // not on the same bicomp as x,y, and z, a K_3_3 can be isolated - this
+ // is case A. So, we'll assume that v is on the same bicomp as x,y, and
+ // z. If z_0 is on a different bicomp than x,y, and z, a K_3_3 can also
+ // be isolated - this is a case B - so we'll assume from now on that v
+ // is on the same bicomp as x, y, and z=z_0. In this case, one can use
+ // properties of the Boyer-Myrvold algorithm to show the existence of an
+ // "x-y path" connecting some vertex on the "left side" of the x,y,z
+ // bicomp with some vertex on the "right side" of the bicomp (where the
+ // left and right are split by a line drawn through v and z.If either of
+ // the endpoints of the x-y path is above x or y on the bicomp, a K_3_3
+ // can be isolated - this is a case C. Otherwise, both endpoints are at
+ // or below x and y on the bicomp. If there is a vertex alpha on the x-y
+ // path such that alpha is not x or y and there's a path from alpha to v
+ // that's disjoint from any of the edges on the bicomp and the x-y path,
+ // a K_3_3 can be isolated - this is a case D. Otherwise, properties of
+ // the Boyer-Myrvold algorithm can be used to show that another vertex
+ // w exists on the lower half of the bicomp such that w is externally
+ // active with respect to v. w can then be used to isolate a K_5 - this
+ // is the configuration of case E.
+
+ vertex_iterator_t vi, vi_end;
+ edge_iterator_t ei, ei_end;
+ out_edge_iterator_t oei, oei_end;
+ typename std::vector<edge_t>::iterator xi, xi_end;
+
+ // Clear the short-circuit edges - these are needed for the planar
+ // testing/embedding algorithm to run in linear time, but they'll
+ // complicate the kuratowski subgraph isolation
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ face_handles[*vi].reset_vertex_cache();
+ dfs_child_handles[*vi].reset_vertex_cache();
+ }
+
+ vertex_t v = kuratowski_v;
+ vertex_t x = kuratowski_x;
+ vertex_t y = kuratowski_y;
+
+ typedef iterator_property_map
+ <typename std::vector<bool>::iterator, EdgeIndexMap>
+ edge_to_bool_map_t;
+
+ std::vector<bool> is_in_subgraph_vector(num_edges(g), false);
+ edge_to_bool_map_t is_in_subgraph(is_in_subgraph_vector.begin(), em);
+
+ std::vector<bool> is_embedded_vector(num_edges(g), false);
+ edge_to_bool_map_t is_embedded(is_embedded_vector.begin(), em);
+
+ typename std::vector<edge_t>::iterator embedded_itr, embedded_end;
+ embedded_end = embedded_edges.end();
+ for(embedded_itr = embedded_edges.begin();
+ embedded_itr != embedded_end; ++embedded_itr
+ )
+ is_embedded[*embedded_itr] = true;
+
+ // upper_face_vertex is true for x,y, and all vertices above x and y in
+ // the bicomp
+ std::vector<bool> upper_face_vertex_vector(num_vertices(g), false);
+ vertex_to_bool_map_t upper_face_vertex
+ (upper_face_vertex_vector.begin(), vm);
+
+ std::vector<bool> lower_face_vertex_vector(num_vertices(g), false);
+ vertex_to_bool_map_t lower_face_vertex
+ (lower_face_vertex_vector.begin(), vm);
+
+ // These next few variable declarations are all things that we need
+ // to find.
+ vertex_t z;
+ vertex_t bicomp_root;
+ vertex_t w = graph_traits<Graph>::null_vertex();
+ face_handle_t w_handle;
+ face_handle_t v_dfchild_handle;
+ vertex_t first_x_y_path_endpoint = graph_traits<Graph>::null_vertex();
+ vertex_t second_x_y_path_endpoint = graph_traits<Graph>::null_vertex();
+ vertex_t w_ancestor = v;
+
+ enum case_t{NO_CASE_CHOSEN, CASE_A, CASE_B, CASE_C, CASE_D, CASE_E};
+ case_t chosen_case = NO_CASE_CHOSEN;
+
+ std::vector<edge_t> x_external_path;
+ std::vector<edge_t> y_external_path;
+ std::vector<edge_t> case_d_edges;
+
+ std::vector<edge_t> z_v_path;
+ std::vector<edge_t> w_path;
+
+ //first, use a walkup to find a path from V that starts with a
+ //backedge from V, then goes up until it hits either X or Y
+ //(but doesn't find X or Y as the root of a bicomp)
+
+ typename face_vertex_iterator<>::type
+ x_upper_itr(x, face_handles, first_side());
+ typename face_vertex_iterator<>::type
+ x_lower_itr(x, face_handles, second_side());
+ typename face_vertex_iterator<>::type face_itr, face_end;
+
+ // Don't know which path from x is the upper or lower path -
+ // we'll find out here
+ for(face_itr = x_upper_itr; face_itr != face_end; ++face_itr)
+ {
+ if (*face_itr == y)
+ {
+ std::swap(x_upper_itr, x_lower_itr);
+ break;
+ }
+ }
+
+ upper_face_vertex[x] = true;
+
+ vertex_t current_vertex = x;
+ vertex_t previous_vertex;
+ for(face_itr = x_upper_itr; face_itr != face_end; ++face_itr)
+ {
+ previous_vertex = current_vertex;
+ current_vertex = *face_itr;
+ upper_face_vertex[current_vertex] = true;
+ }
+
+ v_dfchild_handle
+ = dfs_child_handles[canonical_dfs_child[previous_vertex]];
+
+ for(face_itr = x_lower_itr; *face_itr != y; ++face_itr)
+ {
+ vertex_t current_vertex(*face_itr);
+ lower_face_vertex[current_vertex] = true;
+
+ typename face_handle_list_t::iterator roots_itr, roots_end;
+
+ if (w == graph_traits<Graph>::null_vertex()) //haven't found a w yet
+ {
+ roots_end = pertinent_roots[current_vertex]->end();
+ for(roots_itr = pertinent_roots[current_vertex]->begin();
+ roots_itr != roots_end; ++roots_itr
+ )
+ {
+ if (low_point[canonical_dfs_child[roots_itr->first_vertex()]]
+ < dfs_number[v]
+ )
+ {
+ w = current_vertex;
+ w_handle = *roots_itr;
+ break;
+ }
+ }
+ }
+
+ }
+
+ for(; face_itr != face_end; ++face_itr)
+ {
+ vertex_t current_vertex(*face_itr);
+ upper_face_vertex[current_vertex] = true;
+ bicomp_root = current_vertex;
+ }
+
+ typedef typename face_edge_iterator<>::type walkup_itr_t;
+
+ std::vector<bool> outer_face_edge_vector(num_edges(g), false);
+ edge_to_bool_map_t outer_face_edge(outer_face_edge_vector.begin(), em);
+
+ walkup_itr_t walkup_end;
+ for(walkup_itr_t walkup_itr(x, face_handles, first_side());
+ walkup_itr != walkup_end; ++walkup_itr
+ )
+ {
+ outer_face_edge[*walkup_itr] = true;
+ is_in_subgraph[*walkup_itr] = true;
+ }
+
+ for(walkup_itr_t walkup_itr(x, face_handles, second_side());
+ walkup_itr != walkup_end; ++walkup_itr
+ )
+ {
+ outer_face_edge[*walkup_itr] = true;
+ is_in_subgraph[*walkup_itr] = true;
+ }
+
+ std::vector<bool> forbidden_edge_vector(num_edges(g), false);
+ edge_to_bool_map_t forbidden_edge(forbidden_edge_vector.begin(), em);
+
+ std::vector<bool> goal_edge_vector(num_edges(g), false);
+ edge_to_bool_map_t goal_edge(goal_edge_vector.begin(), em);
+
+
+ //Find external path to x and to y
+
+ for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ goal_edge[e]
+ = !outer_face_edge[e] && (source(e,g) == x || target(e,g) == x);
+ forbidden_edge[*ei] = outer_face_edge[*ei];
+ }
+
+ vertex_t x_ancestor = v;
+ vertex_t x_endpoint = graph_traits<Graph>::null_vertex();
+
+ while(x_endpoint == graph_traits<Graph>::null_vertex())
+ {
+ x_ancestor = dfs_parent[x_ancestor];
+ x_endpoint = kuratowski_walkup(x_ancestor,
+ forbidden_edge,
+ goal_edge,
+ is_embedded,
+ x_external_path
+ );
+
+ }
+
+
+ for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ goal_edge[e]
+ = !outer_face_edge[e] && (source(e,g) == y || target(e,g) == y);
+ forbidden_edge[*ei] = outer_face_edge[*ei];
+ }
+
+ vertex_t y_ancestor = v;
+ vertex_t y_endpoint = graph_traits<Graph>::null_vertex();
+
+ while(y_endpoint == graph_traits<Graph>::null_vertex())
+ {
+ y_ancestor = dfs_parent[y_ancestor];
+ y_endpoint = kuratowski_walkup(y_ancestor,
+ forbidden_edge,
+ goal_edge,
+ is_embedded,
+ y_external_path
+ );
+
+ }
+
+
+ vertex_t parent, child;
+
+ //If v isn't on the same bicomp as x and y, it's a case A
+ if (bicomp_root != v)
+ {
+ chosen_case = CASE_A;
+
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ if (lower_face_vertex[*vi])
+ for(tie(oei,oei_end) = out_edges(*vi,g); oei != oei_end; ++oei)
+ if(!outer_face_edge[*oei])
+ goal_edge[*oei] = true;
+
+ for(tie(ei,ei_end) = edges(g); ei != ei_end; ++ei)
+ forbidden_edge[*ei] = outer_face_edge[*ei];
+
+ z = kuratowski_walkup
+ (v, forbidden_edge, goal_edge, is_embedded, z_v_path);
+
+ }
+ else if (w != graph_traits<Graph>::null_vertex())
+ {
+ chosen_case = CASE_B;
+
+ for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ goal_edge[e] = false;
+ forbidden_edge[e] = outer_face_edge[e];
+ }
+
+ goal_edge[w_handle.first_edge()] = true;
+ goal_edge[w_handle.second_edge()] = true;
+
+ z = kuratowski_walkup(v,
+ forbidden_edge,
+ goal_edge,
+ is_embedded,
+ z_v_path
+ );
+
+
+ for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ forbidden_edge[*ei] = outer_face_edge[*ei];
+ }
+
+ typename std::vector<edge_t>::iterator pi, pi_end;
+ pi_end = z_v_path.end();
+ for(pi = z_v_path.begin(); pi != pi_end; ++pi)
+ {
+ goal_edge[*pi] = true;
+ }
+
+ w_ancestor = v;
+ vertex_t w_endpoint = graph_traits<Graph>::null_vertex();
+
+ while(w_endpoint == graph_traits<Graph>::null_vertex())
+ {
+ w_ancestor = dfs_parent[w_ancestor];
+ w_endpoint = kuratowski_walkup(w_ancestor,
+ forbidden_edge,
+ goal_edge,
+ is_embedded,
+ w_path
+ );
+
+ }
+
+ // We really want both the w walkup and the z walkup to finish on
+ // exactly the same edge, but for convenience (since we don't have
+ // control over which side of a bicomp a walkup moves up) we've
+ // defined the walkup to either end at w_handle.first_edge() or
+ // w_handle.second_edge(). If both walkups ended at different edges,
+ // we'll do a little surgery on the w walkup path to make it follow
+ // the other side of the final bicomp.
+
+ if ((w_path.back() == w_handle.first_edge() &&
+ z_v_path.back() == w_handle.second_edge())
+ ||
+ (w_path.back() == w_handle.second_edge() &&
+ z_v_path.back() == w_handle.first_edge())
+ )
+ {
+ walkup_itr_t wi, wi_end;
+ edge_t final_edge = w_path.back();
+ vertex_t anchor
+ = source(final_edge, g) == w_handle.get_anchor() ?
+ target(final_edge, g) : source(final_edge, g);
+ if (face_handles[anchor].first_edge() == final_edge)
+ wi = walkup_itr_t(anchor, face_handles, second_side());
+ else
+ wi = walkup_itr_t(anchor, face_handles, first_side());
+
+ w_path.pop_back();
+
+ for(; wi != wi_end; ++wi)
+ {
+ edge_t e(*wi);
+ if (w_path.back() == e)
+ w_path.pop_back();
+ else
+ w_path.push_back(e);
+ }
+ }
+
+
+ }
+ else
+ {
+
+ //We need to find a valid z, since the x-y path re-defines the lower
+ //face, and the z we found earlier may now be on the upper face.
+
+ chosen_case = CASE_E;
+
+
+ // The z we've used so far is just an externally active vertex on the
+ // lower face path, but may not be the z we need for a case C, D, or
+ // E subgraph. the z we need now is any externally active vertex on
+ // the lower face path with both old_face_handles edges on the outer
+ // face. Since we know an x-y path exists, such a z must also exist.
+
+ //TODO: find this z in the first place.
+
+ //find the new z
+
+ for(face_itr = x_lower_itr; *face_itr != y; ++face_itr)
+ {
+ vertex_t possible_z(*face_itr);
+ if (pertinent(possible_z,v) &&
+ outer_face_edge[face_handles[possible_z].old_first_edge()] &&
+ outer_face_edge[face_handles[possible_z].old_second_edge()]
+ )
+ {
+ z = possible_z;
+ break;
+ }
+ }
+
+ //find x-y path, and a w if one exists.
+
+ if (externally_active(z,v))
+ w = z;
+
+
+ typedef typename face_edge_iterator
+ <single_side, previous_iteration>::type old_face_iterator_t;
+
+ old_face_iterator_t
+ first_old_face_itr(z, face_handles, first_side());
+ old_face_iterator_t
+ second_old_face_itr(z, face_handles, second_side());
+ old_face_iterator_t old_face_itr, old_face_end;
+
+ std::vector<old_face_iterator_t> old_face_iterators;
+ old_face_iterators.push_back(first_old_face_itr);
+ old_face_iterators.push_back(second_old_face_itr);
+
+ std::vector<bool> x_y_path_vertex_vector(num_vertices(g), false);
+ vertex_to_bool_map_t x_y_path_vertex
+ (x_y_path_vertex_vector.begin(), vm);
+
+ typename std::vector<old_face_iterator_t>::iterator
+ of_itr, of_itr_end;
+ of_itr_end = old_face_iterators.end();
+ for(of_itr = old_face_iterators.begin();
+ of_itr != of_itr_end; ++of_itr
+ )
+ {
+
+ old_face_itr = *of_itr;
+
+ vertex_t previous_vertex;
+ bool seen_x_or_y = false;
+ vertex_t current_vertex = z;
+ for(; old_face_itr != old_face_end; ++old_face_itr)
+ {
+ edge_t e(*old_face_itr);
+ previous_vertex = current_vertex;
+ current_vertex = source(e,g) == current_vertex ?
+ target(e,g) : source(e,g);
+
+ if (current_vertex == x || current_vertex == y)
+ seen_x_or_y = true;
+
+ if (w == graph_traits<Graph>::null_vertex() &&
+ externally_active(current_vertex,v) &&
+ outer_face_edge[e] &&
+ outer_face_edge[*next(old_face_itr)] &&
+ !seen_x_or_y
+ )
+ {
+ w = current_vertex;
+ }
+
+ if (!outer_face_edge[e])
+ {
+ if (!upper_face_vertex[current_vertex] &&
+ !lower_face_vertex[current_vertex]
+ )
+ {
+ x_y_path_vertex[current_vertex] = true;
+ }
+
+ is_in_subgraph[e] = true;
+ if (upper_face_vertex[source(e,g)] ||
+ lower_face_vertex[source(e,g)]
+ )
+ {
+ if (first_x_y_path_endpoint ==
+ graph_traits<Graph>::null_vertex()
+ )
+ first_x_y_path_endpoint = source(e,g);
+ else
+ second_x_y_path_endpoint = source(e,g);
+ }
+ if (upper_face_vertex[target(e,g)] ||
+ lower_face_vertex[target(e,g)]
+ )
+ {
+ if (first_x_y_path_endpoint ==
+ graph_traits<Graph>::null_vertex()
+ )
+ first_x_y_path_endpoint = target(e,g);
+ else
+ second_x_y_path_endpoint = target(e,g);
+ }
+
+
+ }
+ else if (previous_vertex == x || previous_vertex == y)
+ {
+ chosen_case = CASE_C;
+ }
+
+ }
+
+ }
+
+ // Look for a case D - one of v's embedded edges will connect to the
+ // x-y path along an inner face path.
+
+ //First, get a list of all of v's embedded child edges
+
+ out_edge_iterator_t v_edge_itr, v_edge_end;
+ for(tie(v_edge_itr,v_edge_end) = out_edges(v,g);
+ v_edge_itr != v_edge_end; ++v_edge_itr
+ )
+ {
+ edge_t embedded_edge(*v_edge_itr);
+
+ if (!is_embedded[embedded_edge] ||
+ embedded_edge == dfs_parent_edge[v]
+ )
+ continue;
+
+ case_d_edges.push_back(embedded_edge);
+
+ vertex_t current_vertex
+ = source(embedded_edge,g) == v ?
+ target(embedded_edge,g) : source(embedded_edge,g);
+
+ typename face_edge_iterator<>::type
+ internal_face_itr, internal_face_end;
+ if (face_handles[current_vertex].first_vertex() == v)
+ {
+ internal_face_itr = typename face_edge_iterator<>::type
+ (current_vertex, face_handles, second_side());
+ }
+ else
+ {
+ internal_face_itr = typename face_edge_iterator<>::type
+ (current_vertex, face_handles, first_side());
+ }
+
+ while(internal_face_itr != internal_face_end &&
+ !outer_face_edge[*internal_face_itr] &&
+ !x_y_path_vertex[current_vertex]
+ )
+ {
+ edge_t e(*internal_face_itr);
+ case_d_edges.push_back(e);
+ current_vertex =
+ source(e,g) == current_vertex ? target(e,g) : source(e,g);
+ ++internal_face_itr;
+ }
+
+ if (x_y_path_vertex[current_vertex])
+ {
+ chosen_case = CASE_D;
+ break;
+ }
+ else
+ {
+ case_d_edges.clear();
+ }
+
+ }
+
+
+ }
+
+
+
+
+ if (chosen_case != CASE_B && chosen_case != CASE_A)
+ {
+
+ //Finding z and w.
+
+ for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ edge_t e(*ei);
+ goal_edge[e] = !outer_face_edge[e] &&
+ (source(e,g) == z || target(e,g) == z);
+ forbidden_edge[e] = outer_face_edge[e];
+ }
+
+ kuratowski_walkup(v,
+ forbidden_edge,
+ goal_edge,
+ is_embedded,
+ z_v_path
+ );
+
+ if (chosen_case == CASE_E)
+ {
+
+ for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ {
+ forbidden_edge[*ei] = outer_face_edge[*ei];
+ goal_edge[*ei] = !outer_face_edge[*ei] &&
+ (source(*ei,g) == w || target(*ei,g) == w);
+ }
+
+ for(tie(oei, oei_end) = out_edges(w,g); oei != oei_end; ++oei)
+ {
+ if (!outer_face_edge[*oei])
+ goal_edge[*oei] = true;
+ }
+
+ typename std::vector<edge_t>::iterator pi, pi_end;
+ pi_end = z_v_path.end();
+ for(pi = z_v_path.begin(); pi != pi_end; ++pi)
+ {
+ goal_edge[*pi] = true;
+ }
+
+ w_ancestor = v;
+ vertex_t w_endpoint = graph_traits<Graph>::null_vertex();
+
+ while(w_endpoint == graph_traits<Graph>::null_vertex())
+ {
+ w_ancestor = dfs_parent[w_ancestor];
+ w_endpoint = kuratowski_walkup(w_ancestor,
+ forbidden_edge,
+ goal_edge,
+ is_embedded,
+ w_path
+ );
+
+ }
+
+ }
+
+
+ }
+
+
+ //We're done isolating the Kuratowski subgraph at this point -
+ //but there's still some cleaning up to do.
+
+ //Update is_in_subgraph with the paths we just found
+
+ xi_end = x_external_path.end();
+ for(xi = x_external_path.begin(); xi != xi_end; ++xi)
+ is_in_subgraph[*xi] = true;
+
+ xi_end = y_external_path.end();
+ for(xi = y_external_path.begin(); xi != xi_end; ++xi)
+ is_in_subgraph[*xi] = true;
+
+ xi_end = z_v_path.end();
+ for(xi = z_v_path.begin(); xi != xi_end; ++xi)
+ is_in_subgraph[*xi] = true;
+
+ xi_end = case_d_edges.end();
+ for(xi = case_d_edges.begin(); xi != xi_end; ++xi)
+ is_in_subgraph[*xi] = true;
+
+ xi_end = w_path.end();
+ for(xi = w_path.begin(); xi != xi_end; ++xi)
+ is_in_subgraph[*xi] = true;
+
+ child = bicomp_root;
+ parent = dfs_parent[child];
+ while(child != parent)
+ {
+ is_in_subgraph[dfs_parent_edge[child]] = true;
+ tie(parent, child) = std::make_pair( dfs_parent[parent], parent );
+ }
+
+
+
+
+ // At this point, we've already isolated the Kuratowski subgraph and
+ // collected all of the edges that compose it in the is_in_subgraph
+ // property map. But we want the verification of such a subgraph to be
+ // a deterministic process, and we can simplify the function
+ // is_kuratowski_subgraph by cleaning up some edges here.
+
+ if (chosen_case == CASE_B)
+ {
+ is_in_subgraph[dfs_parent_edge[v]] = false;
+ }
+ else if (chosen_case == CASE_C)
+ {
+ // In a case C subgraph, at least one of the x-y path endpoints
+ // (call it alpha) is above either x or y on the outer face. The
+ // other endpoint may be attached at x or y OR above OR below. In
+ // any of these three cases, we can form a K_3_3 by removing the
+ // edge attached to v on the outer face that is NOT on the path to
+ // alpha.
+
+ typename face_vertex_iterator<single_side, follow_visitor>::type
+ face_itr, face_end;
+ if (face_handles[v_dfchild_handle.first_vertex()].first_edge() ==
+ v_dfchild_handle.first_edge()
+ )
+ {
+ face_itr = typename face_vertex_iterator
+ <single_side, follow_visitor>::type
+ (v_dfchild_handle.first_vertex(), face_handles, second_side());
+ }
+ else
+ {
+ face_itr = typename face_vertex_iterator
+ <single_side, follow_visitor>::type
+ (v_dfchild_handle.first_vertex(), face_handles, first_side());
+ }
+
+ for(; true; ++face_itr)
+ {
+ vertex_t current_vertex(*face_itr);
+ if (current_vertex == x || current_vertex == y)
+ {
+ is_in_subgraph[v_dfchild_handle.first_edge()] = false;
+ break;
+ }
+ else if (current_vertex == first_x_y_path_endpoint ||
+ current_vertex == second_x_y_path_endpoint)
+ {
+ is_in_subgraph[v_dfchild_handle.second_edge()] = false;
+ break;
+ }
+ }
+
+ }
+ else if (chosen_case == CASE_D)
+ {
+ // Need to remove both of the edges adjacent to v on the outer face.
+ // remove the connecting edges from v to bicomp, then
+ // is_kuratowski_subgraph will shrink vertices of degree 1
+ // automatically...
+
+ is_in_subgraph[v_dfchild_handle.first_edge()] = false;
+ is_in_subgraph[v_dfchild_handle.second_edge()] = false;
+
+ }
+ else if (chosen_case == CASE_E)
+ {
+ // Similarly to case C, if the endpoints of the x-y path are both
+ // below x and y, we should remove an edge to allow the subgraph to
+ // contract to a K_3_3.
+
+
+ if ((first_x_y_path_endpoint != x && first_x_y_path_endpoint != y) ||
+ (second_x_y_path_endpoint != x && second_x_y_path_endpoint != y)
+ )
+ {
+ is_in_subgraph[dfs_parent_edge[v]] = false;
+
+ vertex_t deletion_endpoint, other_endpoint;
+ if (lower_face_vertex[first_x_y_path_endpoint])
+ {
+ deletion_endpoint = second_x_y_path_endpoint;
+ other_endpoint = first_x_y_path_endpoint;
+ }
+ else
+ {
+ deletion_endpoint = first_x_y_path_endpoint;
+ other_endpoint = second_x_y_path_endpoint;
+ }
+
+ typename face_edge_iterator<>::type face_itr, face_end;
+
+ bool found_other_endpoint = false;
+ for(face_itr = typename face_edge_iterator<>::type
+ (deletion_endpoint, face_handles, first_side());
+ face_itr != face_end; ++face_itr
+ )
+ {
+ edge_t e(*face_itr);
+ if (source(e,g) == other_endpoint ||
+ target(e,g) == other_endpoint
+ )
+ {
+ found_other_endpoint = true;
+ break;
+ }
+ }
+
+ if (found_other_endpoint)
+ {
+ is_in_subgraph[face_handles[deletion_endpoint].first_edge()]
+ = false;
+ }
+ else
+ {
+ is_in_subgraph[face_handles[deletion_endpoint].second_edge()]
+ = false;
+ }
+ }
+
+ }
+
+
+ for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ if (is_in_subgraph[*ei])
+ *o_itr = *ei;
+
+ }
+
+
+
+ template<typename EdgePermutation>
+ void make_edge_permutation(EdgePermutation perm)
+ {
+ vertex_iterator_t vi, vi_end;
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_t v(*vi);
+ perm[v].clear();
+ face_handles[v].get_list(std::back_inserter(perm[v]));
+ }
+ }
+
+
+ private:
+
+ const Graph& g;
+ VertexIndexMap vm;
+
+ vertex_t kuratowski_v;
+ vertex_t kuratowski_x;
+ vertex_t kuratowski_y;
+
+ vertex_list_t garbage; // we delete items from linked lists by
+ // splicing them into garbage
+
+ //only need these two for kuratowski subgraph isolation
+ std::vector<vertex_t> current_merge_points;
+ std::vector<edge_t> embedded_edges;
+
+ //property map storage
+ std::vector<v_size_t> low_point_vector;
+ std::vector<vertex_t> dfs_parent_vector;
+ std::vector<v_size_t> dfs_number_vector;
+ std::vector<v_size_t> least_ancestor_vector;
+ std::vector<face_handle_list_ptr_t> pertinent_roots_vector;
+ std::vector<v_size_t> backedge_flag_vector;
+ std::vector<v_size_t> visited_vector;
+ std::vector< face_handle_t > face_handles_vector;
+ std::vector< face_handle_t > dfs_child_handles_vector;
+ std::vector< vertex_list_ptr_t > separated_dfs_child_list_vector;
+ std::vector< typename vertex_list_t::iterator >
+ separated_node_in_parent_list_vector;
+ std::vector<vertex_t> canonical_dfs_child_vector;
+ std::vector<bool> flipped_vector;
+ std::vector<edge_vector_t> backedges_vector;
+ edge_vector_t self_loops;
+ std::vector<edge_t> dfs_parent_edge_vector;
+ vertex_vector_t vertices_by_dfs_num;
+
+ //property maps
+ vertex_to_v_size_map_t low_point;
+ vertex_to_vertex_map_t dfs_parent;
+ vertex_to_v_size_map_t dfs_number;
+ vertex_to_v_size_map_t least_ancestor;
+ vertex_to_face_handle_list_ptr_map_t pertinent_roots;
+ vertex_to_v_size_map_t backedge_flag;
+ vertex_to_v_size_map_t visited;
+ vertex_to_face_handle_map_t face_handles;
+ vertex_to_face_handle_map_t dfs_child_handles;
+ vertex_to_vertex_list_ptr_map_t separated_dfs_child_list;
+ vertex_to_separated_node_map_t separated_node_in_parent_list;
+ vertex_to_vertex_map_t canonical_dfs_child;
+ vertex_to_bool_map_t flipped;
+ vertex_to_edge_vector_map_t backedges;
+ vertex_to_edge_map_t dfs_parent_edge; //only need for kuratowski
+
+ merge_stack_t merge_stack;
+
+ };
+
+
+} //namespace boost
+
+#endif //__BOYER_MYRVOLD_IMPL_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/planar_detail/bucket_sort.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/planar_detail/bucket_sort.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,144 @@
+//=======================================================================
+// Copyright 2007 Aaron Windsor
+//
+// 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)
+//=======================================================================
+#ifndef __BUCKET_SORT_HPP__
+#define __BUCKET_SORT_HPP__
+
+#include <vector>
+#include <algorithm>
+#include <boost/property_map.hpp>
+
+
+
+namespace boost
+{
+
+
+ template <typename ItemToRankMap>
+ struct rank_comparison
+ {
+ rank_comparison(ItemToRankMap arg_itrm) : itrm(arg_itrm) {}
+
+ template <typename Item>
+ bool operator() (Item x, Item y) const
+ {
+ return get(itrm, x) < get(itrm, y);
+ }
+
+ private:
+ ItemToRankMap itrm;
+
+ };
+
+
+ template <typename TupleType,
+ int N,
+ typename PropertyMapWrapper = identity_property_map>
+ struct property_map_tuple_adaptor :
+ public put_get_helper< typename PropertyMapWrapper::value_type,
+ property_map_tuple_adaptor
+ <TupleType, N, PropertyMapWrapper>
+ >
+ {
+ typedef typename PropertyMapWrapper::reference reference;
+ typedef typename PropertyMapWrapper::value_type value_type;
+ typedef TupleType key_type;
+ typedef readable_property_map_tag category;
+
+ property_map_tuple_adaptor() {}
+
+ property_map_tuple_adaptor(PropertyMapWrapper wrapper_map) :
+ m_wrapper_map(wrapper_map)
+ {}
+
+ inline value_type operator[](const key_type& x) const
+ {
+ return get(m_wrapper_map, get<n>(x));
+ }
+
+ static const int n = N;
+ PropertyMapWrapper m_wrapper_map;
+
+ };
+
+
+
+
+ // This function sorts a sequence of n items by their ranks in linear time,
+ // given that all ranks are in the range [0, range). This sort is stable.
+ template <typename ForwardIterator,
+ typename ItemToRankMap,
+ typename SizeType>
+ void bucket_sort(ForwardIterator begin,
+ ForwardIterator end,
+ ItemToRankMap rank,
+ SizeType range = 0)
+ {
+#ifdef BOOST_GRAPH_PREFER_STD_LIB
+ std::stable_sort(begin, end, rank_comparison<ItemToRankMap>(rank));
+#else
+ typedef std::vector
+ < typename boost::property_traits<ItemToRankMap>::key_type >
+ vector_of_values_t;
+ typedef std::vector< vector_of_values_t > vector_of_vectors_t;
+
+ if (!range)
+ {
+ rank_comparison<ItemToRankMap> cmp(rank);
+ ForwardIterator max_by_rank = std::max_element(begin, end, cmp);
+ if (max_by_rank == end)
+ return;
+ range = get(rank, *max_by_rank) + 1;
+ }
+
+ vector_of_vectors_t temp_values(range);
+
+ for(ForwardIterator itr = begin; itr != end; ++itr)
+ {
+ temp_values[get(rank, *itr)].push_back(*itr);
+ }
+
+ ForwardIterator orig_seq_itr = begin;
+ typename vector_of_vectors_t::iterator itr_end = temp_values.end();
+ for(typename vector_of_vectors_t::iterator itr = temp_values.begin();
+ itr != itr_end; ++itr
+ )
+ {
+ typename vector_of_values_t::iterator jtr_end = itr->end();
+ for(typename vector_of_values_t::iterator jtr = itr->begin();
+ jtr != jtr_end; ++jtr
+ )
+ {
+ *orig_seq_itr = *jtr;
+ ++orig_seq_itr;
+ }
+ }
+#endif
+ }
+
+
+ template <typename ForwardIterator, typename ItemToRankMap>
+ void bucket_sort(ForwardIterator begin,
+ ForwardIterator end,
+ ItemToRankMap rank)
+ {
+ bucket_sort(begin, end, rank, 0);
+ }
+
+ template <typename ForwardIterator>
+ void bucket_sort(ForwardIterator begin,
+ ForwardIterator end
+ )
+ {
+ bucket_sort(begin, end, identity_property_map());
+ }
+
+
+} //namespace boost
+
+
+#endif //__BUCKET_SORT_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/planar_detail/face_handles.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/planar_detail/face_handles.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,497 @@
+//=======================================================================
+// Copyright (c) Aaron Windsor 2007
+//
+// 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)
+//=======================================================================
+
+#ifndef __FACE_HANDLES_HPP__
+#define __FACE_HANDLES_HPP__
+
+
+#include <list>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/shared_ptr.hpp>
+
+
+// A "face handle" is an optimization meant to serve two purposes in
+// the implementation of the Boyer-Myrvold planarity test: (1) it holds
+// the partial planar embedding of a particular vertex as it's being
+// constructed, and (2) it allows for efficient traversal around the
+// outer face of the partial embedding at that particular vertex. A face
+// handle is lightweight, just a shared pointer to the actual implementation,
+// since it is passed around/copied liberally in the algorithm. It consists
+// of an "anchor" (the actual vertex it's associated with) as well as a
+// sequence of edges. The functions first_vertex/second_vertex and
+// first_edge/second_edge allow fast access to the beginning and end of the
+// stored sequence, which allows one to traverse the outer face of the partial
+// planar embedding as it's being created.
+//
+// There are some policies below that define the contents of the face handles:
+// in the case no embedding is needed (for example, if one just wants to use
+// the Boyer-Myrvold algorithm as a true/false test for planarity, the
+// no_embedding class can be passed as the StoreEmbedding policy. Otherwise,
+// either std_list (which uses as std::list) or recursive_lazy_list can be
+// passed as this policy. recursive_lazy_list has the best theoretical
+// performance (O(n) for a sequence of interleaved concatenations and reversals
+// of the underlying list), but I've noticed little difference between std_list
+// and recursive_lazy_list in my tests, even though using std_list changes
+// the worst-case complexity of the planarity test to O(n^2)
+//
+// Another policy is StoreOldHandlesPolicy, which specifies whether or not
+// to keep a record of the previous first/second vertex/edge - this is needed
+// if a Kuratowski subgraph needs to be isolated.
+
+
+namespace boost { namespace graph { namespace detail {
+
+
+ //face handle policies
+
+ //EmbeddingStorage policy
+ struct store_embedding {};
+ struct recursive_lazy_list : public store_embedding {};
+ struct std_list : public store_embedding {};
+ struct no_embedding {};
+
+ //StoreOldHandlesPolicy
+ struct store_old_handles {};
+ struct no_old_handles {};
+
+
+
+
+ template<typename DataType>
+ struct lazy_list_node
+ {
+ typedef shared_ptr< lazy_list_node<DataType> > ptr_t;
+
+ lazy_list_node(const DataType& data) :
+ m_reversed(false),
+ m_data(data),
+ m_has_data(true)
+ {}
+
+ lazy_list_node(ptr_t left_child, ptr_t right_child) :
+ m_reversed(false),
+ m_has_data(false),
+ m_left_child(left_child),
+ m_right_child(right_child)
+ {}
+
+ bool m_reversed;
+ DataType m_data;
+ bool m_has_data;
+ shared_ptr<lazy_list_node> m_left_child;
+ shared_ptr<lazy_list_node> m_right_child;
+ };
+
+
+
+ template <typename StoreOldHandlesPolicy, typename Vertex, typename Edge>
+ struct old_handles_storage;
+
+ template <typename Vertex, typename Edge>
+ struct old_handles_storage<store_old_handles, Vertex, Edge>
+ {
+ Vertex first_vertex;
+ Vertex second_vertex;
+ Edge first_edge;
+ Edge second_edge;
+ };
+
+ template <typename Vertex, typename Edge>
+ struct old_handles_storage<no_old_handles, Vertex, Edge>
+ {};
+
+
+
+
+
+
+ template <typename StoreEmbeddingPolicy, typename Edge>
+ struct edge_list_storage;
+
+
+
+
+
+ template <typename Edge>
+ struct edge_list_storage<no_embedding, Edge>
+ {
+ typedef void type;
+
+ void push_back(Edge) {}
+ void push_front(Edge) {}
+ void reverse() {}
+ void concat_front(edge_list_storage<no_embedding,Edge>) {}
+ void concat_back(edge_list_storage<no_embedding,Edge>) {}
+ template <typename OutputIterator>
+ void get_list(OutputIterator) {}
+ };
+
+
+
+
+
+ template <typename Edge>
+ struct edge_list_storage<recursive_lazy_list, Edge>
+ {
+ typedef lazy_list_node<Edge> node_type;
+ typedef shared_ptr< node_type > type;
+ type value;
+
+ void push_back(Edge e)
+ {
+ type new_node(new node_type(e));
+ value = type(new node_type(value, new_node));
+ }
+
+ void push_front(Edge e)
+ {
+ type new_node(new node_type(e));
+ value = type(new node_type(new_node, value));
+ }
+
+ void reverse()
+ {
+ value->m_reversed = !value->m_reversed;
+ }
+
+ void concat_front(edge_list_storage<recursive_lazy_list, Edge> other)
+ {
+ value = type(new node_type(other.value, value));
+ }
+
+ void concat_back(edge_list_storage<recursive_lazy_list, Edge> other)
+ {
+ value = type(new node_type(value, other.value));
+ }
+
+ template <typename OutputIterator>
+ void get_list(OutputIterator out)
+ {
+ get_list_helper(out, value);
+ }
+
+ private:
+
+ template <typename OutputIterator>
+ void get_list_helper(OutputIterator o_itr,
+ type root,
+ bool flipped = false
+ )
+ {
+ if (!root)
+ return;
+
+ if (root->m_has_data)
+ *o_itr = root->m_data;
+
+ if ((flipped && !root->m_reversed) ||
+ (!flipped && root->m_reversed)
+ )
+ {
+ get_list_helper(o_itr, root->m_right_child, true);
+ get_list_helper(o_itr, root->m_left_child, true);
+ }
+ else
+ {
+ get_list_helper(o_itr, root->m_left_child, false);
+ get_list_helper(o_itr, root->m_right_child, false);
+ }
+
+ }
+
+ };
+
+
+
+
+
+ template <typename Edge>
+ struct edge_list_storage<std_list, Edge>
+ {
+ typedef std::list<Edge> type;
+ type value;
+
+ void push_back(Edge e)
+ {
+ value.push_back(e);
+ }
+
+ void push_front(Edge e)
+ {
+ value.push_front(e);
+ }
+
+ void reverse()
+ {
+ value.reverse();
+ }
+
+ void concat_front(edge_list_storage<std_list,Edge> other)
+ {
+ value.splice(value.begin(), other.value);
+ }
+
+ void concat_back(edge_list_storage<std_list, Edge> other)
+ {
+ value.splice(value.end(), other.value);
+ }
+
+ template <typename OutputIterator>
+ void get_list(OutputIterator out)
+ {
+ std::copy(value.begin(), value.end(), out);
+ }
+
+ };
+
+
+
+
+
+
+
+ template<typename Graph,
+ typename StoreOldHandlesPolicy,
+ typename StoreEmbeddingPolicy
+ >
+ struct face_handle_impl
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ typedef typename edge_list_storage<StoreEmbeddingPolicy, edge_t>::type
+ edge_list_storage_t;
+
+
+ face_handle_impl() :
+ cached_first_vertex(graph_traits<Graph>::null_vertex()),
+ cached_second_vertex(graph_traits<Graph>::null_vertex()),
+ true_first_vertex(graph_traits<Graph>::null_vertex()),
+ true_second_vertex(graph_traits<Graph>::null_vertex()),
+ anchor(graph_traits<Graph>::null_vertex())
+ {
+ initialize_old_vertices_dispatch(StoreOldHandlesPolicy());
+ }
+
+ void initialize_old_vertices_dispatch(store_old_handles)
+ {
+ old_handles.first_vertex = graph_traits<Graph>::null_vertex();
+ old_handles.second_vertex = graph_traits<Graph>::null_vertex();
+ }
+
+ void initialize_old_vertices_dispatch(no_old_handles) {}
+
+ vertex_t cached_first_vertex;
+ vertex_t cached_second_vertex;
+ vertex_t true_first_vertex;
+ vertex_t true_second_vertex;
+ vertex_t anchor;
+ edge_t cached_first_edge;
+ edge_t cached_second_edge;
+
+ edge_list_storage<StoreEmbeddingPolicy, edge_t> edge_list;
+ old_handles_storage<StoreOldHandlesPolicy, vertex_t, edge_t> old_handles;
+
+ };
+
+
+
+
+
+
+
+
+
+
+
+ template <typename Graph,
+ typename StoreOldHandlesPolicy = store_old_handles,
+ typename StoreEmbeddingPolicy = recursive_lazy_list
+ >
+ class face_handle
+ {
+ public:
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ typedef face_handle_impl
+ <Graph, StoreOldHandlesPolicy, StoreEmbeddingPolicy> impl_t;
+ typedef face_handle
+ <Graph, StoreOldHandlesPolicy, StoreEmbeddingPolicy> self_t;
+
+ face_handle(vertex_t anchor = graph_traits<Graph>::null_vertex()) :
+ pimpl(new impl_t())
+ {
+ pimpl->anchor = anchor;
+ }
+
+ face_handle(vertex_t anchor, edge_t initial_edge, const Graph& g) :
+ pimpl(new impl_t())
+ {
+ vertex_t s(source(initial_edge,g));
+ vertex_t t(target(initial_edge,g));
+ vertex_t other_vertex = s == anchor ? t : s;
+ pimpl->anchor = anchor;
+ pimpl->cached_first_edge = initial_edge;
+ pimpl->cached_second_edge = initial_edge;
+ pimpl->cached_first_vertex = other_vertex;
+ pimpl->cached_second_vertex = other_vertex;
+ pimpl->true_first_vertex = other_vertex;
+ pimpl->true_second_vertex = other_vertex;
+
+ pimpl->edge_list.push_back(initial_edge);
+ store_old_face_handles_dispatch(StoreOldHandlesPolicy());
+ }
+
+ //default copy construction, assignment okay.
+
+ void push_first(edge_t e, const Graph& g)
+ {
+ pimpl->edge_list.push_front(e);
+ pimpl->cached_first_vertex = pimpl->true_first_vertex =
+ source(e, g) == pimpl->anchor ? target(e,g) : source(e,g);
+ pimpl->cached_first_edge = e;
+ }
+
+ void push_second(edge_t e, const Graph& g)
+ {
+ pimpl->edge_list.push_back(e);
+ pimpl->cached_second_vertex = pimpl->true_second_vertex =
+ source(e, g) == pimpl->anchor ? target(e,g) : source(e,g);
+ pimpl->cached_second_edge = e;
+ }
+
+ inline void store_old_face_handles()
+ {
+ store_old_face_handles_dispatch(StoreOldHandlesPolicy());
+ }
+
+ inline vertex_t first_vertex() const
+ {
+ return pimpl->cached_first_vertex;
+ }
+
+ inline vertex_t second_vertex() const
+ {
+ return pimpl->cached_second_vertex;
+ }
+
+ inline vertex_t true_first_vertex() const
+ {
+ return pimpl->true_first_vertex;
+ }
+
+ inline vertex_t true_second_vertex() const
+ {
+ return pimpl->true_second_vertex;
+ }
+
+ inline vertex_t old_first_vertex() const
+ {
+ return pimpl->old_handles.first_vertex;
+ }
+
+ inline vertex_t old_second_vertex() const
+ {
+ return pimpl->old_handles.second_vertex;
+ }
+
+ inline edge_t old_first_edge() const
+ {
+ return pimpl->old_handles.first_edge;
+ }
+
+ inline edge_t old_second_edge() const
+ {
+ return pimpl->old_handles.second_edge;
+ }
+
+ inline edge_t first_edge() const
+ {
+ return pimpl->cached_first_edge;
+ }
+
+ inline edge_t second_edge() const
+ {
+ return pimpl->cached_second_edge;
+ }
+
+ inline vertex_t get_anchor() const
+ {
+ return pimpl->anchor;
+ }
+
+ void glue_first_to_second
+ (face_handle<Graph,StoreOldHandlesPolicy,StoreEmbeddingPolicy>& bottom)
+ {
+ pimpl->edge_list.concat_front(bottom.pimpl->edge_list);
+ pimpl->true_first_vertex = bottom.pimpl->true_first_vertex;
+ pimpl->cached_first_vertex = bottom.pimpl->cached_first_vertex;
+ pimpl->cached_first_edge = bottom.pimpl->cached_first_edge;
+ }
+
+ void glue_second_to_first
+ (face_handle<Graph,StoreOldHandlesPolicy,StoreEmbeddingPolicy>& bottom)
+ {
+ pimpl->edge_list.concat_back(bottom.pimpl->edge_list);
+ pimpl->true_second_vertex = bottom.pimpl->true_second_vertex;
+ pimpl->cached_second_vertex = bottom.pimpl->cached_second_vertex;
+ pimpl->cached_second_edge = bottom.pimpl->cached_second_edge;
+ }
+
+ void flip()
+ {
+ pimpl->edge_list.reverse();
+ std::swap(pimpl->true_first_vertex, pimpl->true_second_vertex);
+ std::swap(pimpl->cached_first_vertex, pimpl->cached_second_vertex);
+ std::swap(pimpl->cached_first_edge, pimpl->cached_second_edge);
+ }
+
+ template <typename OutputIterator>
+ void get_list(OutputIterator o_itr)
+ {
+ pimpl->edge_list.get_list(o_itr);
+ }
+
+ void reset_vertex_cache()
+ {
+ pimpl->cached_first_vertex = pimpl->true_first_vertex;
+ pimpl->cached_second_vertex = pimpl->true_second_vertex;
+ }
+
+ inline void set_first_vertex(vertex_t v)
+ {
+ pimpl->cached_first_vertex = v;
+ }
+
+ inline void set_second_vertex(vertex_t v)
+ {
+ pimpl->cached_second_vertex = v;
+ }
+
+ private:
+
+ void store_old_face_handles_dispatch(store_old_handles)
+ {
+ pimpl->old_handles.first_vertex = pimpl->true_first_vertex;
+ pimpl->old_handles.second_vertex = pimpl->true_second_vertex;
+ pimpl->old_handles.first_edge = pimpl->cached_first_edge;
+ pimpl->old_handles.second_edge = pimpl->cached_second_edge;
+ }
+
+ void store_old_face_handles_dispatch(no_old_handles) {}
+
+
+
+ boost::shared_ptr<impl_t> pimpl;
+
+ };
+
+
+} /* namespace detail */ } /* namespace graph */ } /* namespace boost */
+
+
+#endif //__FACE_HANDLES_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/planar_detail/face_iterators.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/planar_detail/face_iterators.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,375 @@
+//=======================================================================
+// Copyright (c) Aaron Windsor 2007
+//
+// 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)
+//=======================================================================
+
+#ifndef __FACE_ITERATORS_HPP__
+#define __FACE_ITERATORS_HPP__
+
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/graph/graph_traits.hpp>
+
+namespace boost
+{
+
+ //tags for defining traversal properties
+
+ //VisitorType
+ struct lead_visitor {};
+ struct follow_visitor {};
+
+ //TraversalType
+ struct single_side {};
+ struct both_sides {};
+
+ //TraversalSubType
+ struct first_side {}; //for single_side
+ struct second_side {}; //for single_side
+ struct alternating {}; //for both_sides
+
+ //Time
+ struct current_iteration {};
+ struct previous_iteration {};
+
+ // Why TraversalType AND TraversalSubType? TraversalSubType is a function
+ // template parameter passed in to the constructor of the face iterator,
+ // whereas TraversalType is a class template parameter. This lets us decide
+ // at runtime whether to move along the first or second side of a bicomp (by
+ // assigning a face_iterator that has been constructed with TraversalSubType
+ // = first_side or second_side to a face_iterator variable) without any of
+ // the virtual function overhead that comes with implementing this
+ // functionality as a more structured form of type erasure. It also allows
+ // a single face_iterator to be the end iterator of two iterators traversing
+ // both sides of a bicomp.
+
+ //ValueType is either graph_traits<Graph>::vertex_descriptor
+ //or graph_traits<Graph>::edge_descriptor
+
+
+ //forward declaration (defining defaults)
+ template <typename Graph,
+ typename FaceHandlesMap,
+ typename ValueType,
+ typename BicompSideToTraverse = single_side,
+ typename VisitorType = lead_visitor,
+ typename Time = current_iteration
+ >
+ class face_iterator;
+
+
+
+ template <typename Graph, bool StoreEdge>
+ struct edge_storage
+ {};
+
+ template <typename Graph>
+ struct edge_storage <Graph, true>
+ {
+ typename graph_traits<Graph>::edge_descriptor value;
+ };
+
+
+
+
+ //specialization for TraversalType = traverse_vertices
+ template <typename Graph,
+ typename FaceHandlesMap,
+ typename ValueType,
+ typename TraversalType,
+ typename VisitorType,
+ typename Time
+ >
+
+ class face_iterator
+ : public boost::iterator_facade < face_iterator<Graph,
+ FaceHandlesMap,
+ ValueType,
+ TraversalType,
+ VisitorType,
+ Time
+ >,
+ ValueType,
+ boost::forward_traversal_tag,
+ ValueType
+ >
+ {
+ public:
+
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ typedef face_iterator
+ <Graph,FaceHandlesMap,ValueType,TraversalType,VisitorType,Time> self;
+ typedef typename FaceHandlesMap::value_type face_handle_t;
+
+ face_iterator() :
+ m_lead(graph_traits<Graph>::null_vertex()),
+ m_follow(graph_traits<Graph>::null_vertex())
+ {}
+
+ template <typename TraversalSubType>
+ face_iterator(face_handle_t anchor_handle,
+ FaceHandlesMap face_handles,
+ TraversalSubType traversal_type):
+ m_follow(anchor_handle.get_anchor()),
+ m_face_handles(face_handles)
+ {
+ set_lead_dispatch(anchor_handle, traversal_type);
+ }
+
+ template <typename TraversalSubType>
+ face_iterator(vertex_t anchor,
+ FaceHandlesMap face_handles,
+ TraversalSubType traversal_type):
+ m_follow(anchor),
+ m_face_handles(face_handles)
+ {
+ set_lead_dispatch(m_face_handles[anchor], traversal_type);
+ }
+
+ private:
+
+ friend class boost::iterator_core_access;
+
+
+
+
+ inline vertex_t get_first_vertex(face_handle_t anchor_handle,
+ current_iteration
+ )
+ {
+ return anchor_handle.first_vertex();
+ }
+
+ inline vertex_t get_second_vertex(face_handle_t anchor_handle,
+ current_iteration
+ )
+ {
+ return anchor_handle.second_vertex();
+ }
+
+ inline vertex_t get_first_vertex(face_handle_t anchor_handle,
+ previous_iteration
+ )
+ {
+ return anchor_handle.old_first_vertex();
+ }
+
+ inline vertex_t get_second_vertex(face_handle_t anchor_handle,
+ previous_iteration
+ )
+ {
+ return anchor_handle.old_second_vertex();
+ }
+
+
+
+
+
+ inline void set_lead_dispatch(face_handle_t anchor_handle, first_side)
+ {
+ m_lead = get_first_vertex(anchor_handle, Time());
+ set_edge_to_first_dispatch(anchor_handle, ValueType(), Time());
+ }
+
+ inline void set_lead_dispatch(face_handle_t anchor_handle, second_side)
+ {
+ m_lead = get_second_vertex(anchor_handle, Time());
+ set_edge_to_second_dispatch(anchor_handle, ValueType(), Time());
+ }
+
+
+
+
+
+ inline void set_edge_to_first_dispatch(face_handle_t anchor_handle,
+ edge_t,
+ current_iteration
+ )
+ {
+ m_edge.value = anchor_handle.first_edge();
+ }
+
+ inline void set_edge_to_second_dispatch(face_handle_t anchor_handle,
+ edge_t,
+ current_iteration
+ )
+ {
+ m_edge.value = anchor_handle.second_edge();
+ }
+
+ inline void set_edge_to_first_dispatch(face_handle_t anchor_handle,
+ edge_t,
+ previous_iteration
+ )
+ {
+ m_edge.value = anchor_handle.old_first_edge();
+ }
+
+ inline void set_edge_to_second_dispatch(face_handle_t anchor_handle,
+ edge_t,
+ previous_iteration
+ )
+ {
+ m_edge.value = anchor_handle.old_second_edge();
+ }
+
+ template<typename T>
+ inline void set_edge_to_first_dispatch(face_handle_t, vertex_t, T)
+ {}
+
+ template<typename T>
+ inline void set_edge_to_second_dispatch(face_handle_t, vertex_t, T)
+ {}
+
+ void increment()
+ {
+ face_handle_t curr_face_handle(m_face_handles[m_lead]);
+ vertex_t first = get_first_vertex(curr_face_handle, Time());
+ vertex_t second = get_second_vertex(curr_face_handle, Time());
+ if (first == m_follow)
+ {
+ m_follow = m_lead;
+ set_edge_to_second_dispatch(curr_face_handle, ValueType(), Time());
+ m_lead = second;
+ }
+ else if (second == m_follow)
+ {
+ m_follow = m_lead;
+ set_edge_to_first_dispatch(curr_face_handle, ValueType(), Time());
+ m_lead = first;
+ }
+ else
+ m_lead = m_follow = graph_traits<Graph>::null_vertex();
+ }
+
+ bool equal(self const& other) const
+ {
+ return m_lead == other.m_lead && m_follow == other.m_follow;
+ }
+
+ ValueType dereference() const
+ {
+ return dereference_dispatch(VisitorType(), ValueType());
+ }
+
+ inline ValueType dereference_dispatch(lead_visitor, vertex_t) const
+ { return m_lead; }
+
+ inline ValueType dereference_dispatch(follow_visitor, vertex_t) const
+ { return m_follow; }
+
+ inline ValueType dereference_dispatch(lead_visitor, edge_t) const
+ { return m_edge.value; }
+
+ inline ValueType dereference_dispatch(follow_visitor, edge_t) const
+ { return m_edge.value; }
+
+ vertex_t m_lead;
+ vertex_t m_follow;
+ edge_storage<Graph, boost::is_same<ValueType, edge_t>::value > m_edge;
+ FaceHandlesMap m_face_handles;
+ };
+
+
+
+
+
+
+
+
+
+ template <typename Graph,
+ typename FaceHandlesMap,
+ typename ValueType,
+ typename VisitorType,
+ typename Time
+ >
+ class face_iterator
+ <Graph, FaceHandlesMap, ValueType, both_sides, VisitorType, Time>
+ : public boost::iterator_facade< face_iterator<Graph,
+ FaceHandlesMap,
+ ValueType,
+ both_sides,
+ VisitorType,
+ Time>,
+ ValueType,
+ boost::forward_traversal_tag,
+ ValueType >
+ {
+ public:
+
+ typedef face_iterator
+ <Graph,FaceHandlesMap,ValueType,both_sides,VisitorType,Time> self;
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename FaceHandlesMap::value_type face_handle_t;
+
+ face_iterator() {}
+
+ face_iterator(face_handle_t anchor_handle, FaceHandlesMap face_handles):
+ first_itr(anchor_handle, face_handles, first_side()),
+ second_itr(anchor_handle, face_handles, second_side()),
+ first_is_active(true),
+ first_increment(true)
+ {}
+
+ face_iterator(vertex_t anchor, FaceHandlesMap face_handles):
+ first_itr(face_handles[anchor], face_handles, first_side()),
+ second_itr(face_handles[anchor], face_handles, second_side()),
+ first_is_active(true),
+ first_increment(true)
+ {}
+
+ private:
+
+ friend class boost::iterator_core_access;
+
+ typedef face_iterator
+ <Graph, FaceHandlesMap, ValueType, single_side, follow_visitor, Time>
+ inner_itr_t;
+
+ void increment()
+ {
+ if (first_increment)
+ {
+ ++first_itr;
+ ++second_itr;
+ first_increment = false;
+ }
+ else if (first_is_active)
+ ++first_itr;
+ else
+ ++second_itr;
+ first_is_active = !first_is_active;
+ }
+
+ bool equal(self const& other) const
+ {
+ //Want this iterator to be equal to the "end" iterator when at least
+ //one of the iterators has reached the root of the current bicomp.
+ //This isn't ideal, but it works.
+
+ return (first_itr == other.first_itr || second_itr == other.second_itr);
+ }
+
+ ValueType dereference() const
+ {
+ return first_is_active ? *first_itr : *second_itr;
+ }
+
+ inner_itr_t first_itr;
+ inner_itr_t second_itr;
+ inner_itr_t face_end;
+ bool first_is_active;
+ bool first_increment;
+
+ };
+
+
+} /* namespace boost */
+
+
+#endif //__FACE_ITERATORS_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/planar_face_traversal.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/planar_face_traversal.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,210 @@
+//=======================================================================
+// Copyright (c) Aaron Windsor 2007
+//
+// 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)
+//=======================================================================
+
+#ifndef __PLANAR_FACE_TRAVERSAL_HPP__
+#define __PLANAR_FACE_TRAVERSAL_HPP__
+
+#include <vector>
+#include <boost/utility.hpp> //for next and prior
+#include <boost/graph/graph_traits.hpp>
+
+
+namespace boost
+{
+
+
+
+
+ struct planar_face_traversal_visitor
+ {
+ void begin_traversal()
+ {}
+
+ void begin_face()
+ {}
+
+ template <typename Edge>
+ void next_edge(Edge e)
+ {}
+
+ template <typename Vertex>
+ void next_vertex(Vertex v)
+ {}
+
+ void end_face()
+ {}
+
+ void end_traversal()
+ {}
+
+ };
+
+
+
+
+
+ template<typename Graph,
+ typename PlanarEmbedding,
+ typename Visitor,
+ typename EdgeIndexMap>
+ void planar_face_traversal(const Graph& g,
+ PlanarEmbedding embedding,
+ Visitor& visitor, EdgeIndexMap em
+ )
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_t;
+ typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
+ typedef typename graph_traits<Graph>::edge_iterator edge_iterator_t;
+ typedef typename
+ property_traits<PlanarEmbedding>::value_type embedding_value_t;
+ typedef typename embedding_value_t::const_iterator embedding_iterator_t;
+
+ typedef typename
+ std::vector< std::set<vertex_t> > distinguished_edge_storage_t;
+ typedef typename
+ std::vector< std::map<vertex_t, edge_t> >
+ distinguished_edge_to_edge_storage_t;
+
+ typedef typename
+ boost::iterator_property_map
+ <typename distinguished_edge_storage_t::iterator, EdgeIndexMap>
+ distinguished_edge_map_t;
+
+ typedef typename
+ boost::iterator_property_map
+ <typename distinguished_edge_to_edge_storage_t::iterator, EdgeIndexMap>
+ distinguished_edge_to_edge_map_t;
+
+ distinguished_edge_storage_t visited_vector(num_edges(g));
+ distinguished_edge_to_edge_storage_t next_edge_vector(num_edges(g));
+
+ distinguished_edge_map_t visited(visited_vector.begin(), em);
+ distinguished_edge_to_edge_map_t next_edge(next_edge_vector.begin(), em);
+
+ vertex_iterator_t vi, vi_end;
+ typename std::vector<edge_t>::iterator ei, ei_end;
+ edge_iterator_t fi, fi_end;
+ embedding_iterator_t pi, pi_begin, pi_end;
+
+ visitor.begin_traversal();
+
+ // Initialize the next_edge property map. This map is initialized from the
+ // PlanarEmbedding so that get(next_edge, e)[v] is the edge that comes
+ // after e in the clockwise embedding around vertex v.
+
+ for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
+ {
+ vertex_t v(*vi);
+ pi_begin = embedding[v].begin();
+ pi_end = embedding[v].end();
+ for(pi = pi_begin; pi != pi_end; ++pi)
+ {
+ edge_t e(*pi);
+ std::map<vertex_t, edge_t> m = get(next_edge, e);
+ m[v] = next(pi) == pi_end ? *pi_begin : *next(pi);
+ put(next_edge, e, m);
+ }
+ }
+
+ // Take a copy of the edges in the graph here, since we want to accomodate
+ // face traversals that add edges to the graph (for triangulation, in
+ // particular) and don't want to use invalidated edge iterators.
+ // Also, while iterating over all edges in the graph, we single out
+ // any self-loops, which need some special treatment in the face traversal.
+
+ std::vector<edge_t> self_loops;
+ std::vector<edge_t> edges_cache;
+ std::vector<vertex_t> vertices_in_edge;
+
+ for(tie(fi,fi_end) = edges(g); fi != fi_end; ++fi)
+ {
+ edge_t e(*fi);
+ edges_cache.push_back(e);
+ if (source(e,g) == target(e,g))
+ self_loops.push_back(e);
+ }
+
+
+ // Iterate over all edges in the graph
+ ei_end = edges_cache.end();
+ for(ei = edges_cache.begin(); ei != ei_end; ++ei)
+ {
+
+ edge_t e(*ei);
+ vertices_in_edge.clear();
+ vertices_in_edge.push_back(source(e,g));
+ vertices_in_edge.push_back(target(e,g));
+
+ typename std::vector<vertex_t>::iterator vi, vi_end;
+ vi_end = vertices_in_edge.end();
+
+ //Iterate over both vertices in the current edge
+ for(vi = vertices_in_edge.begin(); vi != vi_end; ++vi)
+ {
+
+ vertex_t v(*vi);
+ std::set<vertex_t> e_visited = get(visited, e);
+ typename std::set<vertex_t>::iterator e_visited_found
+ = e_visited.find(v);
+
+ if (e_visited_found == e_visited.end())
+ visitor.begin_face();
+
+ while (e_visited.find(v) == e_visited.end())
+ {
+ visitor.next_vertex(v);
+ visitor.next_edge(e);
+ e_visited.insert(v);
+ put(visited, e, e_visited);
+ v = source(e,g) == v ? target(e,g) : source(e,g);
+ e = get(next_edge, e)[v];
+ e_visited = get(visited, e);
+ }
+
+ if (e_visited_found == e_visited.end())
+ visitor.end_face();
+
+ }
+
+ }
+
+ // Iterate over all self-loops, visiting them once separately
+ // (they've already been visited once, this visitation is for
+ // the "inside" of the self-loop)
+
+ ei_end = self_loops.end();
+ for(ei = self_loops.begin(); ei != ei_end; ++ei)
+ {
+ visitor.begin_face();
+ visitor.next_edge(*ei);
+ visitor.next_vertex(source(*ei,g));
+ visitor.end_face();
+ }
+
+ visitor.end_traversal();
+
+ }
+
+
+
+ template<typename Graph, typename PlanarEmbedding, typename Visitor>
+ inline void planar_face_traversal(const Graph& g,
+ PlanarEmbedding embedding,
+ Visitor& visitor
+ )
+ {
+ planar_face_traversal(g, embedding, visitor, get(edge_index, g));
+ }
+
+
+
+
+} //namespace boost
+
+#endif //__PLANAR_FACE_TRAVERSAL_HPP__
Added: branches/CMake/release/libs/graph/include/boost/graph/plod_generator.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/plod_generator.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,161 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// 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)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_PLOD_GENERATOR_HPP
+#define BOOST_GRAPH_PLOD_GENERATOR_HPP
+
+#include <iterator>
+#include <utility>
+#include <boost/random/uniform_int.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <vector>
+#include <map>
+#include <cmath>
+
+namespace boost {
+
+ template<typename RandomGenerator, typename Graph>
+ class plod_iterator
+ {
+ typedef std::vector<std::pair<std::size_t, std::size_t> > out_degrees_t;
+ typedef typename graph_traits<Graph>::directed_category directed_category;
+
+ public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair<std::size_t, std::size_t> value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef void difference_type;
+
+ plod_iterator()
+ : gen(0), out_degrees(), degrees_left(0), allow_self_loops(false) { }
+
+ plod_iterator(RandomGenerator& gen, std::size_t n,
+ double alpha, double beta, bool allow_self_loops = false)
+ : gen(&gen), n(n), out_degrees(new out_degrees_t),
+ degrees_left(0), allow_self_loops(allow_self_loops)
+ {
+ using std::pow;
+
+ uniform_int<std::size_t> x(0, n-1);
+ for (std::size_t i = 0; i != n; ++i) {
+ std::size_t xv = x(gen);
+ std::size_t degree = (xv == 0? 0 : std::size_t(beta * pow(xv, -alpha)));
+ if (degree != 0) {
+ out_degrees->push_back(std::make_pair(i, degree));
+ }
+ degrees_left += degree;
+ }
+
+ next(directed_category());
+ }
+
+ reference operator*() const { return current; }
+ pointer operator->() const { return ¤t; }
+
+ plod_iterator& operator++()
+ {
+ next(directed_category());
+ return *this;
+ }
+
+ plod_iterator operator++(int)
+ {
+ plod_iterator temp(*this);
+ ++(*this);
+ return temp;
+ }
+
+ bool operator==(const plod_iterator& other) const
+ {
+ return degrees_left == other.degrees_left;
+ }
+
+ bool operator!=(const plod_iterator& other) const
+ { return !(*this == other); }
+
+ private:
+ void next(directed_tag)
+ {
+ uniform_int<std::size_t> x(0, out_degrees->size()-1);
+ std::size_t source;
+ do {
+ source = x(*gen);
+ } while ((*out_degrees)[source].second == 0);
+ current.first = (*out_degrees)[source].first;
+ do {
+ current.second = x(*gen);
+ } while (current.first == current.second && !allow_self_loops);
+ --degrees_left;
+ if (--(*out_degrees)[source].second == 0) {
+ (*out_degrees)[source] = out_degrees->back();
+ out_degrees->pop_back();
+ }
+ }
+
+ void next(undirected_tag)
+ {
+ std::size_t source, target;
+ while (true) {
+ /* We may get to the point where we can't actually find any
+ new edges, so we just add some random edge and set the
+ degrees left = 0 to signal termination. */
+ if (out_degrees->size() < 2) {
+ uniform_int<std::size_t> x(0, n);
+ current.first = x(*gen);
+ do {
+ current.second = x(*gen);
+ } while (current.first == current.second && !allow_self_loops);
+ degrees_left = 0;
+ out_degrees->clear();
+ return;
+ }
+
+ uniform_int<std::size_t> x(0, out_degrees->size()-1);
+
+ // Select source vertex
+ source = x(*gen);
+ if ((*out_degrees)[source].second == 0) {
+ (*out_degrees)[source] = out_degrees->back();
+ out_degrees->pop_back();
+ continue;
+ }
+
+ // Select target vertex
+ target = x(*gen);
+ if ((*out_degrees)[target].second == 0) {
+ (*out_degrees)[target] = out_degrees->back();
+ out_degrees->pop_back();
+ continue;
+ } else if (source != target
+ || (allow_self_loops && (*out_degrees)[source].second > 2)) {
+ break;
+ }
+ }
+
+ // Update degree counts
+ --(*out_degrees)[source].second;
+ --degrees_left;
+ --(*out_degrees)[target].second;
+ --degrees_left;
+ current.first = (*out_degrees)[source].first;
+ current.second = (*out_degrees)[target].first;
+ }
+
+ RandomGenerator* gen;
+ std::size_t n;
+ shared_ptr<out_degrees_t> out_degrees;
+ std::size_t degrees_left;
+ bool allow_self_loops;
+ value_type current;
+ };
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_PLOD_GENERATOR_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/prim_minimum_spanning_tree.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/prim_minimum_spanning_tree.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,91 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_MST_PRIM_HPP
+#define BOOST_GRAPH_MST_PRIM_HPP
+
+#include <functional>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+
+namespace boost {
+
+ namespace detail {
+ // this should be somewhere else in boost...
+ template <class U, class V> struct _project2nd {
+ V operator()(U, V v) const { return v; }
+ };
+ }
+
+ namespace detail {
+
+ // This is Prim's algorithm to calculate the Minimum Spanning Tree
+ // for an undirected graph with weighted edges.
+
+ template <class Graph, class P, class T, class R, class Weight>
+ inline void
+ prim_mst_impl(const Graph& G,
+ typename graph_traits<Graph>::vertex_descriptor s,
+ const bgl_named_params<P,T,R>& params,
+ Weight)
+ {
+ typedef typename property_traits<Weight>::value_type W;
+ std::less<W> compare;
+ detail::_project2nd<W,W> combine;
+ dijkstra_shortest_paths(G, s, params.distance_compare(compare).
+ distance_combine(combine));
+ }
+ } // namespace detail
+
+ template <class VertexListGraph, class DijkstraVisitor,
+ class PredecessorMap, class DistanceMap,
+ class WeightMap, class IndexMap>
+ inline void
+ prim_minimum_spanning_tree
+ (const VertexListGraph& g,
+ typename graph_traits<VertexListGraph>::vertex_descriptor s,
+ PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
+ IndexMap index_map,
+ DijkstraVisitor vis)
+ {
+ typedef typename property_traits<WeightMap>::value_type W;
+ std::less<W> compare;
+ detail::_project2nd<W,W> combine;
+ dijkstra_shortest_paths(g, s, predecessor, distance, weight, index_map,
+ compare, combine, (std::numeric_limits<W>::max)(), 0,
+ vis);
+ }
+
+ template <class VertexListGraph, class PredecessorMap,
+ class P, class T, class R>
+ inline void prim_minimum_spanning_tree
+ (const VertexListGraph& g,
+ PredecessorMap p_map,
+ const bgl_named_params<P,T,R>& params)
+ {
+ detail::prim_mst_impl
+ (g,
+ choose_param(get_param(params, root_vertex_t()), *vertices(g).first),
+ params.predecessor_map(p_map),
+ choose_const_pmap(get_param(params, edge_weight), g, edge_weight));
+ }
+
+ template <class VertexListGraph, class PredecessorMap>
+ inline void prim_minimum_spanning_tree
+ (const VertexListGraph& g, PredecessorMap p_map)
+ {
+ detail::prim_mst_impl
+ (g, *vertices(g).first, predecessor_map(p_map).
+ weight_map(get(edge_weight, g)),
+ get(edge_weight, g));
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_MST_PRIM_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/profile.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/profile.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,43 @@
+//
+//=======================================================================
+// Copyright 2002 Marc Wintermantel (wintermantel_at_[hidden])
+// ETH Zurich, Center of Structure Technologies (www.imes.ethz.ch/st)
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_GRAPH_PROFILE_HPP
+#define BOOST_GRAPH_PROFILE_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/detail/numeric_traits.hpp>
+#include <boost/graph/bandwidth.hpp>
+
+namespace boost {
+
+ template <typename Graph, typename VertexIndexMap>
+ typename graph_traits<Graph>::vertices_size_type
+ profile(const Graph& g, VertexIndexMap index)
+ {
+ typename graph_traits<Graph>::vertices_size_type b = 0;
+ typename graph_traits<Graph>::vertex_iterator i, end;
+ for (tie(i, end) = vertices(g); i != end; ++i){
+ b += ith_bandwidth(*i, g, index) + 1;
+ }
+
+ return b;
+ }
+
+ template <typename Graph>
+ typename graph_traits<Graph>::vertices_size_type
+ profile(const Graph& g)
+ {
+ return profile(g, get(vertex_index, g));
+ }
+
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_PROFILE_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/properties.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/properties.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,389 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_GRAPH_PROPERTIES_HPP
+#define BOOST_GRAPH_PROPERTIES_HPP
+
+#include <boost/config.hpp>
+#include <cassert>
+#include <boost/pending/property.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+// Stay out of the way of the concept checking class
+# define Graph Graph_
+# define RandomAccessContainer RandomAccessContainer_
+#endif
+
+namespace boost {
+
+ enum default_color_type { white_color, gray_color, green_color, red_color, black_color };
+
+ template <class ColorValue>
+ struct color_traits {
+ static default_color_type white() { return white_color; }
+ static default_color_type gray() { return gray_color; }
+ static default_color_type green() { return green_color; }
+ static default_color_type red() { return red_color; }
+ static default_color_type black() { return black_color; }
+ };
+
+ // These functions are now obsolete, replaced by color_traits.
+ inline default_color_type white(default_color_type) { return white_color; }
+ inline default_color_type gray(default_color_type) { return gray_color; }
+ inline default_color_type green(default_color_type) { return green_color; }
+ inline default_color_type red(default_color_type) { return red_color; }
+ inline default_color_type black(default_color_type) { return black_color; }
+
+#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ template <>
+ struct property_traits<default_color_type*> {
+ typedef default_color_type value_type;
+ typedef std::ptrdiff_t key_type;
+ typedef default_color_type& reference;
+ typedef lvalue_property_map_tag category;
+ };
+ // get/put already defined for T*
+#endif
+
+ struct graph_property_tag { };
+ struct vertex_property_tag { };
+ struct edge_property_tag { };
+
+#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ // See examples/edge_property.cpp for how to use this.
+#define BOOST_INSTALL_PROPERTY(KIND, NAME) \
+ template <> struct property_kind<KIND##_##NAME##_t> { \
+ typedef KIND##_property_tag type; \
+ }
+#else
+#define BOOST_INSTALL_PROPERTY(KIND, NAME) \
+ template <> struct property_kind<KIND##_##NAME##_t> { \
+ typedef KIND##_property_tag type; \
+ }
+#endif
+
+#define BOOST_DEF_PROPERTY(KIND, NAME) \
+ enum KIND##_##NAME##_t { KIND##_##NAME }; \
+ BOOST_INSTALL_PROPERTY(KIND, NAME)
+
+ BOOST_DEF_PROPERTY(vertex, all);
+ BOOST_DEF_PROPERTY(edge, all);
+ BOOST_DEF_PROPERTY(graph, all);
+ BOOST_DEF_PROPERTY(vertex, index);
+ BOOST_DEF_PROPERTY(vertex, index1);
+ BOOST_DEF_PROPERTY(vertex, index2);
+ BOOST_DEF_PROPERTY(vertex, root);
+ BOOST_DEF_PROPERTY(edge, index);
+ BOOST_DEF_PROPERTY(edge, name);
+ BOOST_DEF_PROPERTY(edge, weight);
+ BOOST_DEF_PROPERTY(edge, weight2);
+ BOOST_DEF_PROPERTY(edge, color);
+ BOOST_DEF_PROPERTY(vertex, name);
+ BOOST_DEF_PROPERTY(graph, name);
+ BOOST_DEF_PROPERTY(vertex, distance);
+ BOOST_DEF_PROPERTY(vertex, color);
+ BOOST_DEF_PROPERTY(vertex, degree);
+ BOOST_DEF_PROPERTY(vertex, in_degree);
+ BOOST_DEF_PROPERTY(vertex, out_degree);
+ BOOST_DEF_PROPERTY(vertex, current_degree);
+ BOOST_DEF_PROPERTY(vertex, priority);
+ BOOST_DEF_PROPERTY(vertex, discover_time);
+ BOOST_DEF_PROPERTY(vertex, finish_time);
+ BOOST_DEF_PROPERTY(vertex, predecessor);
+ BOOST_DEF_PROPERTY(vertex, rank);
+ BOOST_DEF_PROPERTY(vertex, centrality);
+ BOOST_DEF_PROPERTY(vertex, lowpoint);
+ BOOST_DEF_PROPERTY(edge, reverse);
+ BOOST_DEF_PROPERTY(edge, capacity);
+ BOOST_DEF_PROPERTY(edge, residual_capacity);
+ BOOST_DEF_PROPERTY(edge, centrality);
+ BOOST_DEF_PROPERTY(graph, visitor);
+
+ // These tags are used for property bundles
+ BOOST_DEF_PROPERTY(vertex, bundle);
+ BOOST_DEF_PROPERTY(edge, bundle);
+
+#undef BOOST_DEF_PROPERTY
+
+ namespace detail {
+
+ struct dummy_edge_property_selector {
+ template <class Graph, class Property, class Tag>
+ struct bind_ {
+ typedef identity_property_map type;
+ typedef identity_property_map const_type;
+ };
+ };
+ struct dummy_vertex_property_selector {
+ template <class Graph, class Property, class Tag>
+ struct bind_ {
+ typedef identity_property_map type;
+ typedef identity_property_map const_type;
+ };
+ };
+
+ } // namespace detail
+
+ // Graph classes can either partially specialize property_map
+ // or they can specialize these two selector classes.
+ template <class GraphTag>
+ struct edge_property_selector {
+ typedef detail::dummy_edge_property_selector type;
+ };
+
+ template <class GraphTag>
+ struct vertex_property_selector {
+ typedef detail::dummy_vertex_property_selector type;
+ };
+
+ namespace detail {
+
+ template <class Graph, class PropertyTag>
+ struct edge_property_map {
+ typedef typename Graph::edge_property_type Property;
+ typedef typename Graph::graph_tag graph_tag;
+ typedef typename edge_property_selector<graph_tag>::type Selector;
+ typedef typename Selector::template bind_<Graph,Property,PropertyTag>
+ Bind;
+ typedef typename Bind::type type;
+ typedef typename Bind::const_type const_type;
+ };
+ template <class Graph, class PropertyTag>
+ class vertex_property_map {
+ typedef typename Graph::vertex_property_type Property;
+ typedef typename Graph::graph_tag graph_tag;
+ typedef typename vertex_property_selector<graph_tag>::type Selector;
+ typedef typename Selector::template bind_<Graph,Property,PropertyTag>
+ Bind;
+ public:
+ typedef typename Bind::type type;
+ typedef typename Bind::const_type const_type;
+ };
+
+ // This selects the kind of property map, whether is maps from
+ // edges or from vertices.
+ //
+ // It is overly complicated because it's a workaround for
+ // partial specialization.
+ struct choose_vertex_property_map {
+ template <class Graph, class Property>
+ struct bind_ {
+ typedef vertex_property_map<Graph, Property> type;
+ };
+ };
+ struct choose_edge_property_map {
+ template <class Graph, class Property>
+ struct bind_ {
+ typedef edge_property_map<Graph, Property> type;
+ };
+ };
+ template <class Kind>
+ struct property_map_kind_selector {
+ // VC++ gets confused if this isn't defined, even though
+ // this never gets used.
+ typedef choose_vertex_property_map type;
+ };
+ template <> struct property_map_kind_selector<vertex_property_tag> {
+ typedef choose_vertex_property_map type;
+ };
+ template <> struct property_map_kind_selector<edge_property_tag> {
+ typedef choose_edge_property_map type;
+ };
+ } // namespace detail
+
+ template <class Graph, class Property>
+ struct property_map {
+ private:
+ typedef typename property_kind<Property>::type Kind;
+ typedef typename detail::property_map_kind_selector<Kind>::type Selector;
+ typedef typename Selector::template bind_<Graph, Property> Bind;
+ typedef typename Bind::type Map;
+ public:
+ typedef typename Map::type type;
+ typedef typename Map::const_type const_type;
+ };
+
+ // shortcut for accessing the value type of the property map
+ template <class Graph, class Property>
+ class property_map_value {
+ typedef typename property_map<Graph, Property>::const_type PMap;
+ public:
+ typedef typename property_traits<PMap>::value_type type;
+ };
+
+ template <class Graph, class Property>
+ class graph_property {
+ public:
+ typedef typename property_value<typename Graph::graph_property_type,
+ Property>::type type;
+ };
+
+ template <class Graph>
+ class vertex_property {
+ public:
+ typedef typename Graph::vertex_property_type type;
+ };
+ template <class Graph>
+ class edge_property {
+ public:
+ typedef typename Graph::edge_property_type type;
+ };
+
+ template <typename Graph>
+ class degree_property_map
+ : public put_get_helper<typename graph_traits<Graph>::degree_size_type,
+ degree_property_map<Graph> >
+ {
+ public:
+ typedef typename graph_traits<Graph>::vertex_descriptor key_type;
+ typedef typename graph_traits<Graph>::degree_size_type value_type;
+ typedef value_type reference;
+ typedef readable_property_map_tag category;
+ degree_property_map(const Graph& g) : m_g(g) { }
+ value_type operator[](const key_type& v) const {
+ return degree(v, m_g);
+ }
+ private:
+ const Graph& m_g;
+ };
+ template <typename Graph>
+ inline degree_property_map<Graph>
+ make_degree_map(const Graph& g) {
+ return degree_property_map<Graph>(g);
+ }
+
+ //========================================================================
+ // Iterator Property Map Generating Functions contributed by
+ // Kevin Vanhorn. (see also the property map generating functions
+ // in boost/property_map.hpp)
+
+#if !defined(BOOST_NO_STD_ITERATOR_TRAITS)
+ // A helper function for creating a vertex property map out of a
+ // random access iterator and the internal vertex index map from a
+ // graph.
+ template <class PropertyGraph, class RandomAccessIterator>
+ inline
+ iterator_property_map<
+ RandomAccessIterator,
+ typename property_map<PropertyGraph, vertex_index_t>::type,
+ typename std::iterator_traits<RandomAccessIterator>::value_type,
+ typename std::iterator_traits<RandomAccessIterator>::reference
+ >
+ make_iterator_vertex_map(RandomAccessIterator iter, const PropertyGraph& g)
+ {
+ return make_iterator_property_map(iter, get(vertex_index, g));
+ }
+
+ // Use this next function when vertex_descriptor is known to be an
+ // integer type, with values ranging from 0 to num_vertices(g).
+ //
+ template <class RandomAccessIterator>
+ inline
+ iterator_property_map<
+ RandomAccessIterator,
+ identity_property_map,
+ typename std::iterator_traits<RandomAccessIterator>::value_type,
+ typename std::iterator_traits<RandomAccessIterator>::reference
+ >
+ make_iterator_vertex_map(RandomAccessIterator iter)
+ {
+ return make_iterator_property_map(iter, identity_property_map());
+ }
+#endif
+
+ template <class PropertyGraph, class RandomAccessContainer>
+ inline
+ iterator_property_map<
+ typename RandomAccessContainer::iterator,
+ typename property_map<PropertyGraph, vertex_index_t>::type,
+ typename RandomAccessContainer::value_type,
+ typename RandomAccessContainer::reference
+ >
+ make_container_vertex_map(RandomAccessContainer& c, const PropertyGraph& g)
+ {
+ assert(c.size() >= num_vertices(g));
+ return make_iterator_vertex_map(c.begin(), g);
+ }
+
+ template <class RandomAccessContainer> inline
+ iterator_property_map<
+ typename RandomAccessContainer::iterator,
+ identity_property_map,
+ typename RandomAccessContainer::value_type,
+ typename RandomAccessContainer::reference
+ >
+ make_container_vertex_map(RandomAccessContainer& c)
+ {
+ return make_iterator_vertex_map(c.begin());
+ }
+
+#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+# define BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+#endif
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ template<typename Graph, typename Descriptor, typename Bundle, typename T>
+ struct bundle_property_map
+ : put_get_helper<T&, bundle_property_map<Graph, Descriptor, Bundle, T> >
+ {
+ typedef Descriptor key_type;
+ typedef T value_type;
+ typedef T& reference;
+ typedef lvalue_property_map_tag category;
+
+ bundle_property_map() { }
+ bundle_property_map(Graph* g_, T Bundle::* pm_) : g(g_), pm(pm_) {}
+
+ reference operator[](key_type k) const { return (*g)[k].*pm; }
+ private:
+ Graph* g;
+ T Bundle::* pm;
+ };
+
+ namespace detail {
+ template<typename VertexBundle, typename EdgeBundle, typename Bundle>
+ struct is_vertex_bundle : is_convertible<VertexBundle*, Bundle*> {};
+ }
+
+ template <typename Graph, typename T, typename Bundle>
+ struct property_map<Graph, T Bundle::*>
+ {
+ private:
+ typedef graph_traits<Graph> traits;
+ typedef typename Graph::vertex_bundled vertex_bundled;
+ typedef typename Graph::edge_bundled edge_bundled;
+ typedef typename mpl::if_c<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value),
+ typename traits::vertex_descriptor,
+ typename traits::edge_descriptor>::type
+ descriptor;
+ typedef typename mpl::if_c<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value),
+ vertex_bundled,
+ edge_bundled>::type
+ actual_bundle;
+
+ public:
+ typedef bundle_property_map<Graph, descriptor, actual_bundle, T> type;
+ typedef bundle_property_map<const Graph, descriptor, actual_bundle, const T>
+ const_type;
+ };
+#endif
+
+} // namespace boost
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+// Stay out of the way of the concept checking class
+# undef Graph
+# undef RandomAccessIterator
+#endif
+
+
+#endif /* BOOST_GRAPH_PROPERTIES_HPPA */
Added: branches/CMake/release/libs/graph/include/boost/graph/property_iter_range.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/property_iter_range.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,118 @@
+
+// (C) Copyright François Faure, iMAGIS-GRAVIR / UJF, 2001.
+//
+// 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)
+//
+// Revision History:
+// 03 May 2001 Jeremy Siek
+// Generalized the property map iterator and moved that
+// part to boost/property_map.hpp. Also modified to
+// differentiate between const/mutable graphs and
+// added a workaround to avoid partial specialization.
+
+// 02 May 2001 François Faure
+// Initial version.
+
+#ifndef BOOST_GRAPH_PROPERTY_ITER_RANGE_HPP
+#define BOOST_GRAPH_PROPERTY_ITER_RANGE_HPP
+
+#include <boost/property_map_iterator.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/same_traits.hpp>
+
+namespace boost {
+
+//======================================================================
+// graph property iterator range
+
+ template <class Graph, class PropertyTag>
+ class graph_property_iter_range {
+ typedef typename property_map<Graph, PropertyTag>::type map_type;
+ typedef typename property_map<Graph, PropertyTag>::const_type
+ const_map_type;
+ typedef typename property_kind<PropertyTag>::type Kind;
+ typedef typename mpl::if_c<is_same<Kind, vertex_property_tag>::value,
+ typename graph_traits<Graph>::vertex_iterator,
+ typename graph_traits<Graph>::edge_iterator>::type iter;
+ public:
+ typedef typename property_map_iterator_generator<map_type, iter>::type
+ iterator;
+ typedef typename property_map_iterator_generator<const_map_type, iter>
+ ::type const_iterator;
+ typedef std::pair<iterator, iterator> type;
+ typedef std::pair<const_iterator, const_iterator> const_type;
+ };
+
+ namespace detail {
+
+ template<class Graph,class Tag>
+ typename graph_property_iter_range<Graph,Tag>::type
+ get_property_iter_range_kind(Graph& graph, const Tag& tag,
+ const vertex_property_tag& )
+ {
+ typedef typename graph_property_iter_range<Graph,Tag>::iterator iter;
+ return std::make_pair(iter(vertices(graph).first, get(tag, graph)),
+ iter(vertices(graph).second, get(tag, graph)));
+ }
+
+ template<class Graph,class Tag>
+ typename graph_property_iter_range<Graph,Tag>::const_type
+ get_property_iter_range_kind(const Graph& graph, const Tag& tag,
+ const vertex_property_tag& )
+ {
+ typedef typename graph_property_iter_range<Graph,Tag>
+ ::const_iterator iter;
+ return std::make_pair(iter(vertices(graph).first, get(tag, graph)),
+ iter(vertices(graph).second, get(tag, graph)));
+ }
+
+
+ template<class Graph,class Tag>
+ typename graph_property_iter_range<Graph,Tag>::type
+ get_property_iter_range_kind(Graph& graph, const Tag& tag,
+ const edge_property_tag& )
+ {
+ typedef typename graph_property_iter_range<Graph,Tag>::iterator iter;
+ return std::make_pair(iter(edges(graph).first, get(tag, graph)),
+ iter(edges(graph).second, get(tag, graph)));
+ }
+
+ template<class Graph,class Tag>
+ typename graph_property_iter_range<Graph,Tag>::const_type
+ get_property_iter_range_kind(const Graph& graph, const Tag& tag,
+ const edge_property_tag& )
+ {
+ typedef typename graph_property_iter_range<Graph,Tag>
+ ::const_iterator iter;
+ return std::make_pair(iter(edges(graph).first, get(tag, graph)),
+ iter(edges(graph).second, get(tag, graph)));
+ }
+
+ } // namespace detail
+
+ //======================================================================
+ // get an iterator range of properties
+
+ template<class Graph, class Tag>
+ typename graph_property_iter_range<Graph, Tag>::type
+ get_property_iter_range(Graph& graph, const Tag& tag)
+ {
+ typedef typename property_kind<Tag>::type Kind;
+ return detail::get_property_iter_range_kind(graph, tag, Kind());
+ }
+
+ template<class Graph, class Tag>
+ typename graph_property_iter_range<Graph, Tag>::const_type
+ get_property_iter_range(const Graph& graph, const Tag& tag)
+ {
+ typedef typename property_kind<Tag>::type Kind;
+ return detail::get_property_iter_range_kind(graph, tag, Kind());
+ }
+
+} // namespace boost
+
+
+#endif // BOOST_GRAPH_PROPERTY_ITER_RANGE_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/push_relabel_max_flow.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/push_relabel_max_flow.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,727 @@
+//=======================================================================
+// Copyright 2000 University of Notre Dame.
+// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_PUSH_RELABEL_MAX_FLOW_HPP
+#define BOOST_PUSH_RELABEL_MAX_FLOW_HPP
+
+#include <boost/config.hpp>
+#include <cassert>
+#include <vector>
+#include <list>
+#include <iosfwd>
+#include <algorithm> // for std::min and std::max
+
+#include <boost/pending/queue.hpp>
+#include <boost/limits.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/named_function_params.hpp>
+
+namespace boost {
+
+ namespace detail {
+
+ // This implementation is based on Goldberg's
+ // "On Implementing Push-Relabel Method for the Maximum Flow Problem"
+ // by B.V. Cherkassky and A.V. Goldberg, IPCO '95, pp. 157--171
+ // and on the h_prf.c and hi_pr.c code written by the above authors.
+
+ // This implements the highest-label version of the push-relabel method
+ // with the global relabeling and gap relabeling heuristics.
+
+ // The terms "rank", "distance", "height" are synonyms in
+ // Goldberg's implementation, paper and in the CLR. A "layer" is a
+ // group of vertices with the same distance. The vertices in each
+ // layer are categorized as active or inactive. An active vertex
+ // has positive excess flow and its distance is less than n (it is
+ // not blocked).
+
+ template <class Vertex>
+ struct preflow_layer {
+ std::list<Vertex> active_vertices;
+ std::list<Vertex> inactive_vertices;
+ };
+
+ template <class Graph,
+ class EdgeCapacityMap, // integer value type
+ class ResidualCapacityEdgeMap,
+ class ReverseEdgeMap,
+ class VertexIndexMap, // vertex_descriptor -> integer
+ class FlowValue>
+ class push_relabel
+ {
+ public:
+ typedef graph_traits<Graph> Traits;
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+ typedef typename Traits::edge_descriptor edge_descriptor;
+ typedef typename Traits::vertex_iterator vertex_iterator;
+ typedef typename Traits::out_edge_iterator out_edge_iterator;
+ typedef typename Traits::vertices_size_type vertices_size_type;
+ typedef typename Traits::edges_size_type edges_size_type;
+
+ typedef preflow_layer<vertex_descriptor> Layer;
+ typedef std::vector< Layer > LayerArray;
+ typedef typename LayerArray::iterator layer_iterator;
+ typedef typename LayerArray::size_type distance_size_type;
+
+ typedef color_traits<default_color_type> ColorTraits;
+
+ //=======================================================================
+ // Some helper predicates
+
+ inline bool is_admissible(vertex_descriptor u, vertex_descriptor v) {
+ return distance[u] == distance[v] + 1;
+ }
+ inline bool is_residual_edge(edge_descriptor a) {
+ return 0 < residual_capacity[a];
+ }
+ inline bool is_saturated(edge_descriptor a) {
+ return residual_capacity[a] == 0;
+ }
+
+ //=======================================================================
+ // Layer List Management Functions
+
+ typedef typename std::list<vertex_descriptor>::iterator list_iterator;
+
+ void add_to_active_list(vertex_descriptor u, Layer& layer) {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ layer.active_vertices.push_front(u);
+ max_active = max BOOST_PREVENT_MACRO_SUBSTITUTION(distance[u], max_active);
+ min_active = min BOOST_PREVENT_MACRO_SUBSTITUTION(distance[u], min_active);
+ layer_list_ptr[u] = layer.active_vertices.begin();
+ }
+ void remove_from_active_list(vertex_descriptor u) {
+ layers[distance[u]].active_vertices.erase(layer_list_ptr[u]);
+ }
+
+ void add_to_inactive_list(vertex_descriptor u, Layer& layer) {
+ layer.inactive_vertices.push_front(u);
+ layer_list_ptr[u] = layer.inactive_vertices.begin();
+ }
+ void remove_from_inactive_list(vertex_descriptor u) {
+ layers[distance[u]].inactive_vertices.erase(layer_list_ptr[u]);
+ }
+
+ //=======================================================================
+ // initialization
+ push_relabel(Graph& g_,
+ EdgeCapacityMap cap,
+ ResidualCapacityEdgeMap res,
+ ReverseEdgeMap rev,
+ vertex_descriptor src_,
+ vertex_descriptor sink_,
+ VertexIndexMap idx)
+ : g(g_), n(num_vertices(g_)), capacity(cap), src(src_), sink(sink_),
+ index(idx),
+ excess_flow(num_vertices(g_)),
+ current(num_vertices(g_), out_edges(*vertices(g_).first, g_).second),
+ distance(num_vertices(g_)),
+ color(num_vertices(g_)),
+ reverse_edge(rev),
+ residual_capacity(res),
+ layers(num_vertices(g_)),
+ layer_list_ptr(num_vertices(g_),
+ layers.front().inactive_vertices.end()),
+ push_count(0), update_count(0), relabel_count(0),
+ gap_count(0), gap_node_count(0),
+ work_since_last_update(0)
+ {
+ vertex_iterator u_iter, u_end;
+ // Don't count the reverse edges
+ edges_size_type m = num_edges(g) / 2;
+ nm = alpha() * n + m;
+
+ // Initialize flow to zero which means initializing
+ // the residual capacity to equal the capacity.
+ out_edge_iterator ei, e_end;
+ for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
+ for (tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) {
+ residual_capacity[*ei] = capacity[*ei];
+ }
+
+ for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
+ vertex_descriptor u = *u_iter;
+ excess_flow[u] = 0;
+ current[u] = out_edges(u, g).first;
+ }
+
+ bool overflow_detected = false;
+ FlowValue test_excess = 0;
+
+ out_edge_iterator a_iter, a_end;
+ for (tie(a_iter, a_end) = out_edges(src, g); a_iter != a_end; ++a_iter)
+ if (target(*a_iter, g) != src)
+ test_excess += residual_capacity[*a_iter];
+ if (test_excess > (std::numeric_limits<FlowValue>::max)())
+ overflow_detected = true;
+
+ if (overflow_detected)
+ excess_flow[src] = (std::numeric_limits<FlowValue>::max)();
+ else {
+ excess_flow[src] = 0;
+ for (tie(a_iter, a_end) = out_edges(src, g);
+ a_iter != a_end; ++a_iter) {
+ edge_descriptor a = *a_iter;
+ if (target(a, g) != src) {
+ ++push_count;
+ FlowValue delta = residual_capacity[a];
+ residual_capacity[a] -= delta;
+ residual_capacity[reverse_edge[a]] += delta;
+ excess_flow[target(a, g)] += delta;
+ }
+ }
+ }
+ max_distance = num_vertices(g) - 1;
+ max_active = 0;
+ min_active = n;
+
+ for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
+ vertex_descriptor u = *u_iter;
+ if (u == sink) {
+ distance[u] = 0;
+ continue;
+ } else if (u == src && !overflow_detected)
+ distance[u] = n;
+ else
+ distance[u] = 1;
+
+ if (excess_flow[u] > 0)
+ add_to_active_list(u, layers[1]);
+ else if (distance[u] < n)
+ add_to_inactive_list(u, layers[1]);
+ }
+
+ } // push_relabel constructor
+
+ //=======================================================================
+ // This is a breadth-first search over the residual graph
+ // (well, actually the reverse of the residual graph).
+ // Would be cool to have a graph view adaptor for hiding certain
+ // edges, like the saturated (non-residual) edges in this case.
+ // Goldberg's implementation abused "distance" for the coloring.
+ void global_distance_update()
+ {
+ BOOST_USING_STD_MAX();
+ ++update_count;
+ vertex_iterator u_iter, u_end;
+ for (tie(u_iter,u_end) = vertices(g); u_iter != u_end; ++u_iter) {
+ color[*u_iter] = ColorTraits::white();
+ distance[*u_iter] = n;
+ }
+ color[sink] = ColorTraits::gray();
+ distance[sink] = 0;
+
+ for (distance_size_type l = 0; l <= max_distance; ++l) {
+ layers[l].active_vertices.clear();
+ layers[l].inactive_vertices.clear();
+ }
+
+ max_distance = max_active = 0;
+ min_active = n;
+
+ Q.push(sink);
+ while (! Q.empty()) {
+ vertex_descriptor u = Q.top();
+ Q.pop();
+ distance_size_type d_v = distance[u] + 1;
+
+ out_edge_iterator ai, a_end;
+ for (tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai) {
+ edge_descriptor a = *ai;
+ vertex_descriptor v = target(a, g);
+ if (color[v] == ColorTraits::white()
+ && is_residual_edge(reverse_edge[a])) {
+ distance[v] = d_v;
+ color[v] = ColorTraits::gray();
+ current[v] = out_edges(v, g).first;
+ max_distance = max BOOST_PREVENT_MACRO_SUBSTITUTION(d_v, max_distance);
+
+ if (excess_flow[v] > 0)
+ add_to_active_list(v, layers[d_v]);
+ else
+ add_to_inactive_list(v, layers[d_v]);
+
+ Q.push(v);
+ }
+ }
+ }
+ } // global_distance_update()
+
+ //=======================================================================
+ // This function is called "push" in Goldberg's h_prf implementation,
+ // but it is called "discharge" in the paper and in hi_pr.c.
+ void discharge(vertex_descriptor u)
+ {
+ assert(excess_flow[u] > 0);
+ while (1) {
+ out_edge_iterator ai, ai_end;
+ for (ai = current[u], ai_end = out_edges(u, g).second;
+ ai != ai_end; ++ai) {
+ edge_descriptor a = *ai;
+ if (is_residual_edge(a)) {
+ vertex_descriptor v = target(a, g);
+ if (is_admissible(u, v)) {
+ ++push_count;
+ if (v != sink && excess_flow[v] == 0) {
+ remove_from_inactive_list(v);
+ add_to_active_list(v, layers[distance[v]]);
+ }
+ push_flow(a);
+ if (excess_flow[u] == 0)
+ break;
+ }
+ }
+ } // for out_edges of i starting from current
+
+ Layer& layer = layers[distance[u]];
+ distance_size_type du = distance[u];
+
+ if (ai == ai_end) { // i must be relabeled
+ relabel_distance(u);
+ if (layer.active_vertices.empty()
+ && layer.inactive_vertices.empty())
+ gap(du);
+ if (distance[u] == n)
+ break;
+ } else { // i is no longer active
+ current[u] = ai;
+ add_to_inactive_list(u, layer);
+ break;
+ }
+ } // while (1)
+ } // discharge()
+
+ //=======================================================================
+ // This corresponds to the "push" update operation of the paper,
+ // not the "push" function in Goldberg's h_prf.c implementation.
+ // The idea is to push the excess flow from from vertex u to v.
+ void push_flow(edge_descriptor u_v)
+ {
+ vertex_descriptor
+ u = source(u_v, g),
+ v = target(u_v, g);
+
+ BOOST_USING_STD_MIN();
+ FlowValue flow_delta
+ = min BOOST_PREVENT_MACRO_SUBSTITUTION(excess_flow[u], residual_capacity[u_v]);
+
+ residual_capacity[u_v] -= flow_delta;
+ residual_capacity[reverse_edge[u_v]] += flow_delta;
+
+ excess_flow[u] -= flow_delta;
+ excess_flow[v] += flow_delta;
+ } // push_flow()
+
+ //=======================================================================
+ // The main purpose of this routine is to set distance[v]
+ // to the smallest value allowed by the valid labeling constraints,
+ // which are:
+ // distance[t] = 0
+ // distance[u] <= distance[v] + 1 for every residual edge (u,v)
+ //
+ distance_size_type relabel_distance(vertex_descriptor u)
+ {
+ BOOST_USING_STD_MAX();
+ ++relabel_count;
+ work_since_last_update += beta();
+
+ distance_size_type min_distance = num_vertices(g);
+ distance[u] = min_distance;
+
+ // Examine the residual out-edges of vertex i, choosing the
+ // edge whose target vertex has the minimal distance.
+ out_edge_iterator ai, a_end, min_edge_iter;
+ for (tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai) {
+ ++work_since_last_update;
+ edge_descriptor a = *ai;
+ vertex_descriptor v = target(a, g);
+ if (is_residual_edge(a) && distance[v] < min_distance) {
+ min_distance = distance[v];
+ min_edge_iter = ai;
+ }
+ }
+ ++min_distance;
+ if (min_distance < n) {
+ distance[u] = min_distance; // this is the main action
+ current[u] = min_edge_iter;
+ max_distance = max BOOST_PREVENT_MACRO_SUBSTITUTION(min_distance, max_distance);
+ }
+ return min_distance;
+ } // relabel_distance()
+
+ //=======================================================================
+ // cleanup beyond the gap
+ void gap(distance_size_type empty_distance)
+ {
+ ++gap_count;
+
+ distance_size_type r; // distance of layer before the current layer
+ r = empty_distance - 1;
+
+ // Set the distance for the vertices beyond the gap to "infinity".
+ for (layer_iterator l = layers.begin() + empty_distance + 1;
+ l < layers.begin() + max_distance; ++l) {
+ list_iterator i;
+ for (i = l->inactive_vertices.begin();
+ i != l->inactive_vertices.end(); ++i) {
+ distance[*i] = n;
+ ++gap_node_count;
+ }
+ l->inactive_vertices.clear();
+ }
+ max_distance = r;
+ max_active = r;
+ }
+
+ //=======================================================================
+ // This is the core part of the algorithm, "phase one".
+ FlowValue maximum_preflow()
+ {
+ work_since_last_update = 0;
+
+ while (max_active >= min_active) { // "main" loop
+
+ Layer& layer = layers[max_active];
+ list_iterator u_iter = layer.active_vertices.begin();
+
+ if (u_iter == layer.active_vertices.end())
+ --max_active;
+ else {
+ vertex_descriptor u = *u_iter;
+ remove_from_active_list(u);
+
+ discharge(u);
+
+ if (work_since_last_update * global_update_frequency() > nm) {
+ global_distance_update();
+ work_since_last_update = 0;
+ }
+ }
+ } // while (max_active >= min_active)
+
+ return excess_flow[sink];
+ } // maximum_preflow()
+
+ //=======================================================================
+ // remove excess flow, the "second phase"
+ // This does a DFS on the reverse flow graph of nodes with excess flow.
+ // If a cycle is found, cancel it.
+ // Return the nodes with excess flow in topological order.
+ //
+ // Unlike the prefl_to_flow() implementation, we use
+ // "color" instead of "distance" for the DFS labels
+ // "parent" instead of nl_prev for the DFS tree
+ // "topo_next" instead of nl_next for the topological ordering
+ void convert_preflow_to_flow()
+ {
+ vertex_iterator u_iter, u_end;
+ out_edge_iterator ai, a_end;
+
+ vertex_descriptor r, restart, u;
+
+ std::vector<vertex_descriptor> parent(n);
+ std::vector<vertex_descriptor> topo_next(n);
+
+ vertex_descriptor tos(parent[0]),
+ bos(parent[0]); // bogus initialization, just to avoid warning
+ bool bos_null = true;
+
+ // handle self-loops
+ for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
+ for (tie(ai, a_end) = out_edges(*u_iter, g); ai != a_end; ++ai)
+ if (target(*ai, g) == *u_iter)
+ residual_capacity[*ai] = capacity[*ai];
+
+ // initialize
+ for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
+ u = *u_iter;
+ color[u] = ColorTraits::white();
+ parent[u] = u;
+ current[u] = out_edges(u, g).first;
+ }
+ // eliminate flow cycles and topologically order the vertices
+ for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
+ u = *u_iter;
+ if (color[u] == ColorTraits::white()
+ && excess_flow[u] > 0
+ && u != src && u != sink ) {
+ r = u;
+ color[r] = ColorTraits::gray();
+ while (1) {
+ for (; current[u] != out_edges(u, g).second; ++current[u]) {
+ edge_descriptor a = *current[u];
+ if (capacity[a] == 0 && is_residual_edge(a)) {
+ vertex_descriptor v = target(a, g);
+ if (color[v] == ColorTraits::white()) {
+ color[v] = ColorTraits::gray();
+ parent[v] = u;
+ u = v;
+ break;
+ } else if (color[v] == ColorTraits::gray()) {
+ // find minimum flow on the cycle
+ FlowValue delta = residual_capacity[a];
+ while (1) {
+ BOOST_USING_STD_MIN();
+ delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, residual_capacity[*current[v]]);
+ if (v == u)
+ break;
+ else
+ v = target(*current[v], g);
+ }
+ // remove delta flow units
+ v = u;
+ while (1) {
+ a = *current[v];
+ residual_capacity[a] -= delta;
+ residual_capacity[reverse_edge[a]] += delta;
+ v = target(a, g);
+ if (v == u)
+ break;
+ }
+
+ // back-out of DFS to the first saturated edge
+ restart = u;
+ for (v = target(*current[u], g); v != u; v = target(a, g)){
+ a = *current[v];
+ if (color[v] == ColorTraits::white()
+ || is_saturated(a)) {
+ color[target(*current[v], g)] = ColorTraits::white();
+ if (color[v] != ColorTraits::white())
+ restart = v;
+ }
+ }
+ if (restart != u) {
+ u = restart;
+ ++current[u];
+ break;
+ }
+ } // else if (color[v] == ColorTraits::gray())
+ } // if (capacity[a] == 0 ...
+ } // for out_edges(u, g) (though "u" changes during loop)
+
+ if (current[u] == out_edges(u, g).second) {
+ // scan of i is complete
+ color[u] = ColorTraits::black();
+ if (u != src) {
+ if (bos_null) {
+ bos = u;
+ bos_null = false;
+ tos = u;
+ } else {
+ topo_next[u] = tos;
+ tos = u;
+ }
+ }
+ if (u != r) {
+ u = parent[u];
+ ++current[u];
+ } else
+ break;
+ }
+ } // while (1)
+ } // if (color[u] == white && excess_flow[u] > 0 & ...)
+ } // for all vertices in g
+
+ // return excess flows
+ // note that the sink is not on the stack
+ if (! bos_null) {
+ for (u = tos; u != bos; u = topo_next[u]) {
+ ai = out_edges(u, g).first;
+ while (excess_flow[u] > 0 && ai != out_edges(u, g).second) {
+ if (capacity[*ai] == 0 && is_residual_edge(*ai))
+ push_flow(*ai);
+ ++ai;
+ }
+ }
+ // do the bottom
+ u = bos;
+ ai = out_edges(u, g).first;
+ while (excess_flow[u] > 0) {
+ if (capacity[*ai] == 0 && is_residual_edge(*ai))
+ push_flow(*ai);
+ ++ai;
+ }
+ }
+
+ } // convert_preflow_to_flow()
+
+ //=======================================================================
+ inline bool is_flow()
+ {
+ vertex_iterator u_iter, u_end;
+ out_edge_iterator ai, a_end;
+
+ // check edge flow values
+ for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
+ for (tie(ai, a_end) = out_edges(*u_iter, g); ai != a_end; ++ai) {
+ edge_descriptor a = *ai;
+ if (capacity[a] > 0)
+ if ((residual_capacity[a] + residual_capacity[reverse_edge[a]]
+ != capacity[a] + capacity[reverse_edge[a]])
+ || (residual_capacity[a] < 0)
+ || (residual_capacity[reverse_edge[a]] < 0))
+ return false;
+ }
+ }
+
+ // check conservation
+ FlowValue sum;
+ for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
+ vertex_descriptor u = *u_iter;
+ if (u != src && u != sink) {
+ if (excess_flow[u] != 0)
+ return false;
+ sum = 0;
+ for (tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai)
+ if (capacity[*ai] > 0)
+ sum -= capacity[*ai] - residual_capacity[*ai];
+ else
+ sum += residual_capacity[*ai];
+
+ if (excess_flow[u] != sum)
+ return false;
+ }
+ }
+
+ return true;
+ } // is_flow()
+
+ bool is_optimal() {
+ // check if mincut is saturated...
+ global_distance_update();
+ return distance[src] >= n;
+ }
+
+ void print_statistics(std::ostream& os) const {
+ os << "pushes: " << push_count << std::endl
+ << "relabels: " << relabel_count << std::endl
+ << "updates: " << update_count << std::endl
+ << "gaps: " << gap_count << std::endl
+ << "gap nodes: " << gap_node_count << std::endl
+ << std::endl;
+ }
+
+ void print_flow_values(std::ostream& os) const {
+ os << "flow values" << std::endl;
+ vertex_iterator u_iter, u_end;
+ out_edge_iterator ei, e_end;
+ for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
+ for (tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
+ if (capacity[*ei] > 0)
+ os << *u_iter << " " << target(*ei, g) << " "
+ << (capacity[*ei] - residual_capacity[*ei]) << std::endl;
+ os << std::endl;
+ }
+
+ //=======================================================================
+
+ Graph& g;
+ vertices_size_type n;
+ vertices_size_type nm;
+ EdgeCapacityMap capacity;
+ vertex_descriptor src;
+ vertex_descriptor sink;
+ VertexIndexMap index;
+
+ // will need to use random_access_property_map with these
+ std::vector< FlowValue > excess_flow;
+ std::vector< out_edge_iterator > current;
+ std::vector< distance_size_type > distance;
+ std::vector< default_color_type > color;
+
+ // Edge Property Maps that must be interior to the graph
+ ReverseEdgeMap reverse_edge;
+ ResidualCapacityEdgeMap residual_capacity;
+
+ LayerArray layers;
+ std::vector< list_iterator > layer_list_ptr;
+ distance_size_type max_distance; // maximal distance
+ distance_size_type max_active; // maximal distance with active node
+ distance_size_type min_active; // minimal distance with active node
+ boost::queue<vertex_descriptor> Q;
+
+ // Statistics counters
+ long push_count;
+ long update_count;
+ long relabel_count;
+ long gap_count;
+ long gap_node_count;
+
+ inline double global_update_frequency() { return 0.5; }
+ inline vertices_size_type alpha() { return 6; }
+ inline long beta() { return 12; }
+
+ long work_since_last_update;
+ };
+
+ } // namespace detail
+
+ template <class Graph,
+ class CapacityEdgeMap, class ResidualCapacityEdgeMap,
+ class ReverseEdgeMap, class VertexIndexMap>
+ typename property_traits<CapacityEdgeMap>::value_type
+ push_relabel_max_flow
+ (Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink,
+ CapacityEdgeMap cap, ResidualCapacityEdgeMap res,
+ ReverseEdgeMap rev, VertexIndexMap index_map)
+ {
+ typedef typename property_traits<CapacityEdgeMap>::value_type FlowValue;
+
+ detail::push_relabel<Graph, CapacityEdgeMap, ResidualCapacityEdgeMap,
+ ReverseEdgeMap, VertexIndexMap, FlowValue>
+ algo(g, cap, res, rev, src, sink, index_map);
+
+ FlowValue flow = algo.maximum_preflow();
+
+ algo.convert_preflow_to_flow();
+
+ assert(algo.is_flow());
+ assert(algo.is_optimal());
+
+ return flow;
+ } // push_relabel_max_flow()
+
+ template <class Graph, class P, class T, class R>
+ typename detail::edge_capacity_value<Graph, P, T, R>::type
+ push_relabel_max_flow
+ (Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink,
+ const bgl_named_params<P, T, R>& params)
+ {
+ return push_relabel_max_flow
+ (g, src, sink,
+ choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
+ choose_pmap(get_param(params, edge_residual_capacity),
+ g, edge_residual_capacity),
+ choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index)
+ );
+ }
+
+ template <class Graph>
+ typename property_traits<
+ typename property_map<Graph, edge_capacity_t>::const_type
+ >::value_type
+ push_relabel_max_flow
+ (Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink)
+ {
+ bgl_named_params<int, buffer_param_t> params(0); // bogus empty param
+ return push_relabel_max_flow(g, src, sink, params);
+ }
+
+} // namespace boost
+
+#endif // BOOST_PUSH_RELABEL_MAX_FLOW_HPP
+
Added: branches/CMake/release/libs/graph/include/boost/graph/random.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/random.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,205 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright (C) Vladimir Prus 2003
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_GRAPH_RANDOM_HPP
+#define BOOST_GRAPH_RANDOM_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/variate_generator.hpp>
+
+#include <boost/pending/property.hpp>
+#include <boost/graph/properties.hpp>
+
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/copy.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+#include <iostream>
+
+namespace boost {
+
+ // grab a random vertex from the graph's vertex set
+ template <class Graph, class RandomNumGen>
+ typename graph_traits<Graph>::vertex_descriptor
+ random_vertex(Graph& g, RandomNumGen& gen)
+ {
+ if (num_vertices(g) > 1) {
+ #if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581))
+ std::size_t n = std::random( num_vertices(g) );
+ #else
+ uniform_int<> distrib(0, num_vertices(g)-1);
+ variate_generator<RandomNumGen&, uniform_int<> > rand_gen(gen, distrib);
+ std::size_t n = rand_gen();
+ #endif
+ typename graph_traits<Graph>::vertex_iterator
+ i = vertices(g).first;
+ while (n-- > 0) ++i; // std::advance not VC++ portable
+ return *i;
+ } else
+ return *vertices(g).first;
+ }
+
+ template <class Graph, class RandomNumGen>
+ typename graph_traits<Graph>::edge_descriptor
+ random_edge(Graph& g, RandomNumGen& gen) {
+ if (num_edges(g) > 1) {
+ #if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581))
+ typename graph_traits<Graph>::edges_size_type
+ n = std::random( num_edges(g) );
+ #else
+ uniform_int<> distrib(0, num_edges(g)-1);
+ variate_generator<RandomNumGen&, uniform_int<> > rand_gen(gen, distrib);
+ typename graph_traits<Graph>::edges_size_type
+ n = rand_gen();
+ #endif
+ typename graph_traits<Graph>::edge_iterator
+ i = edges(g).first;
+ while (n-- > 0) ++i; // std::advance not VC++ portable
+ return *i;
+ } else
+ return *edges(g).first;
+ }
+
+ namespace detail {
+ class dummy_property_copier {
+ public:
+ template<class V1, class V2>
+ void operator()(const V1&, const V2&) const {}
+ };
+ }
+
+ template <typename MutableGraph, class RandNumGen>
+ void generate_random_graph1
+ (MutableGraph& g,
+ typename graph_traits<MutableGraph>::vertices_size_type V,
+ typename graph_traits<MutableGraph>::vertices_size_type E,
+ RandNumGen& gen,
+ bool allow_parallel = true,
+ bool self_edges = false)
+ {
+ typedef graph_traits<MutableGraph> Traits;
+ typedef typename Traits::vertices_size_type v_size_t;
+ typedef typename Traits::edges_size_type e_size_t;
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+
+ // When parallel edges are not allowed, we create a new graph which
+ // does not allow parallel edges, construct it and copy back.
+ // This is not efficient if 'g' already disallow parallel edges,
+ // but that's task for later.
+ if (!allow_parallel) {
+
+ typedef typename boost::graph_traits<MutableGraph>::directed_category dir;
+ typedef typename mpl::if_<is_convertible<dir, directed_tag>,
+ directedS, undirectedS>::type select;
+ adjacency_list<setS, vecS, select> g2;
+ generate_random_graph1(g2, V, E, gen, true, self_edges);
+
+ copy_graph(g2, g, vertex_copy(detail::dummy_property_copier()).
+ edge_copy(detail::dummy_property_copier()));
+
+ } else {
+
+ for (v_size_t i = 0; i < V; ++i)
+ add_vertex(g);
+
+ for (e_size_t j = 0; j < E; ++j) {
+ vertex_descriptor a = random_vertex(g, gen), b;
+ do {
+ b = random_vertex(g, gen);
+ } while (self_edges == false && a == b);
+ add_edge(a, b, g);
+ }
+ }
+ }
+
+ template <typename MutableGraph, class RandNumGen>
+ void generate_random_graph
+ (MutableGraph& g,
+ typename graph_traits<MutableGraph>::vertices_size_type V,
+ typename graph_traits<MutableGraph>::vertices_size_type E,
+ RandNumGen& gen,
+ bool allow_parallel = true,
+ bool self_edges = false)
+ {
+ generate_random_graph1(g, V, E, gen, allow_parallel, self_edges);
+ }
+
+ template <typename MutableGraph, typename RandNumGen,
+ typename VertexOutputIterator, typename EdgeOutputIterator>
+ void generate_random_graph
+ (MutableGraph& g,
+ typename graph_traits<MutableGraph>::vertices_size_type V,
+ typename graph_traits<MutableGraph>::vertices_size_type E,
+ RandNumGen& gen,
+ VertexOutputIterator vertex_out,
+ EdgeOutputIterator edge_out,
+ bool self_edges = false)
+ {
+ typedef graph_traits<MutableGraph> Traits;
+ typedef typename Traits::vertices_size_type v_size_t;
+ typedef typename Traits::edges_size_type e_size_t;
+ typedef typename Traits::vertex_descriptor vertex_t;
+ typedef typename Traits::edge_descriptor edge_t;
+
+ for (v_size_t i = 0; i < V; ++i)
+ *vertex_out++ = add_vertex(g);
+
+ for (e_size_t j = 0; j < E; ++j) {
+ vertex_t a = random_vertex(g, gen), b;
+ do {
+ b = random_vertex(g, gen);
+ } while (self_edges == false && a == b);
+ edge_t e; bool inserted;
+ tie(e, inserted) = add_edge(a, b, g);
+ if (inserted)
+ *edge_out++ = std::make_pair(source(e, g), target(e, g));
+ }
+ }
+
+ namespace detail {
+
+ template<class Property, class G, class RandomGenerator>
+ void randomize_property(G& g, RandomGenerator& rg,
+ Property, vertex_property_tag)
+ {
+ typename property_map<G, Property>::type pm = get(Property(), g);
+ typename graph_traits<G>::vertex_iterator vi, ve;
+ for (tie(vi, ve) = vertices(g); vi != ve; ++vi) {
+ pm[*vi] = rg();
+ }
+ }
+
+ template<class Property, class G, class RandomGenerator>
+ void randomize_property(G& g, RandomGenerator& rg,
+ Property, edge_property_tag)
+ {
+ typename property_map<G, Property>::type pm = get(Property(), g);
+ typename graph_traits<G>::edge_iterator ei, ee;
+ for (tie(ei, ee) = edges(g); ei != ee; ++ei) {
+ pm[*ei] = rg();
+ }
+ }
+ }
+
+ template<class Property, class G, class RandomGenerator>
+ void randomize_property(G& g, RandomGenerator& rg)
+ {
+ detail::randomize_property
+ (g, rg, Property(), typename property_kind<Property>::type());
+ }
+
+
+
+
+}
+
+
+#endif
Added: branches/CMake/release/libs/graph/include/boost/graph/random_layout.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/random_layout.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,49 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// 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)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_RANDOM_LAYOUT_HPP
+#define BOOST_GRAPH_RANDOM_LAYOUT_HPP
+
+#include <boost/graph/graph_traits.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/mpl/if.hpp>
+
+namespace boost {
+
+template<typename Graph, typename PositionMap, typename Dimension,
+ typename RandomNumberGenerator>
+void
+random_graph_layout(const Graph& g, PositionMap position_map,
+ Dimension minX, Dimension maxX,
+ Dimension minY, Dimension maxY,
+ RandomNumberGenerator& gen)
+{
+ typedef typename mpl::if_<is_integral<Dimension>,
+ uniform_int<Dimension>,
+ uniform_real<Dimension> >::type distrib_t;
+ typedef typename mpl::if_<is_integral<Dimension>,
+ RandomNumberGenerator&,
+ uniform_01<RandomNumberGenerator, Dimension> >
+ ::type gen_t;
+
+ gen_t my_gen(gen);
+ distrib_t x(minX, maxX);
+ distrib_t y(minY, maxY);
+ typename graph_traits<Graph>::vertex_iterator vi, vi_end;
+ for(tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
+ position_map[*vi].x = x(my_gen);
+ position_map[*vi].y = y(my_gen);
+ }
+}
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_RANDOM_LAYOUT_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/read_dimacs.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/read_dimacs.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,277 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
+//
+// 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)
+//=======================================================================
+
+/*
+ Reads maximal flow problem in extended DIMACS format.
+ This works, but could use some polishing.
+*/
+
+/* ----------------------------------------------------------------- */
+
+#include <vector>
+#include <istream>
+#include <stdio.h>
+
+namespace boost {
+
+template <class Graph, class CapacityMap, class ReverseEdgeMap>
+int read_dimacs_max_flow(Graph& g,
+ CapacityMap capacity,
+ ReverseEdgeMap reverse_edge,
+ typename graph_traits<Graph>::vertex_descriptor& src,
+ typename graph_traits<Graph>::vertex_descriptor& sink,
+ std::istream& in=std::cin)
+{
+ // const int MAXLINE = 100; /* max line length in the input file */
+ const int ARC_FIELDS = 3; /* no of fields in arc line */
+ const int NODE_FIELDS = 2; /* no of fields in node line */
+ const int P_FIELDS = 3; /* no of fields in problem line */
+ const char* PROBLEM_TYPE = "max"; /* name of problem type*/
+
+ typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
+
+ std::vector<vertex_descriptor> verts;
+
+ long m, n, /* number of edges and nodes */
+ i, head, tail, cap;
+
+ long no_lines=0, /* no of current input line */
+ no_plines=0, /* no of problem-lines */
+ no_nslines=0, /* no of node-source-lines */
+ no_nklines=0, /* no of node-source-lines */
+ no_alines=0; /* no of arc-lines */
+
+ std::string in_line; /* for reading input line */
+ char pr_type[3]; /* for reading type of the problem */
+ char nd; /* source (s) or sink (t) */
+
+ int k, /* temporary */
+ err_no; /* no of detected error */
+
+ /* -------------- error numbers & error messages ---------------- */
+ const int EN1 = 0;
+ const int EN2 = 1;
+ const int EN3 = 2;
+ const int EN4 = 3;
+ // const int EN6 = 4;
+ // const int EN10 = 5;
+ // const int EN7 = 6;
+ const int EN8 = 7;
+ const int EN9 = 8;
+ const int EN11 = 9;
+ const int EN12 = 10;
+ // const int EN13 = 11;
+ const int EN14 = 12;
+ const int EN16 = 13;
+ const int EN15 = 14;
+ const int EN17 = 15;
+ const int EN18 = 16;
+ const int EN21 = 17;
+ const int EN19 = 18;
+ const int EN20 = 19;
+ const int EN22 = 20;
+
+ static char *err_message[] =
+ {
+ /* 0*/ "more than one problem line.",
+ /* 1*/ "wrong number of parameters in the problem line.",
+ /* 2*/ "it is not a Max Flow problem line.",
+ /* 3*/ "bad value of a parameter in the problem line.",
+ /* 4*/ "can't obtain enough memory to solve this problem.",
+ /* 5*/ "more than one line with the problem name.",
+ /* 6*/ "can't read problem name.",
+ /* 7*/ "problem description must be before node description.",
+ /* 8*/ "this parser doesn't support multiply sources and sinks.",
+ /* 9*/ "wrong number of parameters in the node line.",
+ /*10*/ "wrong value of parameters in the node line.",
+ /*11*/ " ",
+ /*12*/ "source and sink descriptions must be before arc descriptions.",
+ /*13*/ "too many arcs in the input.",
+ /*14*/ "wrong number of parameters in the arc line.",
+ /*15*/ "wrong value of parameters in the arc line.",
+ /*16*/ "unknown line type in the input.",
+ /*17*/ "reading error.",
+ /*18*/ "not enough arcs in the input.",
+ /*19*/ "source or sink doesn't have incident arcs.",
+ /*20*/ "can't read anything from the input file."
+ };
+ /* --------------------------------------------------------------- */
+
+ /* The main loop:
+ - reads the line of the input,
+ - analyses its type,
+ - checks correctness of parameters,
+ - puts data to the arrays,
+ - does service functions
+ */
+
+ while (std::getline(in, in_line)) {
+ ++no_lines;
+
+ switch (in_line[0]) {
+ case 'c': /* skip lines with comments */
+ case '\n': /* skip empty lines */
+ case '\0': /* skip empty lines at the end of file */
+ break;
+
+ case 'p': /* problem description */
+ if ( no_plines > 0 )
+ /* more than one problem line */
+ { err_no = EN1 ; goto error; }
+
+ no_plines = 1;
+
+ if (
+ /* reading problem line: type of problem, no of nodes, no of arcs */
+ sscanf ( in_line.c_str(), "%*c %3s %ld %ld", pr_type, &n, &m )
+ != P_FIELDS
+ )
+ /*wrong number of parameters in the problem line*/
+ { err_no = EN2; goto error; }
+
+ if ( strcmp ( pr_type, PROBLEM_TYPE ) )
+ /*wrong problem type*/
+ { err_no = EN3; goto error; }
+
+ if ( n <= 0 || m <= 0 )
+ /*wrong value of no of arcs or nodes*/
+ { err_no = EN4; goto error; }
+
+ {
+ for (long vi = 0; vi < n; ++vi)
+ verts.push_back(add_vertex(g));
+ }
+ break;
+
+ case 'n': /* source(s) description */
+ if ( no_plines == 0 )
+ /* there was not problem line above */
+ { err_no = EN8; goto error; }
+
+ /* reading source or sink */
+ k = sscanf ( in_line.c_str(),"%*c %ld %c", &i, &nd );
+ --i; // index from 0
+ if ( k < NODE_FIELDS )
+ /* node line is incorrect */
+ { err_no = EN11; goto error; }
+
+ if ( i < 0 || i > n )
+ /* wrong value of node */
+ { err_no = EN12; goto error; }
+
+ switch (nd) {
+ case 's': /* source line */
+
+ if ( no_nslines != 0)
+ /* more than one source line */
+ { err_no = EN9; goto error; }
+
+ no_nslines = 1;
+ src = verts[i];
+ break;
+
+ case 't': /* sink line */
+
+ if ( no_nklines != 0)
+ /* more than one sink line */
+ { err_no = EN9; goto error; }
+
+ no_nklines = 1;
+ sink = verts[i];
+ break;
+
+ default:
+ /* wrong type of node-line */
+ err_no = EN12; goto error;
+ }
+ break;
+
+ case 'a': /* arc description */
+ if ( no_nslines == 0 || no_nklines == 0 )
+ /* there was not source and sink description above */
+ { err_no = EN14; goto error; }
+
+ if ( no_alines >= m )
+ /*too many arcs on input*/
+ { err_no = EN16; goto error; }
+
+ if (
+ /* reading an arc description */
+ sscanf ( in_line.c_str(),"%*c %ld %ld %ld",
+ &tail, &head, &cap )
+ != ARC_FIELDS
+ )
+ /* arc description is not correct */
+ { err_no = EN15; goto error; }
+
+ --tail; // index from 0, not 1
+ --head;
+ if ( tail < 0 || tail > n ||
+ head < 0 || head > n
+ )
+ /* wrong value of nodes */
+ { err_no = EN17; goto error; }
+
+ {
+ edge_descriptor e1, e2;
+ bool in1, in2;
+ tie(e1, in1) = add_edge(verts[tail], verts[head], g);
+ tie(e2, in2) = add_edge(verts[head], verts[tail], g);
+ if (!in1 || !in2) {
+ std::cerr << "unable to add edge (" << head << "," << tail << ")"
+ << std::endl;
+ return -1;
+ }
+ capacity[e1] = cap;
+ capacity[e2] = 0;
+ reverse_edge[e1] = e2;
+ reverse_edge[e2] = e1;
+ }
+ ++no_alines;
+ break;
+
+ default:
+ /* unknown type of line */
+ err_no = EN18; goto error;
+
+ } /* end of switch */
+ } /* end of input loop */
+
+ /* ----- all is red or error while reading ----- */
+
+ if ( feof (stdin) == 0 ) /* reading error */
+ { err_no=EN21; goto error; }
+
+ if ( no_lines == 0 ) /* empty input */
+ { err_no = EN22; goto error; }
+
+ if ( no_alines < m ) /* not enough arcs */
+ { err_no = EN19; goto error; }
+
+ if ( out_degree(src, g) == 0 || out_degree(sink, g) == 0 )
+ /* no arc goes out of the source */
+ { err_no = EN20; goto error; }
+
+ /* Thanks God! all is done */
+ return (0);
+
+ /* ---------------------------------- */
+ error: /* error found reading input */
+
+ printf ( "\nline %ld of input - %s\n",
+ no_lines, err_message[err_no] );
+
+ exit (1);
+ return (0); /* to avoid warning */
+}
+/* -------------------- end of parser -------------------*/
+
+} // namespace boost
Added: branches/CMake/release/libs/graph/include/boost/graph/relax.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/relax.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,77 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek,
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_GRAPH_RELAX_HPP
+#define BOOST_GRAPH_RELAX_HPP
+
+#include <functional>
+#include <boost/limits.hpp> // for numeric limits
+#include <boost/graph/graph_traits.hpp>
+#include <boost/property_map.hpp>
+
+namespace boost {
+
+ // The following version of the plus functor prevents
+ // problems due to overflow at positive infinity.
+
+ template <class T>
+ struct closed_plus
+ {
+ T operator()(const T& a, const T& b) const {
+ using namespace std;
+ T zero(0);
+ T result = a + b;
+ if (result < zero && a >= zero && b >= zero)
+ return (numeric_limits<T>::max)();
+ return result;
+ }
+ };
+
+ template <class Graph, class WeightMap,
+ class PredecessorMap, class DistanceMap,
+ class BinaryFunction, class BinaryPredicate>
+ bool relax(typename graph_traits<Graph>::edge_descriptor e,
+ const Graph& g, const WeightMap& w,
+ PredecessorMap& p, DistanceMap& d,
+ const BinaryFunction& combine, const BinaryPredicate& compare)
+ {
+ typedef typename graph_traits<Graph>::directed_category DirCat;
+ bool is_undirected = is_same<DirCat, undirected_tag>::value;
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ Vertex u = source(e, g), v = target(e, g);
+ typedef typename property_traits<DistanceMap>::value_type D;
+ typedef typename property_traits<WeightMap>::value_type W;
+ D d_u = get(d, u), d_v = get(d, v);
+ W w_e = get(w, e);
+
+ if ( compare(combine(d_u, w_e), d_v) ) {
+ put(d, v, combine(d_u, w_e));
+ put(p, v, u);
+ return true;
+ } else if (is_undirected && compare(combine(d_v, w_e), d_u)) {
+ put(d, u, combine(d_v, w_e));
+ put(p, u, v);
+ return true;
+ } else
+ return false;
+ }
+
+ template <class Graph, class WeightMap,
+ class PredecessorMap, class DistanceMap>
+ bool relax(typename graph_traits<Graph>::edge_descriptor e,
+ const Graph& g, WeightMap w, PredecessorMap p, DistanceMap d)
+ {
+ typedef typename property_traits<DistanceMap>::value_type D;
+ typedef closed_plus<D> Combine;
+ typedef std::less<D> Compare;
+ return relax(e, g, w, p, d, Combine(), Compare());
+ }
+
+} // namespace boost
+
+#endif /* BOOST_GRAPH_RELAX_HPP */
Added: branches/CMake/release/libs/graph/include/boost/graph/reverse_graph.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/reverse_graph.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,324 @@
+// (C) Copyright David Abrahams 2000.
+// 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)
+
+#ifndef REVERSE_GRAPH_DWA092300_H_
+# define REVERSE_GRAPH_DWA092300_H_
+
+#include <boost/graph/adjacency_iterator.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/tuple/tuple.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+// Stay out of the way of the concept checking class
+# define BidirectionalGraph BidirectionalGraph_
+#endif
+
+namespace boost {
+
+struct reverse_graph_tag { };
+
+ namespace detail {
+
+ template <bool isEdgeList> struct choose_rev_edge_iter { };
+ template <> struct choose_rev_edge_iter<true> {
+ template <class G> struct bind_ {
+ typedef typename graph_traits<G>::edge_iterator type;
+ };
+ };
+ template <> struct choose_rev_edge_iter<false> {
+ template <class G> struct bind_ {
+ typedef void type;
+ };
+ };
+
+ } // namespace detail
+
+template <class BidirectionalGraph, class GraphRef = const BidirectionalGraph&>
+class reverse_graph {
+ typedef reverse_graph<BidirectionalGraph, GraphRef> Self;
+ typedef graph_traits<BidirectionalGraph> Traits;
+ public:
+ typedef BidirectionalGraph base_type;
+
+ // Constructor
+ reverse_graph(GraphRef g) : m_g(g) {}
+
+ // Graph requirements
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+ typedef typename Traits::edge_descriptor edge_descriptor;
+ typedef typename Traits::directed_category directed_category;
+ typedef typename Traits::edge_parallel_category edge_parallel_category;
+ typedef typename Traits::traversal_category traversal_category;
+
+ // IncidenceGraph requirements
+ typedef typename Traits::in_edge_iterator out_edge_iterator;
+ typedef typename Traits::degree_size_type degree_size_type;
+
+ // BidirectionalGraph requirements
+ typedef typename Traits::out_edge_iterator in_edge_iterator;
+
+ // AdjacencyGraph requirements
+ typedef typename adjacency_iterator_generator<Self,
+ vertex_descriptor, out_edge_iterator>::type adjacency_iterator;
+
+ // VertexListGraph requirements
+ typedef typename Traits::vertex_iterator vertex_iterator;
+
+ // EdgeListGraph requirements
+ enum { is_edge_list = is_convertible<traversal_category,
+ edge_list_graph_tag>::value };
+ typedef detail::choose_rev_edge_iter<is_edge_list> ChooseEdgeIter;
+ typedef typename ChooseEdgeIter::
+ template bind_<BidirectionalGraph>::type edge_iterator;
+ typedef typename Traits::vertices_size_type vertices_size_type;
+ typedef typename Traits::edges_size_type edges_size_type;
+
+ // More typedefs used by detail::edge_property_map, vertex_property_map
+ typedef typename BidirectionalGraph::edge_property_type
+ edge_property_type;
+ typedef typename BidirectionalGraph::vertex_property_type
+ vertex_property_type;
+ typedef reverse_graph_tag graph_tag;
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ // Bundled properties support
+ template<typename Descriptor>
+ typename graph::detail::bundled_result<BidirectionalGraph,
+ Descriptor>::type&
+ operator[](Descriptor x)
+ { return m_g[x]; }
+
+ template<typename Descriptor>
+ typename graph::detail::bundled_result<BidirectionalGraph,
+ Descriptor>::type const&
+ operator[](Descriptor x) const
+ { return m_g[x]; }
+#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+
+ static vertex_descriptor null_vertex()
+ { return Traits::null_vertex(); }
+
+ // would be private, but template friends aren't portable enough.
+ // private:
+ GraphRef m_g;
+};
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ template<typename Graph, typename GraphRef>
+ struct vertex_bundle_type<reverse_graph<Graph, GraphRef> >
+ : vertex_bundle_type<Graph> { };
+
+ template<typename Graph, typename GraphRef>
+ struct edge_bundle_type<reverse_graph<Graph, GraphRef> >
+ : edge_bundle_type<Graph> { };
+#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+
+template <class BidirectionalGraph>
+inline reverse_graph<BidirectionalGraph>
+make_reverse_graph(const BidirectionalGraph& g)
+{
+ return reverse_graph<BidirectionalGraph>(g);
+}
+
+template <class BidirectionalGraph>
+inline reverse_graph<BidirectionalGraph, BidirectionalGraph&>
+make_reverse_graph(BidirectionalGraph& g)
+{
+ return reverse_graph<BidirectionalGraph, BidirectionalGraph&>(g);
+}
+
+template <class BidirectionalGraph, class GRef>
+std::pair<typename reverse_graph<BidirectionalGraph>::vertex_iterator,
+ typename reverse_graph<BidirectionalGraph>::vertex_iterator>
+vertices(const reverse_graph<BidirectionalGraph,GRef>& g)
+{
+ return vertices(g.m_g);
+}
+
+template <class BidirectionalGraph, class GRef>
+std::pair<typename reverse_graph<BidirectionalGraph>::edge_iterator,
+ typename reverse_graph<BidirectionalGraph>::edge_iterator>
+edges(const reverse_graph<BidirectionalGraph,GRef>& g)
+{
+ return edges(g.m_g);
+}
+
+template <class BidirectionalGraph, class GRef>
+inline std::pair<typename BidirectionalGraph::in_edge_iterator,
+ typename BidirectionalGraph::in_edge_iterator>
+out_edges(const typename BidirectionalGraph::vertex_descriptor u,
+ const reverse_graph<BidirectionalGraph,GRef>& g)
+{
+ return in_edges(u, g.m_g);
+}
+
+template <class BidirectionalGraph, class GRef>
+inline typename BidirectionalGraph::vertices_size_type
+num_vertices(const reverse_graph<BidirectionalGraph,GRef>& g)
+{
+ return num_vertices(g.m_g);
+}
+
+template <class BidirectionalGraph, class GRef>
+inline typename reverse_graph<BidirectionalGraph>::edges_size_type
+num_edges(const reverse_graph<BidirectionalGraph,GRef>& g)
+{
+ return num_edges(g.m_g);
+}
+
+template <class BidirectionalGraph, class GRef>
+inline typename BidirectionalGraph::degree_size_type
+out_degree(const typename BidirectionalGraph::vertex_descriptor u,
+ const reverse_graph<BidirectionalGraph,GRef>& g)
+{
+ return in_degree(u, g.m_g);
+}
+
+template <class BidirectionalGraph, class GRef>
+inline std::pair<typename BidirectionalGraph::edge_descriptor, bool>
+edge(const typename BidirectionalGraph::vertex_descriptor u,
+ const typename BidirectionalGraph::vertex_descriptor v,
+ const reverse_graph<BidirectionalGraph,GRef>& g)
+{
+ return edge(v, u, g.m_g);
+}
+
+template <class BidirectionalGraph, class GRef>
+inline std::pair<typename BidirectionalGraph::out_edge_iterator,
+ typename BidirectionalGraph::out_edge_iterator>
+in_edges(const typename BidirectionalGraph::vertex_descriptor u,
+ const reverse_graph<BidirectionalGraph,GRef>& g)
+{
+ return out_edges(u, g.m_g);
+}
+
+template <class BidirectionalGraph, class GRef>
+inline std::pair<typename reverse_graph<BidirectionalGraph,GRef>::adjacency_iterator,
+ typename reverse_graph<BidirectionalGraph,GRef>::adjacency_iterator>
+adjacent_vertices(const typename BidirectionalGraph::vertex_descriptor u,
+ const reverse_graph<BidirectionalGraph,GRef>& g)
+{
+ typedef reverse_graph<BidirectionalGraph,GRef> Graph;
+ typename Graph::out_edge_iterator first, last;
+ tie(first, last) = out_edges(u, g);
+ typedef typename Graph::adjacency_iterator adjacency_iterator;
+ return std::make_pair(adjacency_iterator(first, const_cast<Graph*>(&g)),
+ adjacency_iterator(last, const_cast<Graph*>(&g)));
+}
+
+template <class BidirectionalGraph, class GRef>
+inline typename BidirectionalGraph::degree_size_type
+in_degree(const typename BidirectionalGraph::vertex_descriptor u,
+ const reverse_graph<BidirectionalGraph,GRef>& g)
+{
+ return out_degree(u, g.m_g);
+}
+
+template <class Edge, class BidirectionalGraph, class GRef>
+inline typename graph_traits<BidirectionalGraph>::vertex_descriptor
+source(const Edge& e, const reverse_graph<BidirectionalGraph,GRef>& g)
+{
+ return target(e, g.m_g);
+}
+
+template <class Edge, class BidirectionalGraph, class GRef>
+inline typename graph_traits<BidirectionalGraph>::vertex_descriptor
+target(const Edge& e, const reverse_graph<BidirectionalGraph,GRef>& g)
+{
+ return source(e, g.m_g);
+}
+
+
+namespace detail {
+
+ struct reverse_graph_vertex_property_selector {
+ template <class ReverseGraph, class Property, class Tag>
+ struct bind_ {
+ typedef typename ReverseGraph::base_type Graph;
+ typedef property_map<Graph, Tag> PMap;
+ typedef typename PMap::type type;
+ typedef typename PMap::const_type const_type;
+ };
+ };
+
+ struct reverse_graph_edge_property_selector {
+ template <class ReverseGraph, class Property, class Tag>
+ struct bind_ {
+ typedef typename ReverseGraph::base_type Graph;
+ typedef property_map<Graph, Tag> PMap;
+ typedef typename PMap::type type;
+ typedef typename PMap::const_type const_type;
+ };
+ };
+
+} // namespace detail
+
+template <>
+struct vertex_property_selector<reverse_graph_tag> {
+ typedef detail::reverse_graph_vertex_property_selector type;
+};
+
+template <>
+struct edge_property_selector<reverse_graph_tag> {
+ typedef detail::reverse_graph_edge_property_selector type;
+};
+
+template <class BidirGraph, class GRef, class Property>
+typename property_map<BidirGraph, Property>::type
+get(Property p, reverse_graph<BidirGraph,GRef>& g)
+{
+ return get(p, g.m_g);
+}
+
+template <class BidirGraph, class GRef, class Property>
+typename property_map<BidirGraph, Property>::const_type
+get(Property p, const reverse_graph<BidirGraph,GRef>& g)
+{
+ const BidirGraph& gref = g.m_g; // in case GRef is non-const
+ return get(p, gref);
+}
+
+template <class BidirectionalGraph, class GRef, class Property, class Key>
+typename property_traits<
+ typename property_map<BidirectionalGraph, Property>::const_type
+>::value_type
+get(Property p, const reverse_graph<BidirectionalGraph,GRef>& g, const Key& k)
+{
+ return get(p, g.m_g, k);
+}
+
+template <class BidirectionalGraph, class GRef, class Property, class Key, class Value>
+void
+put(Property p, const reverse_graph<BidirectionalGraph,GRef>& g, const Key& k,
+ const Value& val)
+{
+ put(p, g.m_g, k, val);
+}
+
+template<typename BidirectionalGraph, typename GRef, typename Tag,
+ typename Value>
+inline void
+set_property(const reverse_graph<BidirectionalGraph,GRef>& g, Tag tag,
+ const Value& value)
+{
+ set_property(g.m_g, tag, value);
+}
+
+template<typename BidirectionalGraph, typename GRef, typename Tag>
+inline
+typename graph_property<BidirectionalGraph, Tag>::type
+get_property(const reverse_graph<BidirectionalGraph,GRef>& g, Tag tag)
+{
+ return get_property(g.m_g, tag);
+}
+
+} // namespace boost
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+// Stay out of the way of the concept checking class
+# undef BidirectionalGraph
+#endif
+
+#endif
Added: branches/CMake/release/libs/graph/include/boost/graph/sequential_vertex_coloring.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/sequential_vertex_coloring.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,124 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2004 The Trustees of Indiana University
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_GRAPH_SEQUENTIAL_VERTEX_COLORING_HPP
+#define BOOST_GRAPH_SEQUENTIAL_VERTEX_COLORING_HPP
+
+#include <vector>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/property_map.hpp>
+#include <boost/limits.hpp>
+
+#ifdef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
+# include <iterator>
+#endif
+
+/* This algorithm is to find coloring of a graph
+
+ Algorithm:
+ Let G = (V,E) be a graph with vertices (somehow) ordered v_1, v_2, ...,
+ v_n. For k = 1, 2, ..., n the sequential algorithm assigns v_k to the
+ smallest possible color.
+
+ Reference:
+
+ Thomas F. Coleman and Jorge J. More, Estimation of sparse Jacobian
+ matrices and graph coloring problems. J. Numer. Anal. V20, P187-209, 1983
+
+ v_k is stored as o[k] here.
+
+ The color of the vertex v will be stored in color[v].
+ i.e., vertex v belongs to coloring color[v] */
+
+namespace boost {
+ template <class VertexListGraph, class OrderPA, class ColorMap>
+ typename property_traits<ColorMap>::value_type
+ sequential_vertex_coloring(const VertexListGraph& G, OrderPA order,
+ ColorMap color)
+ {
+ typedef graph_traits<VertexListGraph> GraphTraits;
+ typedef typename GraphTraits::vertex_descriptor Vertex;
+ typedef typename property_traits<ColorMap>::value_type size_type;
+
+ size_type max_color = 0;
+ const size_type V = num_vertices(G);
+
+ // We need to keep track of which colors are used by
+ // adjacent vertices. We do this by marking the colors
+ // that are used. The mark array contains the mark
+ // for each color. The length of mark is the
+ // number of vertices since the maximum possible number of colors
+ // is the number of vertices.
+ std::vector<size_type> mark(V,
+ std::numeric_limits<size_type>::max BOOST_PREVENT_MACRO_SUBSTITUTION());
+
+ //Initialize colors
+ typename GraphTraits::vertex_iterator v, vend;
+ for (tie(v, vend) = vertices(G); v != vend; ++v)
+ put(color, *v, V-1);
+
+ //Determine the color for every vertex one by one
+ for ( size_type i = 0; i < V; i++) {
+ Vertex current = get(order,i);
+ typename GraphTraits::adjacency_iterator v, vend;
+
+ //Mark the colors of vertices adjacent to current.
+ //i can be the value for marking since i increases successively
+ for (tie(v,vend) = adjacent_vertices(current, G); v != vend; ++v)
+ mark[get(color,*v)] = i;
+
+ //Next step is to assign the smallest un-marked color
+ //to the current vertex.
+ size_type j = 0;
+
+ //Scan through all useable colors, find the smallest possible
+ //color that is not used by neighbors. Note that if mark[j]
+ //is equal to i, color j is used by one of the current vertex's
+ //neighbors.
+ while ( j < max_color && mark[j] == i )
+ ++j;
+
+ if ( j == max_color ) //All colors are used up. Add one more color
+ ++max_color;
+
+ //At this point, j is the smallest possible color
+ put(color, current, j); //Save the color of vertex current
+ }
+
+ return max_color;
+ }
+
+ template<class VertexListGraph, class ColorMap>
+ typename property_traits<ColorMap>::value_type
+ sequential_vertex_coloring(const VertexListGraph& G, ColorMap color)
+ {
+ typedef typename graph_traits<VertexListGraph>::vertex_descriptor
+ vertex_descriptor;
+ typedef typename graph_traits<VertexListGraph>::vertex_iterator
+ vertex_iterator;
+
+ std::pair<vertex_iterator, vertex_iterator> v = vertices(G);
+#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
+ std::vector<vertex_descriptor> order(v.first, v.second);
+#else
+ std::vector<vertex_descriptor> order;
+ order.reserve(std::distance(v.first, v.second));
+ while (v.first != v.second) order.push_back(*v.first++);
+#endif
+ return sequential_vertex_coloring
+ (G,
+ make_iterator_property_map
+ (order.begin(), identity_property_map(),
+ graph_traits<VertexListGraph>::null_vertex()),
+ color);
+ }
+}
+
+#endif
Added: branches/CMake/release/libs/graph/include/boost/graph/simple_point.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/simple_point.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,23 @@
+//=======================================================================
+// Copyright 2005 Trustees of Indiana University
+// Authors: Andrew Lumsdaine, Douglas Gregor
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_GRAPH_SIMPLE_POINT_HPP
+#define BOOST_GRAPH_SIMPLE_POINT_HPP
+
+namespace boost {
+
+template<typename T>
+struct simple_point
+{
+ T x;
+ T y;
+};
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_SIMPLE_POINT_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/sloan_ordering.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/sloan_ordering.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,448 @@
+//
+//=======================================================================
+// Copyright 2002 Marc Wintermantel (wintermantel_at_[hidden])
+// ETH Zurich, Center of Structure Technologies (www.imes.ethz.ch/st)
+//
+// 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)
+//=======================================================================
+//
+
+#ifndef BOOST_GRAPH_SLOAN_HPP
+#define BOOST_GRAPH_SLOAN_HPP
+
+#define WEIGHT1 1 //default weight for the distance in the Sloan algorithm
+#define WEIGHT2 2 //default weight for the degree in the Sloan algorithm
+#define MAXINT 2147483647 //Maximum value for a 32bit integer
+
+#include <boost/config.hpp>
+#include <vector>
+#include <queue>
+#include <boost/pending/queue.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/pending/indirect_cmp.hpp>
+#include <boost/property_map.hpp>
+#include <algorithm>
+#include <utility>
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/cuthill_mckee_ordering.hpp>
+
+
+////////////////////////////////////////////////////////////
+//
+//Sloan-Algorithm for graph reordering
+//(optimzes profile and wavefront, not primiraly bandwidth
+//
+////////////////////////////////////////////////////////////
+
+namespace boost {
+
+ /////////////////////////////////////////////////////////////////////////
+ // Function that returns the maximum depth of
+ // a rooted level strucutre (RLS)
+ //
+ /////////////////////////////////////////////////////////////////////////
+ template<class Distance>
+ unsigned RLS_depth(Distance& d)
+ {
+ unsigned h_s = 0;
+ typename Distance::iterator iter;
+
+ for (iter = d.begin(); iter != d.end(); ++iter)
+ {
+ if(*iter > h_s)
+ {
+ h_s = *iter;
+ }
+ }
+
+ return h_s;
+ }
+
+
+
+ /////////////////////////////////////////////////////////////////////////
+ // Function that returns the width of the largest level of
+ // a rooted level strucutre (RLS)
+ //
+ /////////////////////////////////////////////////////////////////////////
+ template<class Distance, class my_int>
+ unsigned RLS_max_width(Distance& d, my_int depth)
+ {
+
+ //Searching for the maximum width of a level
+ std::vector<unsigned> dummy_width(depth+1, 0);
+ std::vector<unsigned>::iterator my_it;
+ typename Distance::iterator iter;
+ unsigned w_max = 0;
+
+ for (iter = d.begin(); iter != d.end(); ++iter)
+ {
+ dummy_width[*iter]++;
+ }
+
+ for(my_it = dummy_width.begin(); my_it != dummy_width.end(); ++my_it)
+ {
+ if(*my_it > w_max) w_max = *my_it;
+ }
+
+ return w_max;
+
+ }
+
+
+ /////////////////////////////////////////////////////////////////////////
+ // Function for finding a good starting node for Sloan algorithm
+ //
+ // This is to find a good starting node. "good" is in the sense
+ // of the ordering generated.
+ /////////////////////////////////////////////////////////////////////////
+ template <class Graph, class ColorMap, class DegreeMap>
+ typename graph_traits<Graph>::vertex_descriptor
+ sloan_start_end_vertices(Graph& G,
+ typename graph_traits<Graph>::vertex_descriptor &s,
+ ColorMap color,
+ DegreeMap degree)
+ {
+ typedef typename property_traits<DegreeMap>::value_type Degree;
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename std::vector< typename graph_traits<Graph>::vertices_size_type>::iterator vec_iter;
+ typedef typename graph_traits<Graph>::vertices_size_type size_type;
+
+ typedef typename property_map<Graph, vertex_index_t>::const_type VertexID;
+
+ s = *(vertices(G).first);
+ Vertex e = s;
+ Vertex i;
+ unsigned my_degree = get(degree, s );
+ unsigned dummy, h_i, h_s, w_i, w_e;
+ bool new_start = true;
+ unsigned maximum_degree = 0;
+
+ //Creating a std-vector for storing the distance from the start vertex in dist
+ std::vector<typename graph_traits<Graph>::vertices_size_type> dist(num_vertices(G), 0);
+
+ //Wrap a property_map_iterator around the std::iterator
+ boost::iterator_property_map<vec_iter, VertexID, size_type, size_type&> dist_pmap(dist.begin(), get(vertex_index, G));
+
+ //Creating a property_map for the indices of a vertex
+ typename property_map<Graph, vertex_index_t>::type index_map = get(vertex_index, G);
+
+ //Creating a priority queue
+ typedef indirect_cmp<DegreeMap, std::greater<Degree> > Compare;
+ Compare comp(degree);
+ std::priority_queue<Vertex, std::vector<Vertex>, Compare> degree_queue(comp);
+
+ //step 1
+ //Scan for the vertex with the smallest degree and the maximum degree
+ typename graph_traits<Graph>::vertex_iterator ui, ui_end;
+ for (tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
+ {
+ dummy = get(degree, *ui);
+
+ if(dummy < my_degree)
+ {
+ my_degree = dummy;
+ s = *ui;
+ }
+
+ if(dummy > maximum_degree)
+ {
+ maximum_degree = dummy;
+ }
+ }
+ //end 1
+
+ do{
+ new_start = false; //Setting the loop repetition status to false
+
+ //step 2
+ //initialize the the disance std-vector with 0
+ for(typename std::vector<typename graph_traits<Graph>::vertices_size_type>::iterator iter = dist.begin(); iter != dist.end(); ++iter) *iter = 0;
+
+ //generating the RLS (rooted level structure)
+ breadth_first_search
+ (G, s, visitor
+ (
+ make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) )
+ )
+ );
+
+ //end 2
+
+ //step 3
+ //calculating the depth of the RLS
+ h_s = RLS_depth(dist);
+
+ //step 4
+ //pushing one node of each degree in an ascending manner into degree_queue
+ std::vector<bool> shrink_trace(maximum_degree, false);
+ for (tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
+ {
+ dummy = get(degree, *ui);
+
+ if( (dist[index_map[*ui]] == h_s ) && ( !shrink_trace[ dummy ] ) )
+ {
+ degree_queue.push(*ui);
+ shrink_trace[ dummy ] = true;
+ }
+ }
+
+ //end 3 & 4
+
+
+ //step 5
+ //Initializing w
+ w_e = MAXINT;
+ //end 5
+
+
+ //step 6
+ //Testing for termination
+ while( !degree_queue.empty() )
+ {
+ i = degree_queue.top(); //getting the node with the lowest degree from the degree queue
+ degree_queue.pop(); //ereasing the node with the lowest degree from the degree queue
+
+ //generating a RLS
+ for(typename std::vector<typename graph_traits<Graph>::vertices_size_type>::iterator iter = dist.begin(); iter != dist.end(); ++iter) *iter = 0;
+
+ breadth_first_search
+ (G, i, boost::visitor
+ (
+ make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) )
+ )
+ );
+
+ //Calculating depth and width of the rooted level
+ h_i = RLS_depth(dist);
+ w_i = RLS_max_width(dist, h_i);
+
+ //Testing for termination
+ if( (h_i > h_s) && (w_i < w_e) )
+ {
+ h_s = h_i;
+ s = i;
+ while(!degree_queue.empty()) degree_queue.pop();
+ new_start = true;
+ }
+ else if(w_i < w_e)
+ {
+ w_e = w_i;
+ e = i;
+ }
+ }
+ //end 6
+
+ }while(new_start);
+
+ return e;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Sloan algorithm with a given starting Vertex.
+ //
+ // This algorithm requires user to provide a starting vertex to
+ // compute Sloan ordering.
+ //////////////////////////////////////////////////////////////////////////
+ template <class Graph, class OutputIterator,
+ class ColorMap, class DegreeMap,
+ class PriorityMap, class Weight>
+ OutputIterator
+ sloan_ordering(Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor s,
+ typename graph_traits<Graph>::vertex_descriptor e,
+ OutputIterator permutation,
+ ColorMap color,
+ DegreeMap degree,
+ PriorityMap priority,
+ Weight W1,
+ Weight W2)
+ {
+ //typedef typename property_traits<DegreeMap>::value_type Degree;
+ typedef typename property_traits<PriorityMap>::value_type Degree;
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename std::vector<typename graph_traits<Graph>::vertices_size_type>::iterator vec_iter;
+ typedef typename graph_traits<Graph>::vertices_size_type size_type;
+
+ typedef typename property_map<Graph, vertex_index_t>::const_type VertexID;
+
+
+ //Creating a std-vector for storing the distance from the end vertex in it
+ typename std::vector<typename graph_traits<Graph>::vertices_size_type> dist(num_vertices(g), 0);
+
+ //Wrap a property_map_iterator around the std::iterator
+ boost::iterator_property_map<vec_iter, VertexID, size_type, size_type&> dist_pmap(dist.begin(), get(vertex_index, g));
+
+ breadth_first_search
+ (g, e, visitor
+ (
+ make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) )
+ )
+ );
+
+ //Creating a property_map for the indices of a vertex
+ typename property_map<Graph, vertex_index_t>::type index_map = get(vertex_index, g);
+
+ //Sets the color and priority to their initial status
+ unsigned cdeg;
+ typename graph_traits<Graph>::vertex_iterator ui, ui_end;
+ for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
+ {
+ put(color, *ui, Color::white());
+ cdeg=get(degree, *ui)+1;
+ put(priority, *ui, W1*dist[index_map[*ui]]-W2*cdeg );
+ }
+
+ //Priority list
+ typedef indirect_cmp<PriorityMap, std::greater<Degree> > Compare;
+ Compare comp(priority);
+ std::list<Vertex> priority_list;
+
+ //Some more declarations
+ typename graph_traits<Graph>::out_edge_iterator ei, ei_end, ei2, ei2_end;
+ Vertex u, v, w;
+
+ put(color, s, Color::green()); //Sets the color of the starting vertex to gray
+ priority_list.push_front(s); //Puts s into the priority_list
+
+ while ( !priority_list.empty() )
+ {
+ priority_list.sort(comp); //Orders the elements in the priority list in an ascending manner
+
+ u = priority_list.front(); //Accesses the last element in the priority list
+ priority_list.pop_front(); //Removes the last element in the priority list
+
+ if(get(color, u) == Color::green() )
+ {
+ //for-loop over all out-edges of vertex u
+ for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei)
+ {
+ v = target(*ei, g);
+
+ put( priority, v, get(priority, v) + W2 ); //updates the priority
+
+ if (get(color, v) == Color::white() ) //test if the vertex is inactive
+ {
+ put(color, v, Color::green() ); //giving the vertex a preactive status
+ priority_list.push_front(v); //writing the vertex in the priority_queue
+ }
+ }
+ }
+
+ //Here starts step 8
+ *permutation++ = u; //Puts u to the first position in the permutation-vector
+ put(color, u, Color::black() ); //Gives u an inactive status
+
+ //for loop over all the adjacent vertices of u
+ for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
+
+ v = target(*ei, g);
+
+ if (get(color, v) == Color::green() ) { //tests if the vertex is inactive
+
+ put(color, v, Color::red() ); //giving the vertex an active status
+ put(priority, v, get(priority, v)+W2); //updates the priority
+
+ //for loop over alll adjacent vertices of v
+ for (tie(ei2, ei2_end) = out_edges(v, g); ei2 != ei2_end; ++ei2) {
+ w = target(*ei2, g);
+
+ if(get(color, w) != Color::black() ) { //tests if vertex is postactive
+
+ put(priority, w, get(priority, w)+W2); //updates the priority
+
+ if(get(color, w) == Color::white() ){
+
+ put(color, w, Color::green() ); // gives the vertex a preactive status
+ priority_list.push_front(w); // puts the vertex into the priority queue
+
+ } //end if
+
+ } //end if
+
+ } //end for
+
+ } //end if
+
+ } //end for
+
+ } //end while
+
+
+ return permutation;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // Same algorithm as before, but without the weights given (taking default weights
+ template <class Graph, class OutputIterator,
+ class ColorMap, class DegreeMap,
+ class PriorityMap>
+ OutputIterator
+ sloan_ordering(Graph& g,
+ typename graph_traits<Graph>::vertex_descriptor s,
+ typename graph_traits<Graph>::vertex_descriptor e,
+ OutputIterator permutation,
+ ColorMap color,
+ DegreeMap degree,
+ PriorityMap priority)
+ {
+ return sloan_ordering(g, s, e, permutation, color, degree, priority, WEIGHT1, WEIGHT2);
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // Sloan algorithm without a given starting Vertex.
+ //
+ // This algorithm finds a good starting vertex itself to
+ // compute Sloan-ordering.
+ //////////////////////////////////////////////////////////////////////////
+
+
+
+ template < class Graph, class OutputIterator,
+ class Color, class Degree,
+ class Priority, class Weight>
+ inline OutputIterator
+ sloan_ordering(Graph& G,
+ OutputIterator permutation,
+ Color color,
+ Degree degree,
+ Priority priority,
+ Weight W1,
+ Weight W2 )
+ {
+ typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
+
+ Vertex s, e;
+ e = sloan_start_end_vertices(G, s, color, degree);
+
+ return sloan_ordering(G, s, e, permutation, color, degree, priority, W1, W2);
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // Same as before, but without given weights (default weights are taken instead)
+ template < class Graph, class OutputIterator,
+ class Color, class Degree,
+ class Priority >
+ inline OutputIterator
+ sloan_ordering(Graph& G,
+ OutputIterator permutation,
+ Color color,
+ Degree degree,
+ Priority priority)
+ {
+ return sloan_ordering(G, permutation, color, degree, priority, WEIGHT1, WEIGHT2);
+ }
+
+
+} // namespace boost
+
+
+#endif // BOOST_GRAPH_SLOAN_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/small_world_generator.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/small_world_generator.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,114 @@
+// Copyright 2004 The Trustees of Indiana University.
+
+// 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)
+
+// Authors: Douglas Gregor
+// Andrew Lumsdaine
+#ifndef BOOST_GRAPH_SMALL_WORLD_GENERATOR_HPP
+#define BOOST_GRAPH_SMALL_WORLD_GENERATOR_HPP
+
+#include <iterator>
+#include <utility>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/uniform_int.hpp>
+
+namespace boost {
+
+ // Assumes undirected
+ template<typename RandomGenerator, typename Graph>
+ class small_world_iterator
+ {
+ typedef typename graph_traits<Graph>::vertices_size_type
+ vertices_size_type;
+
+ public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::pair<vertices_size_type, vertices_size_type> value_type;
+ typedef const value_type& reference;
+ typedef const value_type* pointer;
+ typedef void difference_type;
+
+ small_world_iterator() : gen(0) {}
+ small_world_iterator(RandomGenerator& gen, vertices_size_type n,
+ vertices_size_type k, double prob = 0.0,
+ bool allow_self_loops = false)
+ : gen(&gen), n(n), k(k), prob(prob), source(0),
+ target(allow_self_loops? 0 : 1),
+ allow_self_loops(allow_self_loops),
+ current(0, allow_self_loops? 0 : 1)
+ { }
+
+ reference operator*() const { return current; }
+ pointer operator->() const { return ¤t; }
+
+ small_world_iterator& operator++()
+ {
+ target = (target + 1) % n;
+ if (target == (source + k/2 + 1) % n) {
+ ++source;
+ if (allow_self_loops) target = source;
+ else target = (source + 1) % n;
+ }
+ current.first = source;
+
+ uniform_01<RandomGenerator, double> rand01(*gen);
+ uniform_int<vertices_size_type> rand_vertex_gen(0, n-1);
+ double x = rand01();
+ *gen = rand01.base(); // GRRRR
+ if (x < prob) {
+ vertices_size_type lower = (source + n - k/2) % n;
+ vertices_size_type upper = (source + k/2) % n;
+ do {
+ current.second = rand_vertex_gen(*gen);
+ } while (current.second >= lower && current.second <= upper
+ || (upper < lower
+ && (current.second >= lower || current.second <= upper)));
+ } else {
+ current.second = target;
+ }
+ return *this;
+ }
+
+ small_world_iterator operator++(int)
+ {
+ small_world_iterator temp(*this);
+ ++(*this);
+ return temp;
+ }
+
+ bool operator==(const small_world_iterator& other) const
+ {
+ if (!gen && other.gen) return other == *this;
+ else if (gen && !other.gen) return source == n;
+ else if (!gen && !other.gen) return true;
+ return source == other.source && target == other.target;
+ }
+
+ bool operator!=(const small_world_iterator& other) const
+ { return !(*this == other); }
+
+ private:
+ void next()
+ {
+ uniform_int<vertices_size_type> rand_vertex(0, n-1);
+ current.first = rand_vertex(*gen);
+ do {
+ current.second = rand_vertex(*gen);
+ } while (current.first == current.second && !allow_self_loops);
+ }
+
+ RandomGenerator* gen;
+ vertices_size_type n;
+ vertices_size_type k;
+ double prob;
+ vertices_size_type source;
+ vertices_size_type target;
+ bool allow_self_loops;
+ value_type current;
+ };
+
+} // end namespace boost
+
+#endif // BOOST_GRAPH_SMALL_WORLD_GENERATOR_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/smallest_last_ordering.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/smallest_last_ordering.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,122 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+
+// Revision History:
+// 17 March 2006: Fixed a bug: when updating the degree a vertex
+// could be moved to a wrong bucket. (Roman Dementiev)
+//
+
+
+
+#ifndef BOOST_SMALLEST_LAST_VERTEX_ORDERING_HPP
+#define BOOST_SMALLEST_LAST_VERTEX_ORDERING_HPP
+/*
+ The smallest-last ordering is defined for the loopless graph G with
+ vertices a(j), j = 1,2,...,n where a(j) is the j-th column of A and
+ with edge (a(i),a(j)) if and only if columns i and j have a
+ non-zero in the same row position. The smallest-last ordering is
+ determined recursively by letting list(k), k = n,...,1 be a column
+ with least degree in the subgraph spanned by the un-ordered
+ columns.
+ */
+#include <vector>
+#include <algorithm>
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/pending/bucket_sorter.hpp>
+
+namespace boost {
+
+ template <class VertexListGraph, class Order, class Degree, class Marker>
+ void
+ smallest_last_vertex_ordering(const VertexListGraph& G, Order order,
+ Degree degree, Marker marker) {
+ typedef typename boost::graph_traits<VertexListGraph> GraphTraits;
+ typedef typename GraphTraits::vertex_descriptor Vertex;
+ //typedef typename GraphTraits::size_type size_type;
+ typedef std::size_t size_type;
+
+ const size_type num = num_vertices(G);
+
+ typedef typename boost::detail::vertex_property_map<VertexListGraph, vertex_index_t>::type ID;
+ typedef bucket_sorter<size_type, Vertex, Degree, ID> BucketSorter;
+
+ BucketSorter degree_bucket_sorter(num, num, degree,
+ get(vertex_index,G));
+
+ smallest_last_vertex_ordering(G, order, degree, marker, degree_bucket_sorter);
+ }
+
+ template <class VertexListGraph, class Order, class Degree,
+ class Marker, class BucketSorter>
+ void
+ smallest_last_vertex_ordering(const VertexListGraph& G, Order order,
+ Degree degree, Marker marker,
+ BucketSorter& degree_buckets) {
+ typedef typename boost::graph_traits<VertexListGraph> GraphTraits;
+ typedef typename GraphTraits::vertex_descriptor Vertex;
+ //typedef typename GraphTraits::size_type size_type;
+ typedef std::size_t size_type;
+
+ const size_type num = num_vertices(G);
+
+ typename GraphTraits::vertex_iterator v, vend;
+ for (boost::tie(v, vend) = vertices(G); v != vend; ++v) {
+ put(marker, *v, num);
+ put(degree, *v, out_degree(*v, G));
+ degree_buckets.push(*v);
+ }
+
+ size_type minimum_degree = 0;
+ size_type current_order = num - 1;
+
+ while ( 1 ) {
+ typedef typename BucketSorter::stack MDStack;
+ MDStack minimum_degree_stack = degree_buckets[minimum_degree];
+ while (minimum_degree_stack.empty())
+ minimum_degree_stack = degree_buckets[++minimum_degree];
+
+ Vertex node = minimum_degree_stack.top();
+ put(order, current_order, node);
+
+ if ( current_order == 0 ) //find all vertices
+ break;
+
+ minimum_degree_stack.pop();
+ put(marker, node, 0); //node has been ordered.
+
+ typename GraphTraits::adjacency_iterator v, vend;
+ for (boost::tie(v,vend) = adjacent_vertices(node, G); v != vend; ++v)
+
+ if ( get(marker,*v) > current_order ) { //*v is unordered vertex
+ put(marker, *v, current_order); //mark the columns adjacent to node
+
+ //delete *v from the bucket sorter
+ degree_buckets.remove(*v);
+
+ //It is possible minimum degree goes down
+ //Here we keep tracking it.
+ put(degree, *v, get(degree, *v) - 1);
+ BOOST_USING_STD_MIN();
+ minimum_degree = min BOOST_PREVENT_MACRO_SUBSTITUTION(minimum_degree, get(degree, *v));
+
+ //reinsert *v in the bucket sorter with the new degree
+ degree_buckets.push(*v);
+ }
+
+ current_order--;
+ }
+
+ //at this point, order[i] = v_i;
+ }
+
+}
+
+#endif
+
Added: branches/CMake/release/libs/graph/include/boost/graph/stanford_graph.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/stanford_graph.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,565 @@
+//=======================================================================
+// Copyright 1997-2001 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+#ifndef BOOST_GRAPH_SGB_GRAPH_HPP
+#define BOOST_GRAPH_SGB_GRAPH_HPP
+
+#include <boost/config.hpp>
+#include <boost/iterator.hpp>
+#include <boost/operators.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+
+// Thanks to Andreas Scherer for numerous suggestions and fixes!
+
+// This file adapts a Stanford GraphBase (SGB) Graph pointer into a
+// VertexListGraph. Note that a graph adaptor class is not needed,
+// SGB's Graph* is used as is. The VertexListGraph concept is fulfilled by
+// defining the appropriate non-member functions for Graph*.
+//
+// The PROTOTYPES change file extensions to SGB must be applied so
+// that the SGB functions have real prototypes which are necessary for
+// the C++ compiler. To apply the PROTOTYPES extensions, before you do
+// "make tests install" for SGB do "ln -s PROTOTYPES/* ." to the SGB
+// root directory (or just copy all the files from the PROTOTYPES
+// directory to the SGB root directory).
+//
+extern "C" {
+ // We include all global definitions for the general stuff
+ // of The Stanford GraphBase and its various graph generator
+ // functions by reading all SGB headerfiles as in section 2 of
+ // the "test_sample" program.
+#include <gb_graph.h> /* SGB data structures */
+#include <gb_io.h> /* SGB input/output routines */
+#include <gb_flip.h> /* random number generator */
+#include <gb_dijk.h> /* routines for shortest paths */
+#include <gb_basic.h> /* the basic graph operations */
+#undef empty /* avoid name clash with C++ standard library */
+ inline Graph* empty( long n ) /* and provide workaround */
+ { return board(n,0L,0L,0L,2L,0L,0L); }
+#include <gb_books.h> /* graphs based on literature */
+#include <gb_econ.h> /* graphs based on economic data */
+#include <gb_games.h> /* graphs based on football scores */
+#include <gb_gates.h> /* graphs based on logic circuits */
+#undef val /* avoid name clash with g++ headerfile stl_tempbuf.h */
+ // val ==> Vertex::x.I
+#include <gb_lisa.h> /* graphs based on Mona Lisa */
+#include <gb_miles.h> /* graphs based on mileage data */
+#include <gb_plane.h> /* planar graphs */
+#include <gb_raman.h> /* Ramanujan graphs */
+#include <gb_rand.h> /* random graphs */
+#include <gb_roget.h> /* graphs based on Roget's Thesaurus */
+#include <gb_save.h> /* we save results in ASCII format */
+#include <gb_words.h> /* five-letter-word graphs */
+#undef weight /* avoid name clash with BGL parameter */
+ // weight ==> Vertex::u.I
+}
+
+namespace boost {
+ class sgb_edge;
+}
+
+class sgb_out_edge_iterator;
+class sgb_adj_iterator;
+class sgb_vertex_iterator;
+
+namespace boost {
+ typedef Graph* sgb_graph_ptr;
+ typedef const Graph* sgb_const_graph_ptr;
+
+ struct sgb_traversal_tag :
+ public virtual vertex_list_graph_tag,
+ public virtual incidence_graph_tag,
+ public virtual adjacency_graph_tag { };
+
+ template <> struct graph_traits<sgb_graph_ptr> {
+ typedef Vertex* vertex_descriptor;
+ typedef boost::sgb_edge edge_descriptor;
+ typedef sgb_out_edge_iterator out_edge_iterator;
+ typedef void in_edge_iterator;
+ typedef sgb_adj_iterator adjacency_iterator;
+ typedef sgb_vertex_iterator vertex_iterator;
+ typedef void edge_iterator;
+ typedef long vertices_size_type;
+ typedef long edge_size_type;
+ typedef long degree_size_type;
+ typedef directed_tag directed_category;
+ typedef sgb_traversal_tag traversal_category;
+ typedef allow_parallel_edge_tag edge_parallel_category;
+ };
+ template <> struct graph_traits<sgb_const_graph_ptr> {
+ typedef Vertex* vertex_descriptor;
+ typedef boost::sgb_edge edge_descriptor;
+ typedef sgb_out_edge_iterator out_edge_iterator;
+ typedef void in_edge_iterator;
+ typedef sgb_adj_iterator adjacency_iterator;
+ typedef sgb_vertex_iterator vertex_iterator;
+ typedef void edge_iterator;
+ typedef long vertices_size_type;
+ typedef long edge_size_type;
+ typedef long degree_size_type;
+ typedef directed_tag directed_category;
+ typedef sgb_traversal_tag traversal_category;
+ typedef allow_parallel_edge_tag edge_parallel_category;
+ };
+}
+
+namespace boost {
+
+ struct edge_length_t {
+ typedef edge_property_tag kind;
+ };
+
+ // We could just use Arc* as the edge descriptor type, but
+ // we want to add the source(e,g) function which requires
+ // that we carry along a pointer to the source vertex.
+ class sgb_edge {
+ typedef sgb_edge self;
+ public:
+ sgb_edge() : _arc(0), _src(0) { }
+ sgb_edge(Arc* a, Vertex* s) : _arc(a), _src(s) { }
+ friend Vertex* source(self e, sgb_const_graph_ptr) { return e._src; }
+ friend Vertex* target(self e, sgb_const_graph_ptr) { return e._arc->tip; }
+ friend bool operator==(const self& a, const self& b) {
+ return a._arc == b._arc; }
+ friend bool operator!=(const self& a, const self& b) {
+ return a._arc != b._arc; }
+#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+ template <class Ref> friend class sgb_edge_length_map;
+ template <class Tag, class Ref> friend class sgb_edge_util_map;
+ friend long get(edge_length_t, const sgb_graph_ptr&, const sgb_edge& key);
+ friend long get(edge_length_t, const sgb_const_graph_ptr&, const sgb_edge& key);
+ friend void put(edge_length_t, sgb_graph_ptr&, const sgb_edge& key, long value);
+ protected:
+#endif
+ Arc* _arc;
+ Vertex* _src;
+ };
+} // namespace boost
+
+ class sgb_out_edge_iterator
+ : public boost::forward_iterator_helper<
+ sgb_out_edge_iterator, boost::sgb_edge,
+ std::ptrdiff_t, boost::sgb_edge*, boost::sgb_edge>
+ {
+ typedef sgb_out_edge_iterator self;
+ public:
+ sgb_out_edge_iterator() : _src(0), _arc(0) {}
+ sgb_out_edge_iterator(Vertex* s, Arc* d) : _src(s), _arc(d) {}
+ boost::sgb_edge operator*() { return boost::sgb_edge(_arc, _src); }
+ self& operator++() { _arc = _arc->next; return *this; }
+ friend bool operator==(const self& x, const self& y) {
+ return x._arc == y._arc; }
+ protected:
+ Vertex* _src;
+ Arc* _arc;
+ };
+
+ class sgb_adj_iterator
+ : public boost::forward_iterator_helper<
+ sgb_adj_iterator, Vertex*, std::ptrdiff_t, Vertex**,Vertex*>
+ {
+ typedef sgb_adj_iterator self;
+ public:
+ sgb_adj_iterator() : _arc(0) {}
+ sgb_adj_iterator(Arc* d) : _arc(d) {}
+ Vertex* operator*() { return _arc->tip; }
+ self& operator++() { _arc = _arc->next; return *this; }
+ friend bool operator==(const self& x, const self& y) {
+ return x._arc == y._arc; }
+ protected:
+ Arc* _arc;
+ };
+
+ // The reason we have this instead of just using Vertex* is that we
+ // want to use Vertex* as the vertex_descriptor instead of just
+ // Vertex, which avoids problems with boost passing vertex descriptors
+ // by value and how that interacts with the sgb_vertex_id_map.
+ class sgb_vertex_iterator
+ : public boost::forward_iterator_helper<
+ sgb_vertex_iterator, Vertex*, std::ptrdiff_t, Vertex**, Vertex*>
+ {
+ typedef sgb_vertex_iterator self;
+ public:
+ sgb_vertex_iterator() : _v(0) { }
+ sgb_vertex_iterator(Vertex* v) : _v(v) { }
+ Vertex* operator*() { return _v; }
+ self& operator++() { ++_v; return *this; }
+ friend bool operator==(const self& x, const self& y) {
+ return x._v == y._v; }
+ protected:
+ Vertex* _v;
+ };
+
+namespace boost {
+
+ inline std::pair<sgb_vertex_iterator,sgb_vertex_iterator>
+ vertices(sgb_const_graph_ptr g)
+ {
+ return std::make_pair(sgb_vertex_iterator(g->vertices),
+ sgb_vertex_iterator(g->vertices + g->n));
+ }
+
+ inline std::pair<sgb_out_edge_iterator,sgb_out_edge_iterator>
+ out_edges(Vertex* u, sgb_const_graph_ptr)
+ {
+ return std::make_pair( sgb_out_edge_iterator(u, u->arcs),
+ sgb_out_edge_iterator(u, 0) );
+ }
+
+ inline boost::graph_traits<sgb_graph_ptr>::degree_size_type
+ out_degree(Vertex* u, sgb_const_graph_ptr g)
+ {
+ boost::graph_traits<sgb_graph_ptr>::out_edge_iterator i, i_end;
+ boost::tie(i, i_end) = out_edges(u, g);
+ return std::distance(i, i_end);
+ }
+
+ // in_edges?
+
+ inline std::pair<sgb_adj_iterator,sgb_adj_iterator>
+ adjacent_vertices(Vertex* u, sgb_const_graph_ptr)
+ {
+ return std::make_pair( sgb_adj_iterator(u->arcs),
+ sgb_adj_iterator(0) );
+ }
+
+ inline long num_vertices(sgb_const_graph_ptr g) { return g->n; }
+ inline long num_edges(sgb_const_graph_ptr g) { return g->m; }
+
+ inline Vertex* vertex(long v, sgb_const_graph_ptr g)
+ { return g->vertices + v; }
+
+ // Various Property Maps
+
+ // Vertex ID
+ class sgb_vertex_id_map
+ : public boost::put_get_helper<long, sgb_vertex_id_map>
+ {
+ public:
+ typedef boost::readable_property_map_tag category;
+ typedef long value_type;
+ typedef long reference;
+ typedef Vertex* key_type;
+ sgb_vertex_id_map() : _g(0) { }
+ sgb_vertex_id_map(sgb_graph_ptr g) : _g(g) { }
+ long operator[](Vertex* v) const { return v - _g->vertices; }
+ protected:
+ sgb_graph_ptr _g;
+ };
+ inline sgb_vertex_id_map get(vertex_index_t, sgb_graph_ptr g) {
+ return sgb_vertex_id_map(g);
+ }
+
+ // Vertex Name
+ class sgb_vertex_name_map
+ : public boost::put_get_helper<char*, sgb_vertex_name_map>
+ {
+ public:
+ typedef boost::readable_property_map_tag category;
+ typedef char* value_type;
+ typedef char* reference;
+ typedef Vertex* key_type;
+ char* operator[](Vertex* v) const { return v->name; }
+ };
+ inline sgb_vertex_name_map get(vertex_name_t, sgb_graph_ptr) {
+ return sgb_vertex_name_map();
+ }
+
+ // Vertex Property Tags
+#define SGB_PROPERTY_TAG(KIND,TAG) \
+ template <class T> struct TAG##_property { \
+ typedef KIND##_property_tag kind; \
+ typedef T type; \
+ };
+ SGB_PROPERTY_TAG(vertex, u)
+ SGB_PROPERTY_TAG(vertex, v)
+ SGB_PROPERTY_TAG(vertex, w)
+ SGB_PROPERTY_TAG(vertex, x)
+ SGB_PROPERTY_TAG(vertex, y)
+ SGB_PROPERTY_TAG(vertex, z)
+
+ // Edge Property Tags
+ SGB_PROPERTY_TAG(edge, a)
+ SGB_PROPERTY_TAG(edge, b)
+
+ // Various Utility Maps
+
+ // helpers
+ inline Vertex*& get_util(util& u, Vertex*) { return u.V; }
+ inline Arc*& get_util(util& u, Arc*) { return u.A; }
+ inline sgb_graph_ptr& get_util(util& u, sgb_graph_ptr) { return u.G; }
+ inline char*& get_util(util& u, char*) { return u.S; }
+ inline long& get_util(util& u, long) { return u.I; }
+
+#define SGB_GET_UTIL_FIELD(KIND,X) \
+ template <class T> \
+ inline T& get_util_field(KIND* k, X##_property<T>) { \
+ return get_util(k->X, T()); }
+
+ SGB_GET_UTIL_FIELD(Vertex, u)
+ SGB_GET_UTIL_FIELD(Vertex, v)
+ SGB_GET_UTIL_FIELD(Vertex, w)
+ SGB_GET_UTIL_FIELD(Vertex, x)
+ SGB_GET_UTIL_FIELD(Vertex, y)
+ SGB_GET_UTIL_FIELD(Vertex, z)
+
+ SGB_GET_UTIL_FIELD(Arc, a)
+ SGB_GET_UTIL_FIELD(Arc, b)
+
+ // Vertex Utility Map
+ template <class Tag, class Ref>
+ class sgb_vertex_util_map
+ : public boost::put_get_helper<Ref, sgb_vertex_util_map<Tag, Ref> >
+ {
+ public:
+ typedef boost::lvalue_property_map_tag category;
+ typedef typename Tag::type value_type;
+ typedef Vertex* key_type;
+ typedef Ref reference;
+ reference operator[](Vertex* v) const {
+ return get_util_field(v, Tag());
+ }
+ };
+
+ // Edge Utility Map
+ template <class Tag, class Ref>
+ class sgb_edge_util_map
+ : public boost::put_get_helper<Ref, sgb_edge_util_map<Tag, Ref> >
+ {
+ public:
+ typedef boost::lvalue_property_map_tag category;
+ typedef typename Tag::type value_type;
+ typedef Vertex* key_type;
+ typedef Ref reference;
+ reference operator[](const sgb_edge& e) const {
+ return get_util_field(e._arc, Tag());
+ }
+ };
+
+#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+ template <class Tag>
+ inline sgb_vertex_util_map<Tag, const typename Tag::type&>
+ get_property_map(Tag, const sgb_graph_ptr& g, vertex_property_tag) {
+ return sgb_vertex_util_map<Tag, const typename Tag::type&>();
+ }
+ template <class Tag>
+ inline sgb_vertex_util_map<Tag, typename Tag::type&>
+ get_property_map(Tag, sgb_graph_ptr& g, vertex_property_tag) {
+ return sgb_vertex_util_map<Tag, typename Tag::type&>();
+ }
+
+ template <class Tag>
+ inline sgb_edge_util_map<Tag, const typename Tag::type&>
+ get_property_map(Tag, const sgb_graph_ptr& g, edge_property_tag) {
+ return sgb_edge_util_map<Tag, const typename Tag::type&>();
+ }
+ template <class Tag>
+ inline sgb_edge_util_map<Tag, typename Tag::type&>
+ get_property_map(Tag, sgb_graph_ptr& g, edge_property_tag) {
+ return sgb_edge_util_map<Tag, typename Tag::type&>();
+ }
+
+#endif // ! BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+ // Edge Length Access
+ template <class Ref>
+ class sgb_edge_length_map
+ : public boost::put_get_helper<Ref, sgb_edge_length_map<Ref> >
+ {
+ public:
+ typedef boost::lvalue_property_map_tag category;
+ typedef long value_type;
+ typedef sgb_edge key_type;
+ typedef Ref reference;
+ reference operator[](const sgb_edge& e) const {
+ return e._arc->len;
+ }
+ };
+
+ inline sgb_edge_length_map<const long&>
+ get(edge_length_t, const sgb_graph_ptr&) {
+ return sgb_edge_length_map<const long&>();
+ }
+ inline sgb_edge_length_map<const long&>
+ get(edge_length_t, const sgb_const_graph_ptr&) {
+ return sgb_edge_length_map<const long&>();
+ }
+ inline sgb_edge_length_map<long&>
+ get(edge_length_t, sgb_graph_ptr&) {
+ return sgb_edge_length_map<long&>();
+ }
+ inline long
+ get(edge_length_t, const sgb_graph_ptr&, const sgb_edge& key) {
+ return key._arc->len;
+ }
+ inline long
+ get(edge_length_t, const sgb_const_graph_ptr&, const sgb_edge& key) {
+ return key._arc->len;
+ }
+ inline void
+ put(edge_length_t, sgb_graph_ptr&, const sgb_edge& key, long value)
+ {
+ key._arc->len = value;
+ }
+
+ // Property Map Traits Classes
+ template <>
+ struct property_map<sgb_graph_ptr, edge_length_t> {
+ typedef sgb_edge_length_map<long&> type;
+ typedef sgb_edge_length_map<const long&> const_type;
+ };
+ template <>
+ struct property_map<sgb_graph_ptr, vertex_index_t> {
+ typedef sgb_vertex_id_map type;
+ typedef sgb_vertex_id_map const_type;
+ };
+ template <>
+ struct property_map<sgb_graph_ptr, vertex_name_t> {
+ typedef sgb_vertex_name_map type;
+ typedef sgb_vertex_name_map const_type;
+ };
+
+ template <>
+ struct property_map<sgb_const_graph_ptr, edge_length_t> {
+ typedef sgb_edge_length_map<const long&> const_type;
+ };
+ template <>
+ struct property_map<sgb_const_graph_ptr, vertex_index_t> {
+ typedef sgb_vertex_id_map const_type;
+ };
+ template <>
+ struct property_map<sgb_const_graph_ptr, vertex_name_t> {
+ typedef sgb_vertex_name_map const_type;
+ };
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+ namespace detail {
+ template <class Kind, class PropertyTag>
+ struct sgb_choose_property_map { };
+ template <class PropertyTag>
+ struct sgb_choose_property_map<vertex_property_tag, PropertyTag> {
+ typedef typename PropertyTag::type value_type;
+ typedef sgb_vertex_util_map<PropertyTag, value_type&> type;
+ typedef sgb_vertex_util_map<PropertyTag, const value_type&> const_type;
+ };
+ template <class PropertyTag>
+ struct sgb_choose_property_map<edge_property_tag, PropertyTag> {
+ typedef typename PropertyTag::type value_type;
+ typedef sgb_edge_util_map<PropertyTag, value_type&> type;
+ typedef sgb_edge_util_map<PropertyTag, const value_type&> const_type;
+ };
+ } // namespace detail
+ template <class PropertyTag>
+ struct property_map<sgb_graph_ptr, PropertyTag> {
+ typedef typename property_kind<PropertyTag>::type Kind;
+ typedef detail::sgb_choose_property_map<Kind, PropertyTag> Choice;
+ typedef typename Choice::type type;
+ typedef typename Choice::const_type const_type;
+ };
+ template <class PropertyTag>
+ struct property_map<sgb_const_graph_ptr, PropertyTag> {
+ typedef typename property_kind<PropertyTag>::type Kind;
+ typedef detail::sgb_choose_property_map<Kind, PropertyTag> Choice;
+ typedef typename Choice::const_type const_type;
+ };
+
+#define SGB_UTIL_ACCESSOR(KIND,X) \
+ template <class T> \
+ inline sgb_##KIND##_util_map< X##_property<T>, T&> \
+ get(X##_property<T>, sgb_graph_ptr&) { \
+ return sgb_##KIND##_util_map< X##_property<T>, T&>(); \
+ } \
+ template <class T> \
+ inline sgb_##KIND##_util_map< X##_property<T>, const T&> \
+ get(X##_property<T>, const sgb_graph_ptr&) { \
+ return sgb_##KIND##_util_map< X##_property<T>, const T&>(); \
+ } \
+ template <class T> \
+ inline sgb_##KIND##_util_map< X##_property<T>, const T&> \
+ get(X##_property<T>, const sgb_const_graph_ptr&) { \
+ return sgb_##KIND##_util_map< X##_property<T>, const T&>(); \
+ } \
+ template <class T, class Key> \
+ inline typename \
+ sgb_##KIND##_util_map< X##_property<T>, const T&>::value_type \
+ get(X##_property<T>, const sgb_graph_ptr&, const Key& key) { \
+ return sgb_##KIND##_util_map< X##_property<T>, const T&>()[key]; \
+ } \
+ template <class T, class Key> \
+ inline typename \
+ sgb_##KIND##_util_map< X##_property<T>, const T&>::value_type \
+ get(X##_property<T>, const sgb_const_graph_ptr&, const Key& key) { \
+ return sgb_##KIND##_util_map< X##_property<T>, const T&>()[key]; \
+ } \
+ template <class T, class Key, class Value> \
+ inline void \
+ put(X##_property<T>, sgb_graph_ptr&, const Key& key, const Value& value) { \
+ sgb_##KIND##_util_map< X##_property<T>, T&>()[key] = value; \
+ }
+
+#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+#define SGB_UTIL_ACCESSOR_TYPE(KIND,TAG,TYPE) \
+ inline sgb_##KIND##_util_map< TAG<TYPE>, TYPE& > \
+ get(TAG<TYPE>, sgb_graph_ptr&) { \
+ return sgb_##KIND##_util_map< TAG<TYPE>, TYPE& >(); \
+ } \
+ inline sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& > \
+ get(TAG<TYPE>, const sgb_graph_ptr&) { \
+ return sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& >(); \
+ } \
+ inline sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& > \
+ get(TAG<TYPE>, const sgb_const_graph_ptr&) { \
+ return sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& >(); \
+ } \
+ template <class Key> \
+ inline typename sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& >::value_type \
+ get(TAG<TYPE>, const sgb_graph_ptr&, const Key& key) { \
+ return sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& >()[key]; \
+ } \
+ template <class Key> \
+ inline typename sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& >::value_type \
+ get(TAG<TYPE>, const sgb_const_graph_ptr&, const Key& key) { \
+ return sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& >()[key]; \
+ } \
+ template <class Key, class Value> \
+ inline void \
+ put(TAG<TYPE>, sgb_graph_ptr&, const Key& key, const Value& value) { \
+ sgb_##KIND##_util_map< TAG<TYPE>, TYPE& >()[key] = value; \
+ } \
+ template <> struct property_map<sgb_graph_ptr, TAG<TYPE> > { \
+ typedef sgb_##KIND##_util_map< TAG<TYPE>, TYPE&> type; \
+ typedef sgb_##KIND##_util_map< TAG<TYPE>, const TYPE&> const_type; \
+ }
+
+#define SGB_UTIL_ACCESSOR(KIND,TAG) \
+ SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, Vertex*); \
+ SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, Arc*); \
+ SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, sgb_graph_ptr); \
+ SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, long); \
+ SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, char*);
+
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+ SGB_UTIL_ACCESSOR(vertex, u)
+ SGB_UTIL_ACCESSOR(vertex, v)
+ SGB_UTIL_ACCESSOR(vertex, w)
+ SGB_UTIL_ACCESSOR(vertex, x)
+ SGB_UTIL_ACCESSOR(vertex, y)
+ SGB_UTIL_ACCESSOR(vertex, z)
+
+ SGB_UTIL_ACCESSOR(edge, a)
+ SGB_UTIL_ACCESSOR(edge, b)
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_SGB_GRAPH_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/strong_components.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/strong_components.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,334 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+
+#ifndef BOOST_GRAPH_STRONG_COMPONENTS_HPP
+#define BOOST_GRAPH_STRONG_COMPONENTS_HPP
+
+#include <stack>
+#include <boost/config.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/type_traits/conversion_traits.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost {
+
+ //==========================================================================
+ // This is Tarjan's algorithm for strongly connected components
+ // from his paper "Depth first search and linear graph algorithms".
+ // It calculates the components in a single application of DFS.
+ // We implement the algorithm as a dfs-visitor.
+
+ namespace detail {
+
+ template <typename ComponentMap, typename RootMap, typename DiscoverTime,
+ typename Stack>
+ class tarjan_scc_visitor : public dfs_visitor<>
+ {
+ typedef typename property_traits<ComponentMap>::value_type comp_type;
+ typedef typename property_traits<DiscoverTime>::value_type time_type;
+ public:
+ tarjan_scc_visitor(ComponentMap comp_map, RootMap r, DiscoverTime d,
+ comp_type& c_, Stack& s_)
+ : c(c_), comp(comp_map), root(r), discover_time(d),
+ dfs_time(time_type()), s(s_) { }
+
+ template <typename Graph>
+ void discover_vertex(typename graph_traits<Graph>::vertex_descriptor v,
+ const Graph&) {
+ put(root, v, v);
+ put(comp, v, (std::numeric_limits<comp_type>::max)());
+ put(discover_time, v, dfs_time++);
+ s.push(v);
+ }
+ template <typename Graph>
+ void finish_vertex(typename graph_traits<Graph>::vertex_descriptor v,
+ const Graph& g) {
+ typename graph_traits<Graph>::vertex_descriptor w;
+ typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = out_edges(v, g); ei != ei_end; ++ei) {
+ w = target(*ei, g);
+ if (get(comp, w) == (std::numeric_limits<comp_type>::max)())
+ put(root, v, this->min_discover_time(get(root,v), get(root,w)));
+ }
+ if (get(root, v) == v) {
+ do {
+ w = s.top(); s.pop();
+ put(comp, w, c);
+ } while (w != v);
+ ++c;
+ }
+ }
+ private:
+ template <typename Vertex>
+ Vertex min_discover_time(Vertex u, Vertex v) {
+ return get(discover_time, u) < get(discover_time,v) ? u : v;
+ }
+
+ comp_type& c;
+ ComponentMap comp;
+ RootMap root;
+ DiscoverTime discover_time;
+ time_type dfs_time;
+ Stack& s;
+ };
+
+ template <class Graph, class ComponentMap, class RootMap,
+ class DiscoverTime, class P, class T, class R>
+ typename property_traits<ComponentMap>::value_type
+ strong_components_impl
+ (const Graph& g, // Input
+ ComponentMap comp, // Output
+ // Internal record keeping
+ RootMap root,
+ DiscoverTime discover_time,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ function_requires< ReadWritePropertyMapConcept<ComponentMap, Vertex> >();
+ function_requires< ReadWritePropertyMapConcept<RootMap, Vertex> >();
+ typedef typename property_traits<RootMap>::value_type RootV;
+ function_requires< ConvertibleConcept<RootV, Vertex> >();
+ function_requires< ReadWritePropertyMapConcept<DiscoverTime, Vertex> >();
+
+ typename property_traits<ComponentMap>::value_type total = 0;
+
+ std::stack<Vertex> s;
+ detail::tarjan_scc_visitor<ComponentMap, RootMap, DiscoverTime,
+ std::stack<Vertex> >
+ vis(comp, root, discover_time, total, s);
+ depth_first_search(g, params.visitor(vis));
+ return total;
+ }
+
+ //-------------------------------------------------------------------------
+ // The dispatch functions handle the defaults for the rank and discover
+ // time property maps.
+ // dispatch with class specialization to avoid VC++ bug
+
+ template <class DiscoverTimeMap>
+ struct strong_comp_dispatch2 {
+ template <class Graph, class ComponentMap, class RootMap, class P, class T, class R>
+ inline static typename property_traits<ComponentMap>::value_type
+ apply(const Graph& g,
+ ComponentMap comp,
+ RootMap r_map,
+ const bgl_named_params<P, T, R>& params,
+ DiscoverTimeMap time_map)
+ {
+ return strong_components_impl(g, comp, r_map, time_map, params);
+ }
+ };
+
+
+ template <>
+ struct strong_comp_dispatch2<detail::error_property_not_found> {
+ template <class Graph, class ComponentMap, class RootMap,
+ class P, class T, class R>
+ inline static typename property_traits<ComponentMap>::value_type
+ apply(const Graph& g,
+ ComponentMap comp,
+ RootMap r_map,
+ const bgl_named_params<P, T, R>& params,
+ detail::error_property_not_found)
+ {
+ typedef typename graph_traits<Graph>::vertices_size_type size_type;
+ size_type n = num_vertices(g) > 0 ? num_vertices(g) : 1;
+ std::vector<size_type> time_vec(n);
+ return strong_components_impl
+ (g, comp, r_map,
+ make_iterator_property_map(time_vec.begin(), choose_const_pmap
+ (get_param(params, vertex_index),
+ g, vertex_index), time_vec[0]),
+ params);
+ }
+ };
+
+ template <class Graph, class ComponentMap, class RootMap,
+ class P, class T, class R, class DiscoverTimeMap>
+ inline typename property_traits<ComponentMap>::value_type
+ scc_helper2(const Graph& g,
+ ComponentMap comp,
+ RootMap r_map,
+ const bgl_named_params<P, T, R>& params,
+ DiscoverTimeMap time_map)
+ {
+ return strong_comp_dispatch2<DiscoverTimeMap>::apply(g, comp, r_map, params, time_map);
+ }
+
+ template <class RootMap>
+ struct strong_comp_dispatch1 {
+
+ template <class Graph, class ComponentMap, class P, class T, class R>
+ inline static typename property_traits<ComponentMap>::value_type
+ apply(const Graph& g,
+ ComponentMap comp,
+ const bgl_named_params<P, T, R>& params,
+ RootMap r_map)
+ {
+ return scc_helper2(g, comp, r_map, params, get_param(params, vertex_discover_time));
+ }
+ };
+ template <>
+ struct strong_comp_dispatch1<detail::error_property_not_found> {
+
+ template <class Graph, class ComponentMap,
+ class P, class T, class R>
+ inline static typename property_traits<ComponentMap>::value_type
+ apply(const Graph& g,
+ ComponentMap comp,
+ const bgl_named_params<P, T, R>& params,
+ detail::error_property_not_found)
+ {
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typename std::vector<Vertex>::size_type
+ n = num_vertices(g) > 0 ? num_vertices(g) : 1;
+ std::vector<Vertex> root_vec(n);
+ return scc_helper2
+ (g, comp,
+ make_iterator_property_map(root_vec.begin(), choose_const_pmap
+ (get_param(params, vertex_index),
+ g, vertex_index), root_vec[0]),
+ params,
+ get_param(params, vertex_discover_time));
+ }
+ };
+
+ template <class Graph, class ComponentMap, class RootMap,
+ class P, class T, class R>
+ inline typename property_traits<ComponentMap>::value_type
+ scc_helper1(const Graph& g,
+ ComponentMap comp,
+ const bgl_named_params<P, T, R>& params,
+ RootMap r_map)
+ {
+ return detail::strong_comp_dispatch1<RootMap>::apply(g, comp, params,
+ r_map);
+ }
+
+ } // namespace detail
+
+ template <class Graph, class ComponentMap,
+ class P, class T, class R>
+ inline typename property_traits<ComponentMap>::value_type
+ strong_components(const Graph& g, ComponentMap comp,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef typename graph_traits<Graph>::directed_category DirCat;
+ BOOST_STATIC_ASSERT((is_convertible<DirCat*, directed_tag*>::value == true));
+ return detail::scc_helper1(g, comp, params,
+ get_param(params, vertex_root_t()));
+ }
+
+ template <class Graph, class ComponentMap>
+ inline typename property_traits<ComponentMap>::value_type
+ strong_components(const Graph& g, ComponentMap comp)
+ {
+ typedef typename graph_traits<Graph>::directed_category DirCat;
+ BOOST_STATIC_ASSERT((is_convertible<DirCat*, directed_tag*>::value == true));
+ bgl_named_params<int, int> params(0);
+ return strong_components(g, comp, params);
+ }
+
+ template <typename Graph, typename ComponentMap, typename ComponentLists>
+ void build_component_lists
+ (const Graph& g,
+ typename graph_traits<Graph>::vertices_size_type num_scc,
+ ComponentMap component_number,
+ ComponentLists& components)
+ {
+ components.resize(num_scc);
+ typename graph_traits<Graph>::vertex_iterator vi, vi_end;
+ for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
+ components[component_number[*vi]].push_back(*vi);
+ }
+
+
+} // namespace boost
+
+#include <queue>
+#include <vector>
+#include <boost/graph/transpose_graph.hpp>
+#include <boost/pending/indirect_cmp.hpp>
+#include <boost/graph/connected_components.hpp> // for components_recorder
+
+namespace boost {
+
+ //==========================================================================
+ // This is the version of strongly connected components from
+ // "Intro. to Algorithms" by Cormen, Leiserson, Rivest, which was
+ // adapted from "Data Structure and Algorithms" by Aho, Hopcroft,
+ // and Ullman, who credit the algorithm to S.R. Kosaraju and M. Sharir.
+ // The algorithm is based on computing DFS forests the graph
+ // and its transpose.
+
+ // This algorithm is slower than Tarjan's by a constant factor, uses
+ // more memory, and puts more requirements on the graph type.
+
+ template <class Graph, class DFSVisitor, class ComponentsMap,
+ class DiscoverTime, class FinishTime,
+ class ColorMap>
+ typename property_traits<ComponentsMap>::value_type
+ kosaraju_strong_components(Graph& G, ComponentsMap c,
+ FinishTime finish_time, ColorMap color)
+ {
+ function_requires< MutableGraphConcept<Graph> >();
+ // ...
+
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef typename property_traits<ColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+ typename property_traits<FinishTime>::value_type time = 0;
+ depth_first_search
+ (G, make_dfs_visitor(stamp_times(finish_time, time, on_finish_vertex())),
+ color);
+
+ Graph G_T(num_vertices(G));
+ transpose_graph(G, G_T);
+
+ typedef typename property_traits<ComponentsMap>::value_type count_type;
+
+ count_type c_count(0);
+ detail::components_recorder<ComponentsMap>
+ vis(c, c_count);
+
+ // initialize G_T
+ typename graph_traits<Graph>::vertex_iterator ui, ui_end;
+ for (tie(ui, ui_end) = vertices(G_T); ui != ui_end; ++ui)
+ put(color, *ui, Color::white());
+
+ typedef typename property_traits<FinishTime>::value_type D;
+ typedef indirect_cmp< FinishTime, std::less<D> > Compare;
+
+ Compare fl(finish_time);
+ std::priority_queue<Vertex, std::vector<Vertex>, Compare > Q(fl);
+
+ typename graph_traits<Graph>::vertex_iterator i, j, iend, jend;
+ tie(i, iend) = vertices(G_T);
+ tie(j, jend) = vertices(G);
+ for ( ; i != iend; ++i, ++j) {
+ put(finish_time, *i, get(finish_time, *j));
+ Q.push(*i);
+ }
+
+ while ( !Q.empty() ) {
+ Vertex u = Q.top();
+ Q.pop();
+ if (get(color, u) == Color::white()) {
+ depth_first_visit(G_T, u, vis, color);
+ ++c_count;
+ }
+ }
+ return c_count;
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_STRONG_COMPONENTS_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/subgraph.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/subgraph.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,872 @@
+//=======================================================================
+// Copyright 2001 University of Notre Dame.
+// Authors: Jeremy G. Siek and Lie-Quan Lee
+//
+// 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)
+//=======================================================================
+
+#ifndef BOOST_SUBGRAPH_HPP
+#define BOOST_SUBGRAPH_HPP
+
+// UNDER CONSTRUCTION
+
+#include <boost/config.hpp>
+#include <list>
+#include <vector>
+#include <map>
+#include <cassert>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/iterator/indirect_iterator.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost {
+
+ struct subgraph_tag { };
+
+ // Invariants of an induced subgraph:
+ // - If vertex u is in subgraph g, then u must be in g.parent().
+ // - If edge e is in subgraph g, then e must be in g.parent().
+ // - If edge e=(u,v) is in the root graph, then edge e
+ // is also in any subgraph that contains both vertex u and v.
+
+ // The Graph template parameter must have a vertex_index
+ // and edge_index internal property. It is assumed that
+ // the vertex indices are assigned automatically by the
+ // graph during a call to add_vertex(). It is not
+ // assumed that the edge vertices are assigned automatically,
+ // they are explicitly assigned here.
+
+ template <typename Graph>
+ class subgraph {
+ typedef graph_traits<Graph> Traits;
+ typedef std::list<subgraph<Graph>*> ChildrenList;
+ public:
+ // Graph requirements
+ typedef typename Traits::vertex_descriptor vertex_descriptor;
+ typedef typename Traits::edge_descriptor edge_descriptor;
+ typedef typename Traits::directed_category directed_category;
+ typedef typename Traits::edge_parallel_category edge_parallel_category;
+ typedef typename Traits::traversal_category traversal_category;
+
+ static vertex_descriptor null_vertex()
+ {
+ return Traits::null_vertex();
+ }
+
+
+ // IncidenceGraph requirements
+ typedef typename Traits::out_edge_iterator out_edge_iterator;
+ typedef typename Traits::degree_size_type degree_size_type;
+
+ // AdjacencyGraph requirements
+ typedef typename Traits::adjacency_iterator adjacency_iterator;
+
+ // VertexListGraph requirements
+ typedef typename Traits::vertex_iterator vertex_iterator;
+ typedef typename Traits::vertices_size_type vertices_size_type;
+
+ // EdgeListGraph requirements
+ typedef typename Traits::edge_iterator edge_iterator;
+ typedef typename Traits::edges_size_type edges_size_type;
+
+ typedef typename Traits::in_edge_iterator in_edge_iterator;
+
+ typedef typename Graph::edge_property_type edge_property_type;
+ typedef typename Graph::vertex_property_type vertex_property_type;
+ typedef subgraph_tag graph_tag;
+ typedef Graph graph_type;
+ typedef typename Graph::graph_property_type graph_property_type;
+
+ // Constructors
+
+ // Create the main graph, the root of the subgraph tree
+ subgraph()
+ : m_parent(0), m_edge_counter(0)
+ { }
+ subgraph(const graph_property_type& p)
+ : m_graph(p), m_parent(0), m_edge_counter(0)
+ { }
+ subgraph(vertices_size_type n,
+ const graph_property_type& p = graph_property_type())
+ : m_graph(n, p), m_parent(0), m_edge_counter(0), m_global_vertex(n)
+ {
+ typename Graph::vertex_iterator v, v_end;
+ vertices_size_type i = 0;
+ for (tie(v, v_end) = vertices(m_graph); v != v_end; ++v)
+ m_global_vertex[i++] = *v;
+ }
+
+ // copy constructor
+ subgraph(const subgraph& x)
+ : m_graph(x.m_graph), m_parent(x.m_parent),
+ m_edge_counter(x.m_edge_counter),
+ m_global_vertex(x.m_global_vertex),
+ m_global_edge(x.m_global_edge)
+ {
+ // Do a deep copy
+ for (typename ChildrenList::const_iterator i = x.m_children.begin();
+ i != x.m_children.end(); ++i)
+ m_children.push_back(new subgraph<Graph>( **i ));
+ }
+
+
+ ~subgraph() {
+ for (typename ChildrenList::iterator i = m_children.begin();
+ i != m_children.end(); ++i)
+ delete *i;
+ }
+
+
+ // Create a subgraph
+ subgraph<Graph>& create_subgraph() {
+ m_children.push_back(new subgraph<Graph>());
+ m_children.back()->m_parent = this;
+ return *m_children.back();
+ }
+
+ // Create a subgraph with the specified vertex set.
+ template <typename VertexIterator>
+ subgraph<Graph>& create_subgraph(VertexIterator first,
+ VertexIterator last)
+ {
+ m_children.push_back(new subgraph<Graph>());
+ m_children.back()->m_parent = this;
+ for (; first != last; ++first)
+ add_vertex(*first, *m_children.back());
+ return *m_children.back();
+ }
+
+ // local <-> global descriptor conversion functions
+ vertex_descriptor local_to_global(vertex_descriptor u_local) const
+ {
+ return m_global_vertex[u_local];
+ }
+ vertex_descriptor global_to_local(vertex_descriptor u_global) const
+ {
+ vertex_descriptor u_local; bool in_subgraph;
+ tie(u_local, in_subgraph) = this->find_vertex(u_global);
+ assert(in_subgraph == true);
+ return u_local;
+ }
+ edge_descriptor local_to_global(edge_descriptor e_local) const
+ {
+ return m_global_edge[get(get(edge_index, m_graph), e_local)];
+ }
+ edge_descriptor global_to_local(edge_descriptor e_global) const
+ {
+ return
+ (*m_local_edge.find(get(get(edge_index, root().m_graph), e_global))).second;
+ }
+
+ // Is vertex u (of the root graph) contained in this subgraph?
+ // If so, return the matching local vertex.
+ std::pair<vertex_descriptor, bool>
+ find_vertex(vertex_descriptor u_global) const
+ {
+ typename std::map<vertex_descriptor, vertex_descriptor>::const_iterator
+ i = m_local_vertex.find(u_global);
+ bool valid = i != m_local_vertex.end();
+ return std::make_pair((valid ? (*i).second : null_vertex()), valid);
+ }
+
+ // Return the parent graph.
+ subgraph& parent() { return *m_parent; }
+ const subgraph& parent() const { return *m_parent; }
+
+ bool is_root() const { return m_parent == 0; }
+
+ // Return the root graph of the subgraph tree.
+ subgraph& root() {
+ if (this->is_root())
+ return *this;
+ else
+ return m_parent->root();
+ }
+ const subgraph& root() const {
+ if (this->is_root())
+ return *this;
+ else
+ return m_parent->root();
+ }
+
+ // Return the children subgraphs of this graph/subgraph.
+ // Use a list of pointers because the VC++ std::list doesn't like
+ // storing incomplete type.
+ typedef indirect_iterator<
+ typename ChildrenList::const_iterator
+ , subgraph<Graph>
+ , std::bidirectional_iterator_tag
+ >
+ children_iterator;
+
+ typedef indirect_iterator<
+ typename ChildrenList::const_iterator
+ , subgraph<Graph> const
+ , std::bidirectional_iterator_tag
+ >
+ const_children_iterator;
+
+ std::pair<const_children_iterator, const_children_iterator>
+ children() const
+ {
+ return std::make_pair(const_children_iterator(m_children.begin()),
+ const_children_iterator(m_children.end()));
+ }
+
+ std::pair<children_iterator, children_iterator>
+ children()
+ {
+ return std::make_pair(children_iterator(m_children.begin()),
+ children_iterator(m_children.end()));
+ }
+
+ std::size_t num_children() const { return m_children.size(); }
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ // Bundled properties support
+ template<typename Descriptor>
+ typename graph::detail::bundled_result<Graph, Descriptor>::type&
+ operator[](Descriptor x)
+ {
+ if (m_parent == 0) return m_graph[x];
+ else return root().m_graph[local_to_global(x)];
+ }
+
+ template<typename Descriptor>
+ typename graph::detail::bundled_result<Graph, Descriptor>::type const&
+ operator[](Descriptor x) const
+ {
+ if (m_parent == 0) return m_graph[x];
+ else return root().m_graph[local_to_global(x)];
+ }
+#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+
+ // private:
+ typedef typename property_map<Graph, edge_index_t>::type EdgeIndexMap;
+ typedef typename property_traits<EdgeIndexMap>::value_type edge_index_type;
+ BOOST_STATIC_ASSERT((!is_same<edge_index_type,
+ boost::detail::error_property_not_found>::value));
+
+ Graph m_graph;
+ subgraph<Graph>* m_parent;
+ edge_index_type m_edge_counter; // for generating unique edge indices
+ ChildrenList m_children;
+ std::vector<vertex_descriptor> m_global_vertex; // local -> global
+ std::map<vertex_descriptor, vertex_descriptor> m_local_vertex; // global -> local
+ std::vector<edge_descriptor> m_global_edge; // local -> global
+ std::map<edge_index_type, edge_descriptor> m_local_edge; // global -> local
+
+ edge_descriptor
+ local_add_edge(vertex_descriptor u_local, vertex_descriptor v_local,
+ edge_descriptor e_global)
+ {
+ edge_descriptor e_local;
+ bool inserted;
+ tie(e_local, inserted) = add_edge(u_local, v_local, m_graph);
+ put(edge_index, m_graph, e_local, m_edge_counter++);
+ m_global_edge.push_back(e_global);
+ m_local_edge[get(get(edge_index, this->root()), e_global)] = e_local;
+ return e_local;
+ }
+
+ };
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+ template<typename Graph>
+ struct vertex_bundle_type<subgraph<Graph> > : vertex_bundle_type<Graph> { };
+
+ template<typename Graph>
+ struct edge_bundle_type<subgraph<Graph> > : edge_bundle_type<Graph> { };
+#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+
+ //===========================================================================
+ // Functions special to the Subgraph Class
+
+ template <typename G>
+ typename subgraph<G>::vertex_descriptor
+ add_vertex(typename subgraph<G>::vertex_descriptor u_global,
+ subgraph<G>& g)
+ {
+ assert(!g.is_root());
+ typename subgraph<G>::vertex_descriptor u_local, v_global, uu_global;
+ typename subgraph<G>::edge_descriptor e_global;
+
+ u_local = add_vertex(g.m_graph);
+ g.m_global_vertex.push_back(u_global);
+ g.m_local_vertex[u_global] = u_local;
+
+ subgraph<G>& r = g.root();
+
+ // remember edge global and local maps
+ {
+ typename subgraph<G>::out_edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = out_edges(u_global, r);
+ ei != ei_end; ++ei) {
+ e_global = *ei;
+ v_global = target(e_global, r);
+ if (g.find_vertex(v_global).second == true)
+ g.local_add_edge(u_local, g.global_to_local(v_global), e_global);
+ }
+ }
+ if (is_directed(g)) { // not necessary for undirected graph
+ typename subgraph<G>::vertex_iterator vi, vi_end;
+ typename subgraph<G>::out_edge_iterator ei, ei_end;
+ for (tie(vi, vi_end) = vertices(r); vi != vi_end; ++vi) {
+ v_global = *vi;
+ if (g.find_vertex(v_global).second)
+ for (tie(ei, ei_end) = out_edges(*vi, r); ei != ei_end; ++ei) {
+ e_global = *ei;
+ uu_global = target(e_global, r);
+ if (uu_global == u_global && g.find_vertex(v_global).second)
+ g.local_add_edge(g.global_to_local(v_global), u_local, e_global);
+ }
+ }
+ }
+
+ return u_local;
+ }
+
+ //===========================================================================
+ // Functions required by the IncidenceGraph concept
+
+ template <typename G>
+ std::pair<typename graph_traits<G>::out_edge_iterator,
+ typename graph_traits<G>::out_edge_iterator>
+ out_edges(typename graph_traits<G>::vertex_descriptor u_local,
+ const subgraph<G>& g)
+ { return out_edges(u_local, g.m_graph); }
+
+ template <typename G>
+ typename graph_traits<G>::degree_size_type
+ out_degree(typename graph_traits<G>::vertex_descriptor u_local,
+ const subgraph<G>& g)
+ { return out_degree(u_local, g.m_graph); }
+
+ template <typename G>
+ typename graph_traits<G>::vertex_descriptor
+ source(typename graph_traits<G>::edge_descriptor e_local,
+ const subgraph<G>& g)
+ { return source(e_local, g.m_graph); }
+
+ template <typename G>
+ typename graph_traits<G>::vertex_descriptor
+ target(typename graph_traits<G>::edge_descriptor e_local,
+ const subgraph<G>& g)
+ { return target(e_local, g.m_graph); }
+
+ //===========================================================================
+ // Functions required by the BidirectionalGraph concept
+
+ template <typename G>
+ std::pair<typename graph_traits<G>::in_edge_iterator,
+ typename graph_traits<G>::in_edge_iterator>
+ in_edges(typename graph_traits<G>::vertex_descriptor u_local,
+ const subgraph<G>& g)
+ { return in_edges(u_local, g.m_graph); }
+
+ template <typename G>
+ typename graph_traits<G>::degree_size_type
+ in_degree(typename graph_traits<G>::vertex_descriptor u_local,
+ const subgraph<G>& g)
+ { return in_degree(u_local, g.m_graph); }
+
+ template <typename G>
+ typename graph_traits<G>::degree_size_type
+ degree(typename graph_traits<G>::vertex_descriptor u_local,
+ const subgraph<G>& g)
+ { return degree(u_local, g.m_graph); }
+
+ //===========================================================================
+ // Functions required by the AdjacencyGraph concept
+
+ template <typename G>
+ std::pair<typename subgraph<G>::adjacency_iterator,
+ typename subgraph<G>::adjacency_iterator>
+ adjacent_vertices(typename subgraph<G>::vertex_descriptor u_local,
+ const subgraph<G>& g)
+ { return adjacent_vertices(u_local, g.m_graph); }
+
+ //===========================================================================
+ // Functions required by the VertexListGraph concept
+
+ template <typename G>
+ std::pair<typename subgraph<G>::vertex_iterator,
+ typename subgraph<G>::vertex_iterator>
+ vertices(const subgraph<G>& g)
+ { return vertices(g.m_graph); }
+
+ template <typename G>
+ typename subgraph<G>::vertices_size_type
+ num_vertices(const subgraph<G>& g)
+ { return num_vertices(g.m_graph); }
+
+ //===========================================================================
+ // Functions required by the EdgeListGraph concept
+
+ template <typename G>
+ std::pair<typename subgraph<G>::edge_iterator,
+ typename subgraph<G>::edge_iterator>
+ edges(const subgraph<G>& g)
+ { return edges(g.m_graph); }
+
+ template <typename G>
+ typename subgraph<G>::edges_size_type
+ num_edges(const subgraph<G>& g)
+ { return num_edges(g.m_graph); }
+
+ //===========================================================================
+ // Functions required by the AdjacencyMatrix concept
+
+ template <typename G>
+ std::pair<typename subgraph<G>::edge_descriptor, bool>
+ edge(typename subgraph<G>::vertex_descriptor u_local,
+ typename subgraph<G>::vertex_descriptor v_local,
+ const subgraph<G>& g)
+ {
+ return edge(u_local, v_local, g.m_graph);
+ }
+
+ //===========================================================================
+ // Functions required by the MutableGraph concept
+
+ namespace detail {
+
+ template <typename Vertex, typename Edge, typename Graph>
+ void add_edge_recur_down
+ (Vertex u_global, Vertex v_global, Edge e_global, subgraph<Graph>& g);
+
+ template <typename Vertex, typename Edge, typename Children, typename G>
+ void children_add_edge(Vertex u_global, Vertex v_global, Edge e_global,
+ Children& c, subgraph<G>* orig)
+ {
+ for (typename Children::iterator i = c.begin(); i != c.end(); ++i)
+ if ((*i)->find_vertex(u_global).second
+ && (*i)->find_vertex(v_global).second)
+ add_edge_recur_down(u_global, v_global, e_global, **i, orig);
+ }
+
+ template <typename Vertex, typename Edge, typename Graph>
+ void add_edge_recur_down
+ (Vertex u_global, Vertex v_global, Edge e_global, subgraph<Graph>& g,
+ subgraph<Graph>* orig)
+ {
+ if (&g != orig ) {
+ // add local edge only if u_global and v_global are in subgraph g
+ Vertex u_local, v_local;
+ bool u_in_subgraph, v_in_subgraph;
+ tie(u_local, u_in_subgraph) = g.find_vertex(u_global);
+ tie(v_local, v_in_subgraph) = g.find_vertex(v_global);
+ if (u_in_subgraph && v_in_subgraph)
+ g.local_add_edge(u_local, v_local, e_global);
+ }
+ children_add_edge(u_global, v_global, e_global, g.m_children, orig);
+ }
+
+ template <typename Vertex, typename Graph>
+ std::pair<typename subgraph<Graph>::edge_descriptor, bool>
+ add_edge_recur_up(Vertex u_global, Vertex v_global,
+ const typename Graph::edge_property_type& ep,
+ subgraph<Graph>& g, subgraph<Graph>* orig)
+ {
+ if (g.is_root()) {
+ typename subgraph<Graph>::edge_descriptor e_global;
+ bool inserted;
+ tie(e_global, inserted) = add_edge(u_global, v_global, ep, g.m_graph);
+ put(edge_index, g.m_graph, e_global, g.m_edge_counter++);
+ g.m_global_edge.push_back(e_global);
+ children_add_edge(u_global, v_global, e_global, g.m_children, orig);
+ return std::make_pair(e_global, inserted);
+ } else
+ return add_edge_recur_up(u_global, v_global, ep, *g.m_parent, orig);
+ }
+
+ } // namespace detail
+
+ // Add an edge to the subgraph g, specified by the local vertex
+ // descriptors u and v. In addition, the edge will be added to any
+ // other subgraphs which contain vertex descriptors u and v.
+
+ template <typename G>
+ std::pair<typename subgraph<G>::edge_descriptor, bool>
+ add_edge(typename subgraph<G>::vertex_descriptor u_local,
+ typename subgraph<G>::vertex_descriptor v_local,
+ const typename G::edge_property_type& ep,
+ subgraph<G>& g)
+ {
+ if (g.is_root()) // u_local and v_local are really global
+ return detail::add_edge_recur_up(u_local, v_local, ep, g, &g);
+ else {
+ typename subgraph<G>::edge_descriptor e_local, e_global;
+ bool inserted;
+ tie(e_global, inserted) = detail::add_edge_recur_up
+ (g.local_to_global(u_local), g.local_to_global(v_local), ep, g, &g);
+ e_local = g.local_add_edge(u_local, v_local, e_global);
+ return std::make_pair(e_local, inserted);
+ }
+ }
+
+ template <typename G>
+ std::pair<typename subgraph<G>::edge_descriptor, bool>
+ add_edge(typename subgraph<G>::vertex_descriptor u,
+ typename subgraph<G>::vertex_descriptor v,
+ subgraph<G>& g)
+ {
+ typename G::edge_property_type ep;
+ return add_edge(u, v, ep, g);
+ }
+
+ namespace detail {
+
+ //-------------------------------------------------------------------------
+ // implementation of remove_edge(u,v,g)
+
+ template <typename Vertex, typename Graph>
+ void remove_edge_recur_down(Vertex u_global, Vertex v_global,
+ subgraph<Graph>& g);
+
+ template <typename Vertex, typename Children>
+ void children_remove_edge(Vertex u_global, Vertex v_global,
+ Children& c)
+ {
+ for (typename Children::iterator i = c.begin(); i != c.end(); ++i)
+ if ((*i)->find_vertex(u_global).second
+ && (*i)->find_vertex(v_global).second)
+ remove_edge_recur_down(u_global, v_global, **i);
+ }
+
+ template <typename Vertex, typename Graph>
+ void remove_edge_recur_down(Vertex u_global, Vertex v_global,
+ subgraph<Graph>& g)
+ {
+ Vertex u_local, v_local;
+ u_local = g.m_local_vertex[u_global];
+ v_local = g.m_local_vertex[v_global];
+ remove_edge(u_local, v_local, g.m_graph);
+ children_remove_edge(u_global, v_global, g.m_children);
+ }
+
+ template <typename Vertex, typename Graph>
+ void remove_edge_recur_up(Vertex u_global, Vertex v_global,
+ subgraph<Graph>& g)
+ {
+ if (g.is_root()) {
+ remove_edge(u_global, v_global, g.m_graph);
+ children_remove_edge(u_global, v_global, g.m_children);
+ } else
+ remove_edge_recur_up(u_global, v_global, *g.m_parent);
+ }
+
+ //-------------------------------------------------------------------------
+ // implementation of remove_edge(e,g)
+
+ template <typename Edge, typename Graph>
+ void remove_edge_recur_down(Edge e_global, subgraph<Graph>& g);
+
+ template <typename Edge, typename Children>
+ void children_remove_edge(Edge e_global, Children& c)
+ {
+ for (typename Children::iterator i = c.begin(); i != c.end(); ++i)
+ if ((*i)->find_vertex(source(e_global, **i)).second
+ && (*i)->find_vertex(target(e_global, **i)).second)
+ remove_edge_recur_down(source(e_global, **i),
+ target(e_global, **i), **i);
+ }
+
+ template <typename Edge, typename Graph>
+ void remove_edge_recur_down(Edge e_global, subgraph<Graph>& g)
+ {
+ remove_edge(g.global_to_local(e_global), g.m_graph);
+ children_remove_edge(e_global, g.m_children);
+ }
+
+ template <typename Edge, typename Graph>
+ void remove_edge_recur_up(Edge e_global, subgraph<Graph>& g)
+ {
+ if (g.is_root()) {
+ remove_edge(e_global, g.m_graph);
+ children_remove_edge(e_global, g.m_children);
+ } else
+ remove_edge_recur_up(e_global, *g.m_parent);
+ }
+
+ } // namespace detail
+
+ template <typename G>
+ void
+ remove_edge(typename subgraph<G>::vertex_descriptor u_local,
+ typename subgraph<G>::vertex_descriptor v_local,
+ subgraph<G>& g)
+ {
+ if (g.is_root())
+ detail::remove_edge_recur_up(u_local, v_local, g);
+ else
+ detail::remove_edge_recur_up(g.local_to_global(u_local),
+ g.local_to_global(v_local), g);
+ }
+
+ template <typename G>
+ void
+ remove_edge(typename subgraph<G>::edge_descriptor e_local,
+ subgraph<G>& g)
+ {
+ if (g.is_root())
+ detail::remove_edge_recur_up(e_local, g);
+ else
+ detail::remove_edge_recur_up(g.local_to_global(e_local), g);
+ }
+
+ template <typename Predicate, typename G>
+ void
+ remove_edge_if(Predicate p, subgraph<G>& g)
+ {
+ // This is wrong...
+ remove_edge_if(p, g.m_graph);
+ }
+
+ template <typename G>
+ void
+ clear_vertex(typename subgraph<G>::vertex_descriptor v_local,
+ subgraph<G>& g)
+ {
+ // this is wrong...
+ clear_vertex(v_local, g.m_graph);
+ }
+
+ namespace detail {
+
+ template <typename G>
+ typename subgraph<G>::vertex_descriptor
+ add_vertex_recur_up(subgraph<G>& g)
+ {
+ typename subgraph<G>::vertex_descriptor u_local, u_global;
+ if (g.is_root()) {
+ u_global = add_vertex(g.m_graph);
+ g.m_global_vertex.push_back(u_global);
+ } else {
+ u_global = add_vertex_recur_up(*g.m_parent);
+ u_local = add_vertex(g.m_graph);
+ g.m_global_vertex.push_back(u_global);
+ g.m_local_vertex[u_global] = u_local;
+ }
+ return u_global;
+ }
+
+ } // namespace detail
+
+ template <typename G>
+ typename subgraph<G>::vertex_descriptor
+ add_vertex(subgraph<G>& g)
+ {
+ typename subgraph<G>::vertex_descriptor u_local, u_global;
+ if (g.is_root()) {
+ u_global = add_vertex(g.m_graph);
+ g.m_global_vertex.push_back(u_global);
+ u_local = u_global;
+ } else {
+ u_global = detail::add_vertex_recur_up(g.parent());
+ u_local = add_vertex(g.m_graph);
+ g.m_global_vertex.push_back(u_global);
+ g.m_local_vertex[u_global] = u_local;
+ }
+ return u_local;
+ }
+
+ template <typename G>
+ void remove_vertex(typename subgraph<G>::vertex_descriptor u,
+ subgraph<G>& g)
+ {
+ // UNDER CONSTRUCTION
+ assert(false);
+ }
+
+
+ //===========================================================================
+ // Functions required by the PropertyGraph concept
+
+ template <typename GraphPtr, typename PropertyMap, typename Tag>
+ class subgraph_global_property_map
+ : public put_get_helper<
+ typename property_traits<PropertyMap>::reference,
+ subgraph_global_property_map<GraphPtr, PropertyMap, Tag> >
+ {
+ typedef property_traits<PropertyMap> Traits;
+ public:
+ typedef typename Traits::category category;
+ typedef typename Traits::value_type value_type;
+ typedef typename Traits::key_type key_type;
+ typedef typename Traits::reference reference;
+
+ subgraph_global_property_map() { }
+
+ subgraph_global_property_map(GraphPtr g)
+ : m_g(g) { }
+
+ inline reference operator[](key_type e_local) const {
+ PropertyMap pmap = get(Tag(), m_g->root().m_graph);
+ if (m_g->m_parent == 0)
+ return pmap[e_local];
+ else
+ return pmap[m_g->local_to_global(e_local)];
+ }
+ GraphPtr m_g;
+ };
+
+ template <typename GraphPtr, typename PropertyMap, typename Tag>
+ class subgraph_local_property_map
+ : public put_get_helper<
+ typename property_traits<PropertyMap>::reference,
+ subgraph_local_property_map<GraphPtr, PropertyMap, Tag> >
+ {
+ typedef property_traits<PropertyMap> Traits;
+ public:
+ typedef typename Traits::category category;
+ typedef typename Traits::value_type value_type;
+ typedef typename Traits::key_type key_type;
+ typedef typename Traits::reference reference;
+
+ subgraph_local_property_map() { }
+
+ subgraph_local_property_map(GraphPtr g)
+ : m_g(g) { }
+
+ inline reference operator[](key_type e_local) const {
+ PropertyMap pmap = get(Tag(), *m_g);
+ return pmap[e_local];
+ }
+ GraphPtr m_g;
+ };
+
+ namespace detail {
+
+ struct subgraph_any_pmap {
+ template <class Tag, class SubGraph, class Property>
+ class bind_ {
+ typedef typename SubGraph::graph_type Graph;
+ typedef SubGraph* SubGraphPtr;
+ typedef const SubGraph* const_SubGraphPtr;
+ typedef typename property_map<Graph, Tag>::type PMap;
+ typedef typename property_map<Graph, Tag>::const_type const_PMap;
+ public:
+ typedef subgraph_global_property_map<SubGraphPtr, PMap, Tag> type;
+ typedef subgraph_global_property_map<const_SubGraphPtr, const_PMap, Tag>
+ const_type;
+ };
+ };
+ struct subgraph_id_pmap {
+ template <class Tag, class SubGraph, class Property>
+ struct bind_ {
+ typedef typename SubGraph::graph_type Graph;
+ typedef SubGraph* SubGraphPtr;
+ typedef const SubGraph* const_SubGraphPtr;
+ typedef typename property_map<Graph, Tag>::type PMap;
+ typedef typename property_map<Graph, Tag>::const_type const_PMap;
+ public:
+ typedef subgraph_local_property_map<SubGraphPtr, PMap, Tag> type;
+ typedef subgraph_local_property_map<const_SubGraphPtr, const_PMap, Tag>
+ const_type;
+ };
+ };
+ template <class Tag>
+ struct subgraph_choose_pmap_helper {
+ typedef subgraph_any_pmap type;
+ };
+ template <>
+ struct subgraph_choose_pmap_helper<vertex_index_t> {
+ typedef subgraph_id_pmap type;
+ };
+ template <class Tag, class Graph, class Property>
+ struct subgraph_choose_pmap {
+ typedef typename subgraph_choose_pmap_helper<Tag>::type Helper;
+ typedef typename Helper::template bind_<Tag, Graph, Property> Bind;
+ typedef typename Bind::type type;
+ typedef typename Bind::const_type const_type;
+ };
+ struct subgraph_property_generator {
+ template <class SubGraph, class Property, class Tag>
+ struct bind_ {
+ typedef subgraph_choose_pmap<Tag, SubGraph, Property> Choice;
+ typedef typename Choice::type type;
+ typedef typename Choice::const_type const_type;
+ };
+ };
+
+ } // namespace detail
+
+ template <>
+ struct vertex_property_selector<subgraph_tag> {
+ typedef detail::subgraph_property_generator type;
+ };
+
+ template <>
+ struct edge_property_selector<subgraph_tag> {
+ typedef detail::subgraph_property_generator type;
+ };
+
+ template <typename G, typename Property>
+ typename property_map< subgraph<G>, Property>::type
+ get(Property, subgraph<G>& g)
+ {
+ typedef typename property_map< subgraph<G>, Property>::type PMap;
+ return PMap(&g);
+ }
+
+ template <typename G, typename Property>
+ typename property_map< subgraph<G>, Property>::const_type
+ get(Property, const subgraph<G>& g)
+ {
+ typedef typename property_map< subgraph<G>, Property>::const_type PMap;
+ return PMap(&g);
+ }
+
+ template <typename G, typename Property, typename Key>
+ typename property_traits<
+ typename property_map< subgraph<G>, Property>::const_type
+ >::value_type
+ get(Property, const subgraph<G>& g, const Key& k)
+ {
+ typedef typename property_map< subgraph<G>, Property>::const_type PMap;
+ PMap pmap(&g);
+ return pmap[k];
+ }
+
+ template <typename G, typename Property, typename Key, typename Value>
+ void
+ put(Property, subgraph<G>& g, const Key& k, const Value& val)
+ {
+ typedef typename property_map< subgraph<G>, Property>::type PMap;
+ PMap pmap(&g);
+ pmap[k] = val;
+ }
+
+ template <typename G, typename Tag>
+ inline
+ typename graph_property<G, Tag>::type&
+ get_property(subgraph<G>& g, Tag tag) {
+ return get_property(g.m_graph, tag);
+ }
+
+ template <typename G, typename Tag>
+ inline
+ const typename graph_property<G, Tag>::type&
+ get_property(const subgraph<G>& g, Tag tag) {
+ return get_property(g.m_graph, tag);
+ }
+
+ //===========================================================================
+ // Miscellaneous Functions
+
+ template <typename G>
+ typename subgraph<G>::vertex_descriptor
+ vertex(typename subgraph<G>::vertices_size_type n, const subgraph<G>& g)
+ {
+ return vertex(n, g.m_graph);
+ }
+
+} // namespace boost
+
+#endif // BOOST_SUBGRAPH_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/topological_sort.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/topological_sort.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,76 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_TOPOLOGICAL_SORT_HPP
+#define BOOST_GRAPH_TOPOLOGICAL_SORT_HPP
+
+#include <boost/config.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/exception.hpp>
+
+namespace boost {
+
+
+ // Topological sort visitor
+ //
+ // This visitor merely writes the linear ordering into an
+ // OutputIterator. The OutputIterator could be something like an
+ // ostream_iterator, or it could be a back/front_insert_iterator.
+ // Note that if it is a back_insert_iterator, the recorded order is
+ // the reverse topological order. On the other hand, if it is a
+ // front_insert_iterator, the recorded order is the topological
+ // order.
+ //
+ template <typename OutputIterator>
+ struct topo_sort_visitor : public dfs_visitor<>
+ {
+ topo_sort_visitor(OutputIterator _iter)
+ : m_iter(_iter) { }
+
+ template <typename Edge, typename Graph>
+ void back_edge(const Edge& u, Graph&) { throw not_a_dag(); }
+
+ template <typename Vertex, typename Graph>
+ void finish_vertex(const Vertex& u, Graph&) { *m_iter++ = u; }
+
+ OutputIterator m_iter;
+ };
+
+
+ // Topological Sort
+ //
+ // The topological sort algorithm creates a linear ordering
+ // of the vertices such that if edge (u,v) appears in the graph,
+ // then u comes before v in the ordering. The graph must
+ // be a directed acyclic graph (DAG). The implementation
+ // consists mainly of a call to depth-first search.
+ //
+
+ template <typename VertexListGraph, typename OutputIterator,
+ typename P, typename T, typename R>
+ void topological_sort(VertexListGraph& g, OutputIterator result,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef topo_sort_visitor<OutputIterator> TopoVisitor;
+ depth_first_search(g, params.visitor(TopoVisitor(result)));
+ }
+
+ template <typename VertexListGraph, typename OutputIterator>
+ void topological_sort(VertexListGraph& g, OutputIterator result)
+ {
+ topological_sort(g, result,
+ bgl_named_params<int, buffer_param_t>(0)); // bogus
+ }
+
+} // namespace boost
+
+#endif /*BOOST_GRAPH_TOPOLOGICAL_SORT_H*/
Added: branches/CMake/release/libs/graph/include/boost/graph/transitive_closure.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/transitive_closure.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,370 @@
+// Copyright (C) 2001 Vladimir Prus <ghost_at_[hidden]>
+// Copyright (C) 2001 Jeremy Siek <jsiek_at_[hidden]>
+// 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)
+
+// NOTE: this final is generated by libs/graph/doc/transitive_closure.w
+
+#ifndef BOOST_GRAPH_TRANSITIVE_CLOSURE_HPP
+#define BOOST_GRAPH_TRANSITIVE_CLOSURE_HPP
+
+#include <vector>
+#include <algorithm> // for std::min and std::max
+#include <functional>
+#include <boost/config.hpp>
+#include <boost/bind.hpp>
+#include <boost/graph/vector_as_graph.hpp>
+#include <boost/graph/strong_components.hpp>
+#include <boost/graph/topological_sort.hpp>
+#include <boost/graph/graph_concepts.hpp>
+#include <boost/graph/named_function_params.hpp>
+
+namespace boost
+{
+
+ namespace detail
+ {
+ inline void
+ union_successor_sets(const std::vector < std::size_t > &s1,
+ const std::vector < std::size_t > &s2,
+ std::vector < std::size_t > &s3)
+ {
+ BOOST_USING_STD_MIN();
+ for (std::size_t k = 0; k < s1.size(); ++k)
+ s3[k] = min BOOST_PREVENT_MACRO_SUBSTITUTION(s1[k], s2[k]);
+ }
+ } // namespace detail
+
+ namespace detail
+ {
+ template < typename Container, typename ST = std::size_t,
+ typename VT = typename Container::value_type >
+ struct subscript_t:public std::unary_function < ST, VT >
+ {
+ typedef VT& result_type;
+
+ subscript_t(Container & c):container(&c)
+ {
+ }
+ VT & operator() (const ST & i) const
+ {
+ return (*container)[i];
+ }
+ protected:
+ Container * container;
+ };
+ template < typename Container >
+ subscript_t < Container > subscript(Container & c) {
+ return subscript_t < Container > (c);
+ }
+ } // namespace detail
+
+ template < typename Graph, typename GraphTC,
+ typename G_to_TC_VertexMap,
+ typename VertexIndexMap >
+ void transitive_closure(const Graph & g, GraphTC & tc,
+ G_to_TC_VertexMap g_to_tc_map,
+ VertexIndexMap index_map)
+ {
+ if (num_vertices(g) == 0)
+ return;
+ typedef typename graph_traits < Graph >::vertex_descriptor vertex;
+ typedef typename graph_traits < Graph >::edge_descriptor edge;
+ typedef typename graph_traits < Graph >::vertex_iterator vertex_iterator;
+ typedef typename property_traits < VertexIndexMap >::value_type size_type;
+ typedef typename graph_traits <
+ Graph >::adjacency_iterator adjacency_iterator;
+
+ function_requires < VertexListGraphConcept < Graph > >();
+ function_requires < AdjacencyGraphConcept < Graph > >();
+ function_requires < VertexMutableGraphConcept < GraphTC > >();
+ function_requires < EdgeMutableGraphConcept < GraphTC > >();
+ function_requires < ReadablePropertyMapConcept < VertexIndexMap,
+ vertex > >();
+
+ typedef size_type cg_vertex;
+ std::vector < cg_vertex > component_number_vec(num_vertices(g));
+ iterator_property_map < cg_vertex *, VertexIndexMap, cg_vertex, cg_vertex& >
+ component_number(&component_number_vec[0], index_map);
+
+ int num_scc = strong_components(g, component_number,
+ vertex_index_map(index_map));
+
+ std::vector < std::vector < vertex > >components;
+ build_component_lists(g, num_scc, component_number, components);
+
+ typedef std::vector<std::vector<cg_vertex> > CG_t;
+ CG_t CG(num_scc);
+ for (cg_vertex s = 0; s < components.size(); ++s) {
+ std::vector < cg_vertex > adj;
+ for (size_type i = 0; i < components[s].size(); ++i) {
+ vertex u = components[s][i];
+ adjacency_iterator v, v_end;
+ for (tie(v, v_end) = adjacent_vertices(u, g); v != v_end; ++v) {
+ cg_vertex t = component_number[*v];
+ if (s != t) // Avoid loops in the condensation graph
+ adj.push_back(t);
+ }
+ }
+ std::sort(adj.begin(), adj.end());
+ typename std::vector<cg_vertex>::iterator di =
+ std::unique(adj.begin(), adj.end());
+ if (di != adj.end())
+ adj.erase(di, adj.end());
+ CG[s] = adj;
+ }
+
+ std::vector<cg_vertex> topo_order;
+ std::vector<cg_vertex> topo_number(num_vertices(CG));
+ topological_sort(CG, std::back_inserter(topo_order),
+ vertex_index_map(identity_property_map()));
+ std::reverse(topo_order.begin(), topo_order.end());
+ size_type n = 0;
+ for (typename std::vector<cg_vertex>::iterator iter = topo_order.begin();
+ iter != topo_order.end(); ++iter)
+ topo_number[*iter] = n++;
+
+ for (size_type i = 0; i < num_vertices(CG); ++i)
+ std::sort(CG[i].begin(), CG[i].end(),
+ boost::bind(std::less<cg_vertex>(),
+ boost::bind(detail::subscript(topo_number), _1),
+ boost::bind(detail::subscript(topo_number), _2)));
+
+ std::vector<std::vector<cg_vertex> > chains;
+ {
+ std::vector<cg_vertex> in_a_chain(num_vertices(CG));
+ for (typename std::vector<cg_vertex>::iterator i = topo_order.begin();
+ i != topo_order.end(); ++i) {
+ cg_vertex v = *i;
+ if (!in_a_chain[v]) {
+ chains.resize(chains.size() + 1);
+ std::vector<cg_vertex>& chain = chains.back();
+ for (;;) {
+ chain.push_back(v);
+ in_a_chain[v] = true;
+ typename graph_traits<CG_t>::adjacency_iterator adj_first, adj_last;
+ tie(adj_first, adj_last) = adjacent_vertices(v, CG);
+ typename graph_traits<CG_t>::adjacency_iterator next
+ = std::find_if(adj_first, adj_last,
+ std::not1(detail::subscript(in_a_chain)));
+ if (next != adj_last)
+ v = *next;
+ else
+ break; // end of chain, dead-end
+
+ }
+ }
+ }
+ }
+ std::vector<size_type> chain_number(num_vertices(CG));
+ std::vector<size_type> pos_in_chain(num_vertices(CG));
+ for (size_type i = 0; i < chains.size(); ++i)
+ for (size_type j = 0; j < chains[i].size(); ++j) {
+ cg_vertex v = chains[i][j];
+ chain_number[v] = i;
+ pos_in_chain[v] = j;
+ }
+
+ cg_vertex inf = (std::numeric_limits< cg_vertex >::max)();
+ std::vector<std::vector<cg_vertex> > successors(num_vertices(CG),
+ std::vector<cg_vertex>
+ (chains.size(), inf));
+ for (typename std::vector<cg_vertex>::reverse_iterator
+ i = topo_order.rbegin(); i != topo_order.rend(); ++i) {
+ cg_vertex u = *i;
+ typename graph_traits<CG_t>::adjacency_iterator adj, adj_last;
+ for (tie(adj, adj_last) = adjacent_vertices(u, CG);
+ adj != adj_last; ++adj) {
+ cg_vertex v = *adj;
+ if (topo_number[v] < successors[u][chain_number[v]]) {
+ // Succ(u) = Succ(u) U Succ(v)
+ detail::union_successor_sets(successors[u], successors[v],
+ successors[u]);
+ // Succ(u) = Succ(u) U {v}
+ successors[u][chain_number[v]] = topo_number[v];
+ }
+ }
+ }
+
+ for (size_type i = 0; i < CG.size(); ++i)
+ CG[i].clear();
+ for (size_type i = 0; i < CG.size(); ++i)
+ for (size_type j = 0; j < chains.size(); ++j) {
+ size_type topo_num = successors[i][j];
+ if (topo_num < inf) {
+ cg_vertex v = topo_order[topo_num];
+ for (size_type k = pos_in_chain[v]; k < chains[j].size(); ++k)
+ CG[i].push_back(chains[j][k]);
+ }
+ }
+
+
+ // Add vertices to the transitive closure graph
+ typedef typename graph_traits < GraphTC >::vertex_descriptor tc_vertex;
+ {
+ vertex_iterator i, i_end;
+ for (tie(i, i_end) = vertices(g); i != i_end; ++i)
+ g_to_tc_map[*i] = add_vertex(tc);
+ }
+ // Add edges between all the vertices in two adjacent SCCs
+ typename graph_traits<CG_t>::vertex_iterator si, si_end;
+ for (tie(si, si_end) = vertices(CG); si != si_end; ++si) {
+ cg_vertex s = *si;
+ typename graph_traits<CG_t>::adjacency_iterator i, i_end;
+ for (tie(i, i_end) = adjacent_vertices(s, CG); i != i_end; ++i) {
+ cg_vertex t = *i;
+ for (size_type k = 0; k < components[s].size(); ++k)
+ for (size_type l = 0; l < components[t].size(); ++l)
+ add_edge(g_to_tc_map[components[s][k]],
+ g_to_tc_map[components[t][l]], tc);
+ }
+ }
+ // Add edges connecting all vertices in a SCC
+ for (size_type i = 0; i < components.size(); ++i)
+ if (components[i].size() > 1)
+ for (size_type k = 0; k < components[i].size(); ++k)
+ for (size_type l = 0; l < components[i].size(); ++l) {
+ vertex u = components[i][k], v = components[i][l];
+ add_edge(g_to_tc_map[u], g_to_tc_map[v], tc);
+ }
+
+ // Find loopbacks in the original graph.
+ // Need to add it to transitive closure.
+ {
+ vertex_iterator i, i_end;
+ for (tie(i, i_end) = vertices(g); i != i_end; ++i)
+ {
+ adjacency_iterator ab, ae;
+ for (boost::tie(ab, ae) = adjacent_vertices(*i, g); ab != ae; ++ab)
+ {
+ if (*ab == *i)
+ if (components[component_number[*i]].size() == 1)
+ add_edge(g_to_tc_map[*i], g_to_tc_map[*i], tc);
+ }
+ }
+ }
+ }
+
+ template <typename Graph, typename GraphTC>
+ void transitive_closure(const Graph & g, GraphTC & tc)
+ {
+ if (num_vertices(g) == 0)
+ return;
+ typedef typename property_map<Graph, vertex_index_t>::const_type
+ VertexIndexMap;
+ VertexIndexMap index_map = get(vertex_index, g);
+
+ typedef typename graph_traits<GraphTC>::vertex_descriptor tc_vertex;
+ std::vector<tc_vertex> to_tc_vec(num_vertices(g));
+ iterator_property_map < tc_vertex *, VertexIndexMap, tc_vertex, tc_vertex&>
+ g_to_tc_map(&to_tc_vec[0], index_map);
+
+ transitive_closure(g, tc, g_to_tc_map, index_map);
+ }
+
+ namespace detail
+ {
+ template < typename Graph, typename GraphTC, typename G_to_TC_VertexMap,
+ typename VertexIndexMap>
+ void transitive_closure_dispatch
+ (const Graph & g, GraphTC & tc,
+ G_to_TC_VertexMap g_to_tc_map, VertexIndexMap index_map)
+ {
+ typedef typename graph_traits < GraphTC >::vertex_descriptor tc_vertex;
+ typename std::vector < tc_vertex >::size_type
+ n = is_default_param(g_to_tc_map) ? num_vertices(g) : 1;
+ std::vector < tc_vertex > to_tc_vec(n);
+
+ transitive_closure
+ (g, tc,
+ choose_param(g_to_tc_map, make_iterator_property_map
+ (to_tc_vec.begin(), index_map, to_tc_vec[0])),
+ index_map);
+ }
+ } // namespace detail
+
+ template < typename Graph, typename GraphTC,
+ typename P, typename T, typename R >
+ void transitive_closure(const Graph & g, GraphTC & tc,
+ const bgl_named_params < P, T, R > ¶ms)
+ {
+ if (num_vertices(g) == 0)
+ return;
+ detail::transitive_closure_dispatch
+ (g, tc, get_param(params, orig_to_copy_t()),
+ choose_const_pmap(get_param(params, vertex_index), g, vertex_index) );
+ }
+
+
+ template < typename G > void warshall_transitive_closure(G & g)
+ {
+ typedef typename graph_traits < G >::vertex_descriptor vertex;
+ typedef typename graph_traits < G >::vertex_iterator vertex_iterator;
+
+ function_requires < AdjacencyMatrixConcept < G > >();
+ function_requires < EdgeMutableGraphConcept < G > >();
+
+ // Matrix form:
+ // for k
+ // for i
+ // if A[i,k]
+ // for j
+ // A[i,j] = A[i,j] | A[k,j]
+ vertex_iterator ki, ke, ii, ie, ji, je;
+ for (tie(ki, ke) = vertices(g); ki != ke; ++ki)
+ for (tie(ii, ie) = vertices(g); ii != ie; ++ii)
+ if (edge(*ii, *ki, g).second)
+ for (tie(ji, je) = vertices(g); ji != je; ++ji)
+ if (!edge(*ii, *ji, g).second && edge(*ki, *ji, g).second) {
+ add_edge(*ii, *ji, g);
+ }
+ }
+
+
+ template < typename G > void warren_transitive_closure(G & g)
+ {
+ using namespace boost;
+ typedef typename graph_traits < G >::vertex_descriptor vertex;
+ typedef typename graph_traits < G >::vertex_iterator vertex_iterator;
+
+ function_requires < AdjacencyMatrixConcept < G > >();
+ function_requires < EdgeMutableGraphConcept < G > >();
+
+ // Make sure second loop will work
+ if (num_vertices(g) == 0)
+ return;
+
+ // for i = 2 to n
+ // for k = 1 to i - 1
+ // if A[i,k]
+ // for j = 1 to n
+ // A[i,j] = A[i,j] | A[k,j]
+
+ vertex_iterator ic, ie, jc, je, kc, ke;
+ for (tie(ic, ie) = vertices(g), ++ic; ic != ie; ++ic)
+ for (tie(kc, ke) = vertices(g); *kc != *ic; ++kc)
+ if (edge(*ic, *kc, g).second)
+ for (tie(jc, je) = vertices(g); jc != je; ++jc)
+ if (!edge(*ic, *jc, g).second && edge(*kc, *jc, g).second) {
+ add_edge(*ic, *jc, g);
+ }
+ // for i = 1 to n - 1
+ // for k = i + 1 to n
+ // if A[i,k]
+ // for j = 1 to n
+ // A[i,j] = A[i,j] | A[k,j]
+
+ for (tie(ic, ie) = vertices(g), --ie; ic != ie; ++ic)
+ for (kc = ic, ke = ie, ++kc; kc != ke; ++kc)
+ if (edge(*ic, *kc, g).second)
+ for (tie(jc, je) = vertices(g); jc != je; ++jc)
+ if (!edge(*ic, *jc, g).second && edge(*kc, *jc, g).second) {
+ add_edge(*ic, *jc, g);
+ }
+ }
+
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_TRANSITIVE_CLOSURE_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/transpose_graph.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/transpose_graph.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,40 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_TRANSPOSE_HPP
+#define BOOST_GRAPH_TRANSPOSE_HPP
+
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/reverse_graph.hpp>
+#include <boost/graph/copy.hpp>
+
+
+namespace boost {
+
+ template <class VertexListGraph, class MutableGraph>
+ void transpose_graph(const VertexListGraph& G, MutableGraph& G_T)
+ {
+ reverse_graph<VertexListGraph> R(G);
+ copy_graph(R, G_T);
+ }
+
+ template <class VertexListGraph, class MutableGraph,
+ class P, class T, class R>
+ void transpose_graph(const VertexListGraph& G, MutableGraph& G_T,
+ const bgl_named_params<P, T, R>& params)
+ {
+ reverse_graph<VertexListGraph> Rev(G);
+ copy_graph(Rev, G_T, params);
+ }
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_TRANSPOSE_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/tree_traits.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/tree_traits.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,43 @@
+// (C) Copyright Jeremy Siek 1999.
+// 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)
+
+#ifndef BOOST_TREE_STRUCTURE_HPP
+#define BOOST_TREE_STRUCTURE_HPP
+
+namespace boost {
+
+ template <class T>
+ struct tree_traits {
+ typedef typename T::node_descriptor node_descriptor;
+ typedef typename T::children_iterator children_iterator;
+ };
+
+
+ template <class Tree, class TreeVisitor>
+ void traverse_tree(typename tree_traits<Tree>::node_descriptor v,
+ Tree& t, TreeVisitor visitor)
+ {
+ visitor.preorder(v, t);
+ typename tree_traits<Tree>::children_iterator i, end;
+ tie(i, end) = children(v, t);
+ if (i != end) {
+ traverse_tree(*i++, t, visitor);
+ visitor.inorder(v, t);
+ while (i != end)
+ traverse_tree(*i++, t, visitor);
+ } else
+ visitor.inorder(v, t);
+ visitor.postorder(v, t);
+ }
+
+ struct null_tree_visitor {
+ template <typename Node, typename Tree> void preorder(Node, Tree&) { }
+ template <typename Node, typename Tree> void inorder(Node, Tree&) { }
+ template <typename Node, typename Tree> void postorder(Node, Tree&) { }
+ };
+
+} /* namespace boost */
+
+#endif /* BOOST_TREE_STRUCTURE_HPP */
Added: branches/CMake/release/libs/graph/include/boost/graph/two_bit_color_map.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/two_bit_color_map.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,90 @@
+// Copyright (C) 2005-2006 The Trustees of Indiana University.
+
+// 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)
+
+// Authors: Jeremiah Willcock
+// Douglas Gregor
+// Andrew Lumsdaine
+
+// Two bit per color property map
+
+#ifndef BOOST_TWO_BIT_COLOR_MAP_HPP
+#define BOOST_TWO_BIT_COLOR_MAP_HPP
+
+#include <boost/property_map.hpp>
+#include <boost/shared_array.hpp>
+
+namespace boost {
+
+enum two_bit_color_type {
+ two_bit_white = 0,
+ two_bit_gray = 1,
+ two_bit_green = 2,
+ two_bit_black = 3
+};
+
+template <>
+struct color_traits<two_bit_color_type>
+{
+ static two_bit_color_type white() { return two_bit_white; }
+ static two_bit_color_type gray() { return two_bit_gray; }
+ static two_bit_color_type green() { return two_bit_green; }
+ static two_bit_color_type black() { return two_bit_black; }
+};
+
+
+template<typename IndexMap = identity_property_map>
+struct two_bit_color_map
+{
+ std::size_t n;
+ IndexMap index;
+ shared_array<unsigned char> data;
+
+ typedef typename property_traits<IndexMap>::key_type key_type;
+ typedef two_bit_color_type value_type;
+ typedef void reference;
+ typedef read_write_property_map_tag category;
+
+ explicit two_bit_color_map(std::size_t n, const IndexMap& index = IndexMap())
+ : n(n), index(index), data(new unsigned char[(n + 3) / 4])
+ {
+ }
+};
+
+template<typename IndexMap>
+inline two_bit_color_type
+get(const two_bit_color_map<IndexMap>& pm,
+ typename two_bit_color_map<IndexMap>::key_type key)
+{
+ typename property_traits<IndexMap>::value_type i = get(pm.index, key);
+ assert (i < pm.n);
+ return two_bit_color_type((pm.data.get()[i / 4] >> ((i % 4) * 2)) & 3);
+}
+
+template<typename IndexMap>
+inline void
+put(const two_bit_color_map<IndexMap>& pm,
+ typename two_bit_color_map<IndexMap>::key_type key,
+ two_bit_color_type value)
+{
+ typename property_traits<IndexMap>::value_type i = get(pm.index, key);
+ assert (i < pm.n);
+ assert (value >= 0 && value < 4);
+ std::size_t byte_num = i / 4;
+ std::size_t bit_position = ((i % 4) * 2);
+ pm.data.get()[byte_num] = (pm.data.get()[byte_num] & ~(3 << bit_position))
+ | (value << bit_position);
+}
+
+template<typename IndexMap>
+inline two_bit_color_map<IndexMap>
+make_two_bit_color_map(std::size_t n, const IndexMap& index_map)
+{
+ return two_bit_color_map<IndexMap>(n, index_map);
+}
+
+} // end namespace boost
+
+#endif // BOOST_TWO_BIT_COLOR_MAP_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/undirected_dfs.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/undirected_dfs.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,250 @@
+//
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+#ifndef BOOST_GRAPH_UNDIRECTED_DFS_HPP
+#define BOOST_GRAPH_UNDIRECTED_DFS_HPP
+
+#include <boost/graph/depth_first_search.hpp>
+#include <vector>
+
+namespace boost {
+
+ namespace detail {
+
+// Define BOOST_RECURSIVE_DFS to use older, recursive version.
+// It is retained for a while in order to perform performance
+// comparison.
+#ifndef BOOST_RECURSIVE_DFS
+
+ template <typename IncidenceGraph, typename DFSVisitor,
+ typename VertexColorMap, typename EdgeColorMap>
+ void undir_dfv_impl
+ (const IncidenceGraph& g,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor u,
+ DFSVisitor& vis,
+ VertexColorMap vertex_color,
+ EdgeColorMap edge_color)
+ {
+ function_requires<IncidenceGraphConcept<IncidenceGraph> >();
+ function_requires<DFSVisitorConcept<DFSVisitor, IncidenceGraph> >();
+ typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
+ typedef typename graph_traits<IncidenceGraph>::edge_descriptor Edge;
+ function_requires<ReadWritePropertyMapConcept<VertexColorMap,Vertex> >();
+ function_requires<ReadWritePropertyMapConcept<EdgeColorMap,Edge> >();
+ typedef typename property_traits<VertexColorMap>::value_type ColorValue;
+ typedef typename property_traits<EdgeColorMap>::value_type EColorValue;
+ function_requires< ColorValueConcept<ColorValue> >();
+ function_requires< ColorValueConcept<EColorValue> >();
+ typedef color_traits<ColorValue> Color;
+ typedef color_traits<EColorValue> EColor;
+ typedef typename graph_traits<IncidenceGraph>::out_edge_iterator Iter;
+ typedef std::pair<Vertex, std::pair<Iter, Iter> > VertexInfo;
+
+ std::vector<VertexInfo> stack;
+
+ put(vertex_color, u, Color::gray());
+ vis.discover_vertex(u, g);
+ stack.push_back(std::make_pair(u, out_edges(u, g)));
+ while (!stack.empty()) {
+ VertexInfo& back = stack.back();
+ u = back.first;
+ Iter ei, ei_end;
+ tie(ei, ei_end) = back.second;
+ stack.pop_back();
+ while (ei != ei_end) {
+ Vertex v = target(*ei, g);
+ vis.examine_edge(*ei, g);
+ ColorValue v_color = get(vertex_color, v);
+ EColorValue uv_color = get(edge_color, *ei);
+ put(edge_color, *ei, EColor::black());
+ if (v_color == Color::white()) {
+ vis.tree_edge(*ei, g);
+ stack.push_back(std::make_pair(u, std::make_pair(++ei, ei_end)));
+ u = v;
+ put(vertex_color, u, Color::gray());
+ vis.discover_vertex(u, g);
+ tie(ei, ei_end) = out_edges(u, g);
+ } else if (v_color == Color::gray()) {
+ if (uv_color == EColor::white()) vis.back_edge(*ei, g);
+ ++ei;
+ } else { // if (v_color == Color::black())
+ ++ei;
+ }
+ }
+ put(vertex_color, u, Color::black());
+ vis.finish_vertex(u, g);
+ }
+ }
+
+#else // BOOST_RECURSIVE_DFS
+
+ template <typename IncidenceGraph, typename DFSVisitor,
+ typename VertexColorMap, typename EdgeColorMap>
+ void undir_dfv_impl
+ (const IncidenceGraph& g,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor u,
+ DFSVisitor& vis, // pass-by-reference here, important!
+ VertexColorMap vertex_color,
+ EdgeColorMap edge_color)
+ {
+ function_requires<IncidenceGraphConcept<IncidenceGraph> >();
+ function_requires<DFSVisitorConcept<DFSVisitor, IncidenceGraph> >();
+ typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
+ typedef typename graph_traits<IncidenceGraph>::edge_descriptor Edge;
+ function_requires<ReadWritePropertyMapConcept<VertexColorMap,Vertex> >();
+ function_requires<ReadWritePropertyMapConcept<EdgeColorMap,Edge> >();
+ typedef typename property_traits<VertexColorMap>::value_type ColorValue;
+ typedef typename property_traits<EdgeColorMap>::value_type EColorValue;
+ function_requires< ColorValueConcept<ColorValue> >();
+ function_requires< ColorValueConcept<EColorValue> >();
+ typedef color_traits<ColorValue> Color;
+ typedef color_traits<EColorValue> EColor;
+ typename graph_traits<IncidenceGraph>::out_edge_iterator ei, ei_end;
+
+ put(vertex_color, u, Color::gray()); vis.discover_vertex(u, g);
+ for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
+ Vertex v = target(*ei, g); vis.examine_edge(*ei, g);
+ ColorValue v_color = get(vertex_color, v);
+ EColorValue uv_color = get(edge_color, *ei);
+ put(edge_color, *ei, EColor::black());
+ if (v_color == Color::white()) { vis.tree_edge(*ei, g);
+ undir_dfv_impl(g, v, vis, vertex_color, edge_color);
+ } else if (v_color == Color::gray() && uv_color == EColor::white())
+ vis.back_edge(*ei, g);
+ }
+ put(vertex_color, u, Color::black()); vis.finish_vertex(u, g);
+ }
+
+#endif // ! BOOST_RECURSIVE_DFS
+
+ } // namespace detail
+
+ template <typename Graph, typename DFSVisitor,
+ typename VertexColorMap, typename EdgeColorMap,
+ typename Vertex>
+ void
+ undirected_dfs(const Graph& g, DFSVisitor vis,
+ VertexColorMap vertex_color, EdgeColorMap edge_color,
+ Vertex start_vertex)
+ {
+ function_requires<DFSVisitorConcept<DFSVisitor, Graph> >();
+ function_requires<EdgeListGraphConcept<Graph> >();
+
+ typedef typename property_traits<VertexColorMap>::value_type ColorValue;
+ typedef color_traits<ColorValue> Color;
+
+ typename graph_traits<Graph>::vertex_iterator ui, ui_end;
+ for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
+ put(vertex_color, *ui, Color::white()); vis.initialize_vertex(*ui, g);
+ }
+ typename graph_traits<Graph>::edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ put(edge_color, *ei, Color::white());
+
+ if (start_vertex != *vertices(g).first){ vis.start_vertex(start_vertex, g);
+ detail::undir_dfv_impl(g, start_vertex, vis, vertex_color, edge_color);
+ }
+
+ for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
+ ColorValue u_color = get(vertex_color, *ui);
+ if (u_color == Color::white()) { vis.start_vertex(*ui, g);
+ detail::undir_dfv_impl(g, *ui, vis, vertex_color, edge_color);
+ }
+ }
+ }
+
+ template <typename Graph, typename DFSVisitor, typename VertexColorMap,
+ typename EdgeColorMap>
+ void
+ undirected_dfs(const Graph& g, DFSVisitor vis,
+ VertexColorMap vertex_color, EdgeColorMap edge_color)
+ {
+ undirected_dfs(g, vis, vertex_color, edge_color, *vertices(g).first);
+ }
+
+ namespace detail {
+ template <typename VertexColorMap>
+ struct udfs_dispatch {
+
+ template <typename Graph, typename Vertex,
+ typename DFSVisitor, typename EdgeColorMap,
+ typename P, typename T, typename R>
+ static void
+ apply(const Graph& g, DFSVisitor vis, Vertex start_vertex,
+ const bgl_named_params<P, T, R>&,
+ EdgeColorMap edge_color,
+ VertexColorMap vertex_color)
+ {
+ undirected_dfs(g, vis, vertex_color, edge_color, start_vertex);
+ }
+ };
+
+ template <>
+ struct udfs_dispatch<detail::error_property_not_found> {
+ template <typename Graph, typename Vertex, typename DFSVisitor,
+ typename EdgeColorMap,
+ typename P, typename T, typename R>
+ static void
+ apply(const Graph& g, DFSVisitor vis, Vertex start_vertex,
+ const bgl_named_params<P, T, R>& params,
+ EdgeColorMap edge_color,
+ detail::error_property_not_found)
+ {
+ std::vector<default_color_type> color_vec(num_vertices(g));
+ default_color_type c = white_color; // avoid warning about un-init
+ undirected_dfs
+ (g, vis, make_iterator_property_map
+ (color_vec.begin(),
+ choose_const_pmap(get_param(params, vertex_index),
+ g, vertex_index), c),
+ edge_color,
+ start_vertex);
+ }
+ };
+
+ } // namespace detail
+
+
+ // Named Parameter Variant
+ template <typename Graph, typename P, typename T, typename R>
+ void
+ undirected_dfs(const Graph& g,
+ const bgl_named_params<P, T, R>& params)
+ {
+ typedef typename property_value< bgl_named_params<P, T, R>,
+ vertex_color_t>::type C;
+ detail::udfs_dispatch<C>::apply
+ (g,
+ choose_param(get_param(params, graph_visitor),
+ make_dfs_visitor(null_visitor())),
+ choose_param(get_param(params, root_vertex_t()),
+ *vertices(g).first),
+ params,
+ get_param(params, edge_color),
+ get_param(params, vertex_color)
+ );
+ }
+
+
+ template <typename IncidenceGraph, typename DFSVisitor,
+ typename VertexColorMap, typename EdgeColorMap>
+ void undirected_depth_first_visit
+ (const IncidenceGraph& g,
+ typename graph_traits<IncidenceGraph>::vertex_descriptor u,
+ DFSVisitor vis, VertexColorMap vertex_color, EdgeColorMap edge_color)
+ {
+ detail::undir_dfv_impl(g, u, vis, vertex_color, edge_color);
+ }
+
+
+} // namespace boost
+
+
+#endif
Added: branches/CMake/release/libs/graph/include/boost/graph/vector_as_graph.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/vector_as_graph.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,332 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Copyright 2006 The Trustees of Indiana University.
+// Copyright (C) 2001 Vladimir Prus <ghost_at_[hidden]>
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Douglas Gregor
+//
+// 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 mutating functions (add_edge, etc.) were added by Vladimir Prus.
+
+#ifndef BOOST_VECTOR_AS_GRAPH_HPP
+#define BOOST_VECTOR_AS_GRAPH_HPP
+
+#include <cassert>
+#include <utility>
+#include <vector>
+#include <cstddef>
+#include <boost/iterator.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/pending/integer_range.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/properties.hpp>
+#include <algorithm>
+
+/*
+ This module implements the VertexListGraph concept using a
+ std::vector as the "back-bone" of the graph (the vector *is* the
+ graph object). The edge-lists type of the graph is templated, so the
+ user can choose any STL container, so long as the value_type of the
+ container is convertible to the size_type of the vector. For now any
+ graph properties must be stored seperately.
+
+ This module requires the C++ compiler to support partial
+ specialization for the graph_traits class, so this is not portable
+ to VC++.
+
+*/
+
+#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+#error The vector-as-graph module requires a compiler that supports partial specialization
+#endif
+
+
+namespace boost {
+ namespace detail {
+ template <class EdgeList> struct val_out_edge_ret;
+ template <class EdgeList> struct val_out_edge_iter;
+ template <class EdgeList> struct val_edge;
+ }
+}
+
+#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+namespace boost {
+
+ struct vector_as_graph_traversal_tag
+ : public vertex_list_graph_tag,
+ public adjacency_graph_tag,
+ public incidence_graph_tag { };
+
+ template <class EdgeList>
+ struct graph_traits< std::vector<EdgeList> >
+ {
+ typedef typename EdgeList::value_type V;
+ typedef V vertex_descriptor;
+ typedef typename detail::val_edge<EdgeList>::type edge_descriptor;
+ typedef typename EdgeList::const_iterator adjacency_iterator;
+ typedef typename detail::val_out_edge_iter<EdgeList>::type
+ out_edge_iterator;
+ typedef void in_edge_iterator;
+ typedef void edge_iterator;
+ typedef typename integer_range<V>::iterator vertex_iterator;
+ typedef directed_tag directed_category;
+ typedef allow_parallel_edge_tag edge_parallel_category;
+ typedef vector_as_graph_traversal_tag traversal_category;
+ typedef typename std::vector<EdgeList>::size_type vertices_size_type;
+ typedef void edges_size_type;
+ typedef typename EdgeList::size_type degree_size_type;
+ };
+ template <class EdgeList>
+ struct edge_property_type< std::vector<EdgeList> >
+ {
+ typedef void type;
+ };
+ template <class EdgeList>
+ struct vertex_property_type< std::vector<EdgeList> >
+ {
+ typedef void type;
+ };
+ template <class EdgeList>
+ struct graph_property_type< std::vector<EdgeList> >
+ {
+ typedef void type;
+ };
+}
+#endif
+
+namespace boost {
+
+ namespace detail {
+
+ // "val" is short for Vector Adjacency List
+
+ template <class EdgeList>
+ struct val_edge
+ {
+ typedef typename EdgeList::value_type V;
+ typedef std::pair<V,V> type;
+ };
+
+ // need rewrite this using boost::iterator_adaptor
+ template <class V, class Iter>
+ class val_out_edge_iterator
+ : public boost::iterator<std::input_iterator_tag, std::pair<V,V>,
+ std::ptrdiff_t, std::pair<V,V>*, const std::pair<V,V> >
+ {
+ typedef val_out_edge_iterator self;
+ typedef std::pair<V,V> Edge;
+ public:
+ val_out_edge_iterator() { }
+ val_out_edge_iterator(V s, Iter i) : _source(s), _iter(i) { }
+ Edge operator*() const { return Edge(_source, *_iter); }
+ self& operator++() { ++_iter; return *this; }
+ self operator++(int) { self t = *this; ++_iter; return t; }
+ bool operator==(const self& x) const { return _iter == x._iter; }
+ bool operator!=(const self& x) const { return _iter != x._iter; }
+ protected:
+ V _source;
+ Iter _iter;
+ };
+
+ template <class EdgeList>
+ struct val_out_edge_iter
+ {
+ typedef typename EdgeList::value_type V;
+ typedef typename EdgeList::const_iterator Iter;
+ typedef val_out_edge_iterator<V,Iter> type;
+ };
+
+ template <class EdgeList>
+ struct val_out_edge_ret
+ {
+ typedef typename val_out_edge_iter<EdgeList>::type IncIter;
+ typedef std::pair<IncIter,IncIter> type;
+ };
+
+ } // namesapce detail
+
+ template <class EdgeList, class Alloc>
+ typename detail::val_out_edge_ret<EdgeList>::type
+ out_edges(typename EdgeList::value_type v,
+ const std::vector<EdgeList, Alloc>& g)
+ {
+ typedef typename detail::val_out_edge_iter<EdgeList>::type Iter;
+ typedef typename detail::val_out_edge_ret<EdgeList>::type return_type;
+ return return_type(Iter(v, g[v].begin()), Iter(v, g[v].end()));
+ }
+
+ template <class EdgeList, class Alloc>
+ typename EdgeList::size_type
+ out_degree(typename EdgeList::value_type v,
+ const std::vector<EdgeList, Alloc>& g)
+ {
+ return g[v].size();
+ }
+
+ template <class EdgeList, class Alloc>
+ std::pair<typename EdgeList::const_iterator,
+ typename EdgeList::const_iterator>
+ adjacent_vertices(typename EdgeList::value_type v,
+ const std::vector<EdgeList, Alloc>& g)
+ {
+ return std::make_pair(g[v].begin(), g[v].end());
+ }
+
+ // source() and target() already provided for pairs in graph_traits.hpp
+
+ template <class EdgeList, class Alloc>
+ std::pair<typename boost::integer_range<typename EdgeList::value_type>
+ ::iterator,
+ typename boost::integer_range<typename EdgeList::value_type>
+ ::iterator >
+ vertices(const std::vector<EdgeList, Alloc>& v)
+ {
+ typedef typename boost::integer_range<typename EdgeList::value_type>
+ ::iterator Iter;
+ return std::make_pair(Iter(0), Iter(v.size()));
+ }
+
+ template <class EdgeList, class Alloc>
+ typename std::vector<EdgeList, Alloc>::size_type
+ num_vertices(const std::vector<EdgeList, Alloc>& v)
+ {
+ return v.size();
+ }
+
+ template<class EdgeList, class Allocator>
+ typename std::pair<typename detail::val_edge<EdgeList>::type, bool>
+ add_edge(typename EdgeList::value_type u, typename EdgeList::value_type v,
+ std::vector<EdgeList, Allocator>& g)
+ {
+ typedef typename detail::val_edge<EdgeList>::type edge_type;
+ g[u].insert(g[u].end(), v);
+ return std::make_pair(edge_type(u, v), true);
+ }
+
+ template<class EdgeList, class Allocator>
+ typename std::pair<typename detail::val_edge<EdgeList>::type, bool>
+ edge(typename EdgeList::value_type u, typename EdgeList::value_type v,
+ std::vector<EdgeList, Allocator>& g)
+ {
+ typedef typename detail::val_edge<EdgeList>::type edge_type;
+ typename EdgeList::iterator i = g[u].begin(), end = g[u].end();
+ for (; i != end; ++i)
+ if (*i == v)
+ return std::make_pair(edge_type(u, v), true);
+ return std::make_pair(edge_type(), false);
+ }
+
+ template<class EdgeList, class Allocator>
+ void
+ remove_edge(typename EdgeList::value_type u, typename EdgeList::value_type v,
+ std::vector<EdgeList, Allocator>& g)
+ {
+ typename EdgeList::iterator i = std::remove(g[u].begin(), g[u].end(), v);
+ if (i != g[u].end())
+ g[u].erase(i, g[u].end());
+ }
+
+ template<class EdgeList, class Allocator>
+ void
+ remove_edge(typename detail::val_edge<EdgeList>::type e,
+ std::vector<EdgeList, Allocator>& g)
+ {
+ typename EdgeList::value_type u, v;
+ u = e.first;
+ v = e.second;
+ // FIXME: edge type does not fully specify the edge to be deleted
+ typename EdgeList::iterator i = std::remove(g[u].begin(), g[u].end(), v);
+ if (i != g[u].end())
+ g[u].erase(i, g[u].end());
+ }
+
+ template<class EdgeList, class Allocator, class Predicate>
+ void
+ remove_edge_if(Predicate p,
+ std::vector<EdgeList, Allocator>& g)
+ {
+ for (std::size_t u = 0; u < g.size(); ++u) {
+ // Oops! gcc gets internal compiler error on compose_.......
+
+ typedef typename EdgeList::iterator iterator;
+ iterator b = g[u].begin(), e = g[u].end();
+
+ if (!g[u].empty()) {
+
+ for(; b != e;) {
+ if (p(std::make_pair(u, *b))) {
+ --e;
+ if (b == e)
+ break;
+ else
+ iter_swap(b, e);
+ } else {
+ ++b;
+ }
+ }
+ }
+
+ if (e != g[u].end())
+ g[u].erase(e, g[u].end());
+ }
+ }
+
+ template<class EdgeList, class Allocator>
+ typename EdgeList::value_type
+ add_vertex(std::vector<EdgeList, Allocator>& g)
+ {
+ g.resize(g.size()+1);
+ return g.size()-1;
+ }
+
+ template<class EdgeList, class Allocator>
+ void
+ clear_vertex(typename EdgeList::value_type u,
+ std::vector<EdgeList, Allocator>& g)
+ {
+ g[u].clear();
+ for (std::size_t i = 0; i < g.size(); ++i)
+ remove_edge(i, u, g);
+ }
+
+ template<class EdgeList, class Allocator>
+ void
+ remove_vertex(typename EdgeList::value_type u,
+ std::vector<EdgeList, Allocator>& g)
+ {
+ typedef typename EdgeList::iterator iterator;
+ clear_vertex(u, g);
+ g.erase(g.begin() + u);
+ for (std::size_t i = 0; i < g.size(); ++i)
+ for ( iterator it = g[i].begin(); it != g[i].end(); ++it )
+ // after clear_vertex *it is never equal to u
+ if ( *it > u )
+ --*it;
+ }
+
+ template<typename EdgeList, typename Allocator>
+ struct property_map<std::vector<EdgeList, Allocator>, vertex_index_t>
+ {
+ typedef identity_property_map type;
+ typedef type const_type;
+ };
+
+ template<typename EdgeList, typename Allocator>
+ identity_property_map
+ get(vertex_index_t, const std::vector<EdgeList, Allocator>&)
+ {
+ return identity_property_map();
+ }
+
+ template<typename EdgeList, typename Allocator>
+ identity_property_map
+ get(vertex_index_t, std::vector<EdgeList, Allocator>&)
+ {
+ return identity_property_map();
+ }
+} // namespace boost
+
+#endif // BOOST_VECTOR_AS_GRAPH_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/visitors.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/visitors.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,279 @@
+//=======================================================================
+// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
+// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
+//
+// 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)
+//=======================================================================
+//
+// Revision History:
+// 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
+//
+#ifndef BOOST_GRAPH_GRAPH_SEARCH_VISITORS_HPP
+#define BOOST_GRAPH_GRAPH_SEARCH_VISITORS_HPP
+
+#include <iosfwd>
+#include <boost/config.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/limits.hpp>
+#include <boost/graph/detail/is_same.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+// Stay out of the way of the concept checking class
+# define Graph Graph_
+#endif
+
+namespace boost {
+
+ // This is a bit more convenient than std::numeric_limits because
+ // you don't have to explicitly provide type T.
+ template <class T>
+ inline T numeric_limits_max(T) { return (std::numeric_limits<T>::max)(); }
+
+ //========================================================================
+ // Event Tags
+
+ namespace detail {
+ // For partial specialization workaround
+ enum event_visitor_enum
+ { on_no_event_num,
+ on_initialize_vertex_num, on_start_vertex_num,
+ on_discover_vertex_num, on_finish_vertex_num, on_examine_vertex_num,
+ on_examine_edge_num, on_tree_edge_num, on_non_tree_edge_num,
+ on_gray_target_num, on_black_target_num,
+ on_forward_or_cross_edge_num, on_back_edge_num,
+ on_edge_relaxed_num, on_edge_not_relaxed_num,
+ on_edge_minimized_num, on_edge_not_minimized_num
+ };
+
+ template<typename Event, typename Visitor>
+ struct functor_to_visitor : Visitor
+ {
+ typedef Event event_filter;
+ functor_to_visitor(const Visitor& visitor) : Visitor(visitor) {}
+ };
+
+ } // namespace detail
+
+ struct on_no_event { enum { num = detail::on_no_event_num }; };
+
+ struct on_initialize_vertex {
+ enum { num = detail::on_initialize_vertex_num }; };
+ struct on_start_vertex { enum { num = detail::on_start_vertex_num }; };
+ struct on_discover_vertex { enum { num = detail::on_discover_vertex_num }; };
+ struct on_examine_vertex { enum { num = detail::on_examine_vertex_num }; };
+ struct on_finish_vertex { enum { num = detail::on_finish_vertex_num }; };
+
+ struct on_examine_edge { enum { num = detail::on_examine_edge_num }; };
+ struct on_tree_edge { enum { num = detail::on_tree_edge_num }; };
+ struct on_non_tree_edge { enum { num = detail::on_non_tree_edge_num }; };
+ struct on_gray_target { enum { num = detail::on_gray_target_num }; };
+ struct on_black_target { enum { num = detail::on_black_target_num }; };
+ struct on_forward_or_cross_edge {
+ enum { num = detail::on_forward_or_cross_edge_num }; };
+ struct on_back_edge { enum { num = detail::on_back_edge_num }; };
+
+ struct on_edge_relaxed { enum { num = detail::on_edge_relaxed_num }; };
+ struct on_edge_not_relaxed {
+ enum { num = detail::on_edge_not_relaxed_num }; };
+ struct on_edge_minimized { enum { num = detail::on_edge_minimized_num }; };
+ struct on_edge_not_minimized {
+ enum { num = detail::on_edge_not_minimized_num }; };
+
+ struct true_tag { enum { num = true }; };
+ struct false_tag { enum { num = false }; };
+
+ //========================================================================
+ // base_visitor and null_visitor
+
+ // needed for MSVC workaround
+ template <class Visitor>
+ struct base_visitor {
+ typedef on_no_event event_filter;
+ template <class T, class Graph>
+ void operator()(T, Graph&) { }
+ };
+
+ struct null_visitor : public base_visitor<null_visitor> {
+ typedef on_no_event event_filter;
+ template <class T, class Graph>
+ void operator()(T, Graph&) { }
+ };
+
+ //========================================================================
+ // The invoke_visitors() function
+
+ namespace detail {
+ template <class Visitor, class T, class Graph>
+ inline void
+ invoke_dispatch(Visitor& v, T x, Graph& g, true_tag) {
+ v(x, g);
+ }
+ template <class Visitor, class T, class Graph>
+ inline void
+ invoke_dispatch(Visitor&, T, Graph&, false_tag) { }
+ } // namespace detail
+
+ template <class Visitor, class Rest, class T, class Graph, class Tag>
+ inline void
+ invoke_visitors(std::pair<Visitor, Rest>& vlist, T x, Graph& g, Tag tag) {
+ typedef typename Visitor::event_filter Category;
+ typedef typename graph_detail::is_same<Category, Tag>::is_same_tag
+ IsSameTag;
+ detail::invoke_dispatch(vlist.first, x, g, IsSameTag());
+ invoke_visitors(vlist.second, x, g, tag);
+ }
+#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
+ template <class Visitor, class T, class Graph, class Tag>
+ inline void
+ invoke_visitors(base_visitor<Visitor>& vis, T x, Graph& g, Tag) {
+ typedef typename Visitor::event_filter Category;
+ typedef typename graph_detail::is_same<Category, Tag>::is_same_tag
+ IsSameTag;
+ Visitor& v = static_cast<Visitor&>(vis);
+ detail::invoke_dispatch(v, x, g, IsSameTag());
+ }
+#else
+ template <class Visitor, class T, class Graph, class Tag>
+ inline void
+ invoke_visitors(Visitor& v, T x, Graph& g, Tag) {
+ typedef typename Visitor::event_filter Category;
+ typedef typename graph_detail::is_same<Category, Tag>::is_same_tag
+ IsSameTag;
+ detail::invoke_dispatch(v, x, g, IsSameTag());
+ }
+#endif
+
+ //========================================================================
+ // predecessor_recorder
+
+ template <class PredecessorMap, class Tag>
+ struct predecessor_recorder
+ : public base_visitor<predecessor_recorder<PredecessorMap, Tag> >
+ {
+ typedef Tag event_filter;
+ predecessor_recorder(PredecessorMap pa) : m_predecessor(pa) { }
+ template <class Edge, class Graph>
+ void operator()(Edge e, const Graph& g) {
+ put(m_predecessor, target(e, g), source(e, g));
+ }
+ PredecessorMap m_predecessor;
+ };
+ template <class PredecessorMap, class Tag>
+ predecessor_recorder<PredecessorMap, Tag>
+ record_predecessors(PredecessorMap pa, Tag) {
+ return predecessor_recorder<PredecessorMap, Tag> (pa);
+ }
+
+ //========================================================================
+ // edge_predecessor_recorder
+
+ template <class PredEdgeMap, class Tag>
+ struct edge_predecessor_recorder
+ : public base_visitor<edge_predecessor_recorder<PredEdgeMap, Tag> >
+ {
+ typedef Tag event_filter;
+ edge_predecessor_recorder(PredEdgeMap pa) : m_predecessor(pa) { }
+ template <class Edge, class Graph>
+ void operator()(Edge e, const Graph& g) {
+ put(m_predecessor, target(e, g), e);
+ }
+ PredEdgeMap m_predecessor;
+ };
+ template <class PredEdgeMap, class Tag>
+ edge_predecessor_recorder<PredEdgeMap, Tag>
+ record_edge_predecessors(PredEdgeMap pa, Tag) {
+ return edge_predecessor_recorder<PredEdgeMap, Tag> (pa);
+ }
+
+ //========================================================================
+ // distance_recorder
+
+ template <class DistanceMap, class Tag>
+ struct distance_recorder
+ : public base_visitor<distance_recorder<DistanceMap, Tag> >
+ {
+ typedef Tag event_filter;
+ distance_recorder(DistanceMap pa) : m_distance(pa) { }
+ template <class Edge, class Graph>
+ void operator()(Edge e, const Graph& g) {
+ typename graph_traits<Graph>::vertex_descriptor
+ u = source(e, g), v = target(e, g);
+ put(m_distance, v, get(m_distance, u) + 1);
+ }
+ DistanceMap m_distance;
+ };
+ template <class DistanceMap, class Tag>
+ distance_recorder<DistanceMap, Tag>
+ record_distances(DistanceMap pa, Tag) {
+ return distance_recorder<DistanceMap, Tag> (pa);
+ }
+
+ //========================================================================
+ // time_stamper
+
+
+ template <class TimeMap, class TimeT, class Tag>
+ struct time_stamper
+ : public base_visitor<time_stamper<TimeMap, TimeT, Tag> >
+ {
+ typedef Tag event_filter;
+ time_stamper(TimeMap pa, TimeT& t) : m_time_pa(pa), m_time(t) { }
+ template <class Vertex, class Graph>
+ void operator()(Vertex u, const Graph&) {
+ put(m_time_pa, u, ++m_time);
+ }
+ TimeMap m_time_pa;
+ TimeT& m_time;
+ };
+ template <class TimeMap, class TimeT, class Tag>
+ time_stamper<TimeMap, TimeT, Tag>
+ stamp_times(TimeMap pa, TimeT& time_counter, Tag) {
+ return time_stamper<TimeMap, TimeT, Tag>(pa, time_counter);
+ }
+
+ //========================================================================
+ // property_writer
+
+ template <class PA, class OutputIterator, class Tag>
+ struct property_writer
+ : public base_visitor<property_writer<PA, OutputIterator, Tag> >
+ {
+ typedef Tag event_filter;
+
+ property_writer(PA pa, OutputIterator out) : m_pa(pa), m_out(out) { }
+
+ template <class T, class Graph>
+ void operator()(T x, Graph&) { *m_out++ = get(m_pa, x); }
+ PA m_pa;
+ OutputIterator m_out;
+ };
+ template <class PA, class OutputIterator, class Tag>
+ property_writer<PA, OutputIterator, Tag>
+ write_property(PA pa, OutputIterator out, Tag) {
+ return property_writer<PA, OutputIterator, Tag>(pa, out);
+ }
+
+#define BOOST_GRAPH_EVENT_STUB(Event,Kind) \
+ typedef ::boost::Event Event##_type; \
+ template<typename Visitor> \
+ Kind##_visitor<std::pair<detail::functor_to_visitor<Event##_type, \
+ Visitor>, Visitors> > \
+ do_##Event(Visitor visitor) \
+ { \
+ typedef std::pair<detail::functor_to_visitor<Event##_type, Visitor>, \
+ Visitors> visitor_list; \
+ typedef Kind##_visitor<visitor_list> result_type; \
+ return result_type(visitor_list(visitor, m_vis)); \
+ }
+
+} /* namespace boost */
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+// Stay out of the way of the concept checking class
+# undef Graph
+#endif
+
+#endif
Added: branches/CMake/release/libs/graph/include/boost/graph/wavefront.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/wavefront.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,135 @@
+//
+//=======================================================================
+// Copyright 2002 Marc Wintermantel (wintermantel_at_[hidden])
+// ETH Zurich, Center of Structure Technologies (www.imes.ethz.ch/st)
+//
+// 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)
+//=======================================================================
+//
+
+#ifndef BOOST_GRAPH_WAVEFRONT_HPP
+#define BOOST_GRAPH_WAVEFRONT_HPP
+
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/detail/numeric_traits.hpp>
+#include <boost/graph/bandwidth.hpp>
+#include <cmath>
+#include <vector>
+#include <algorithm> // for std::min and std::max
+
+namespace boost {
+
+ template <typename Graph, typename VertexIndexMap>
+ typename graph_traits<Graph>::vertices_size_type
+ ith_wavefront(typename graph_traits<Graph>::vertex_descriptor i,
+ const Graph& g,
+ VertexIndexMap index)
+ {
+ typename graph_traits<Graph>::vertex_descriptor v, w;
+ typename graph_traits<Graph>::vertices_size_type b = 1;
+ typename graph_traits<Graph>::out_edge_iterator edge_it2, edge_it2_end;
+ typename graph_traits<Graph>::vertices_size_type index_i = index[i];
+ std::vector<bool> rows_active(num_vertices(g), false);
+
+ rows_active[index_i] = true;
+
+ typename graph_traits<Graph>::vertex_iterator ui, ui_end;
+ for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
+ {
+ v = *ui;
+ if(index[v] <= index_i)
+ {
+ for (tie(edge_it2, edge_it2_end) = out_edges(v, g); edge_it2 != edge_it2_end; ++edge_it2)
+ {
+ w = target(*edge_it2, g);
+ if( (index[w] >= index_i) && (!rows_active[index[w]]) )
+ {
+ b++;
+ rows_active[index[w]] = true;
+ }
+ }
+ }
+ }
+
+ return b;
+ }
+
+
+ template <typename Graph>
+ typename graph_traits<Graph>::vertices_size_type
+ ith_wavefront(typename graph_traits<Graph>::vertex_descriptor i,
+ const Graph& g)
+ {
+ return ith_wavefront(i, g, get(vertex_index, g));
+ }
+
+
+ template <typename Graph, typename VertexIndexMap>
+ typename graph_traits<Graph>::vertices_size_type
+ max_wavefront(const Graph& g, VertexIndexMap index)
+ {
+ BOOST_USING_STD_MAX();
+ typename graph_traits<Graph>::vertices_size_type b = 0;
+ typename graph_traits<Graph>::vertex_iterator i, end;
+ for (tie(i, end) = vertices(g); i != end; ++i)
+ b = max BOOST_PREVENT_MACRO_SUBSTITUTION(b, ith_wavefront(*i, g, index));
+ return b;
+ }
+
+ template <typename Graph>
+ typename graph_traits<Graph>::vertices_size_type
+ max_wavefront(const Graph& g)
+ {
+ return max_wavefront(g, get(vertex_index, g));
+ }
+
+
+ template <typename Graph, typename VertexIndexMap>
+ double
+ aver_wavefront(const Graph& g, VertexIndexMap index)
+ {
+ double b = 0;
+ typename graph_traits<Graph>::vertex_iterator i, end;
+ for (tie(i, end) = vertices(g); i != end; ++i)
+ b += ith_wavefront(*i, g, index);
+
+ b /= num_vertices(g);
+ return b;
+ }
+
+ template <typename Graph>
+ double
+ aver_wavefront(const Graph& g)
+ {
+ return aver_wavefront(g, get(vertex_index, g));
+ }
+
+
+ template <typename Graph, typename VertexIndexMap>
+ double
+ rms_wavefront(const Graph& g, VertexIndexMap index)
+ {
+ double b = 0;
+ typename graph_traits<Graph>::vertex_iterator i, end;
+ for (tie(i, end) = vertices(g); i != end; ++i)
+ b += std::pow(double ( ith_wavefront(*i, g, index) ), 2.0);
+
+ b /= num_vertices(g);
+
+ return std::sqrt(b);
+ }
+
+ template <typename Graph>
+ double
+ rms_wavefront(const Graph& g)
+ {
+ return rms_wavefront(g, get(vertex_index, g));
+ }
+
+
+} // namespace boost
+
+#endif // BOOST_GRAPH_WAVEFRONT_HPP
Added: branches/CMake/release/libs/graph/include/boost/graph/write_dimacs.hpp
==============================================================================
--- (empty file)
+++ branches/CMake/release/libs/graph/include/boost/graph/write_dimacs.hpp 2008-07-01 12:48:00 EDT (Tue, 01 Jul 2008)
@@ -0,0 +1,72 @@
+// Copyright (c) 2006, Stephan Diederich
+//
+// This code may be used under either of the following two licences:
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE. OF SUCH DAMAGE.
+//
+// Or:
+//
+// 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)
+
+/*
+ Writes maximal flow problem in extended DIMACS format to an OutputIterator
+ Vertex indices are read from an IndexMap and shiftet by 1.
+ so their new range is [1..num_vertices(g)]
+*/
+
+/* ----------------------------------------------------------------- */
+
+#include <vector>
+#include <string>
+#include <ostream>
+
+namespace boost {
+
+template <class Graph, class CapacityMap, class IndexMap>
+void write_dimacs_max_flow(const Graph& g,
+ CapacityMap capacity,
+ IndexMap idx,
+ typename graph_traits<Graph>::vertex_descriptor src,
+ typename graph_traits<Graph>::vertex_descriptor sink,
+ std::ostream& out)
+{
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+ typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
+ typedef typename graph_traits<Graph>::edges_size_type edges_size_type;
+ typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
+
+ out << "c DIMACS max-flow file generated from boost::write_dimacs_max_flow" << std::endl;
+ out << "p max " << num_vertices(g) << " " << num_edges(g) << std::endl; //print problem description "max" and number of verts and edges
+ out << "n " << get(idx, src) + 1 << " s" << std::endl;; //say which one is source
+ out << "n " << get(idx, sink) + 1 << " t" << std::endl; //say which one is sink
+
+ //output the edges
+ edge_iterator ei, e_end;
+ for(tie(ei,e_end) = edges(g); ei!=e_end; ++ei){
+ out << "a " << idx[ source(*ei, g) ] + 1 << " " << idx[ target(*ei, g) ] + 1 << " " << get(capacity,*ei) << std::endl;
+ }
+}
+
+} // namespace boost
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk