|
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
==============================================================================
--- (e