diff --git a/include/boost/graph/bron_kerbosch_all_cliques.hpp b/include/boost/graph/bron_kerbosch_all_cliques.hpp index b9d4f016..48579068 100644 --- a/include/boost/graph/bron_kerbosch_all_cliques.hpp +++ b/include/boost/graph/bron_kerbosch_all_cliques.hpp @@ -4,8 +4,8 @@ // Boost Software License, Version 1.0 (See accompanying file // LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_GRAPH_CLIQUE_HXX -#define BOOST_GRAPH_CLIQUE_HXX +#ifndef BOOST_GRAPH_CLIQUE_HPP +#define BOOST_GRAPH_CLIQUE_HPP #include #include diff --git a/include/boost/graph/closeness_centrality.hpp b/include/boost/graph/closeness_centrality.hpp new file mode 100644 index 00000000..77cea7b0 --- /dev/null +++ b/include/boost/graph/closeness_centrality.hpp @@ -0,0 +1,157 @@ +// (C) Copyright 2007-2009 Andrew Sutton +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0 (See accompanying file +// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GRAPH_CLOSENESS_CENTRALITY_HPP +#define BOOST_GRAPH_CLOSENESS_CENTRALITY_HPP + +#include +#include + +namespace boost +{ +template > +struct closeness_measure + : public geodesic_measure +{ + typedef geodesic_measure< Graph, DistanceType, ResultType> base_type; + typedef typename base_type::distance_type distance_type; + typedef typename base_type::result_type result_type; + + result_type operator ()(distance_type d, const Graph&) + { + function_requires< NumericValueConcept >(); + function_requires< NumericValueConcept >(); + function_requires< AdaptableUnaryFunctionConcept >(); + return (d == base_type::infinite_distance()) + ? base_type::zero_result() + : rec(result_type(d)); + } + Reciprocal rec; +}; + +template +inline closeness_measure< + Graph, typename property_traits::value_type, double, + detail::reciprocal > +measure_closeness(const Graph&, DistanceMap) +{ + typedef typename property_traits::value_type Distance; + return closeness_measure >(); +} + +template +inline closeness_measure< + Graph, typename property_traits::value_type, T, + detail::reciprocal > +measure_closeness(const Graph&, DistanceMap) +{ + typedef typename property_traits::value_type Distance; + return closeness_measure >(); +} + +template +inline closeness_measure< + Graph, typename property_traits::value_type, T, + Reciprocal> +measure_closeness(const Graph&, DistanceMap) +{ + typedef typename property_traits::value_type Distance; + return closeness_measure(); +} + +template +inline typename Measure::result_type +closeness_centrality(const Graph& g, + DistanceMap dist, + Measure measure, + Combinator combine) +{ + function_requires< VertexListGraphConcept >(); + typedef typename graph_traits::vertex_descriptor Vertex; + function_requires< ReadablePropertyMapConcept >(); + typedef typename property_traits::value_type Distance; + function_requires< NumericValueConcept >(); + function_requires< DistanceMeasureConcept >(); + + Distance n = detail::combine_distances(g, dist, combine, Distance(0)); + return measure(n, g); +} + +template +inline typename Measure::result_type +closeness_centrality(const Graph& g, DistanceMap dist, Measure measure) +{ + function_requires< GraphConcept >(); + typedef typename graph_traits::vertex_descriptor Vertex; + function_requires< ReadablePropertyMapConcept >(); + typedef typename property_traits::value_type Distance; + + return closeness_centrality(g, dist, measure, std::plus()); +} + +template +inline double closeness_centrality(const Graph& g, DistanceMap dist) +{ return closeness_centrality(g, dist, measure_closeness(g, dist)); } + +template +inline T closeness_centrality(const Graph& g, DistanceMap dist) +{ return closeness_centrality(g, dist, measure_closeness(g, dist)); } + +template +inline void +all_closeness_centralities(const Graph& g, + DistanceMatrixMap dist, + CentralityMap cent, + Measure measure) +{ + function_requires< VertexListGraphConcept >(); + typedef typename graph_traits::vertex_descriptor Vertex; + function_requires< ReadablePropertyMapConcept >(); + typedef typename property_traits::value_type DistanceMap; + function_requires< ReadablePropertyMapConcept >(); + function_requires< WritablePropertyMapConcept >(); + typedef typename property_traits::value_type Distance; + typedef typename property_traits::value_type Centrality; + + typename graph_traits::vertex_iterator i, end; + for(tie(i, end) = vertices(g); i != end; ++i) { + DistanceMap dm = get(dist, *i); + Centrality c = closeness_centrality(g, dm, measure); + put(cent, *i, c); + } +} + +template +inline void +all_closeness_centralities(const Graph& g, + DistanceMatrixMap dist, + CentralityMap cent) +{ + function_requires< GraphConcept >(); + typedef typename graph_traits::vertex_descriptor Vertex; + function_requires< ReadablePropertyMapConcept >(); + typedef typename property_traits::value_type DistanceMap; + function_requires< ReadablePropertyMapConcept >(); + typedef typename property_traits::value_type Distance; + typedef typename property_traits::value_type Result; + + all_closeness_centralities(g, dist, cent, measure_closeness(g, DistanceMap())); +} + +} /* namespace boost */ + +#endif diff --git a/include/boost/graph/detail/geodesic.hpp b/include/boost/graph/detail/geodesic.hpp new file mode 100644 index 00000000..f61e8af7 --- /dev/null +++ b/include/boost/graph/detail/geodesic.hpp @@ -0,0 +1,129 @@ +// (C) Copyright 2007 Andrew Sutton +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0 (See accompanying file +// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GRAPH_DETAIL_GEODESIC_HPP +#define BOOST_GRAPH_DETAIL_GEODESIC_HPP + +#include +#include +#include + +// TODO: Should this really be in detail? + +namespace boost +{ +// This is a very good discussion on centrality measures. While I can't +// say that this has been the motivating factor for the design and +// implementation of ths centrality framework, it does provide a single +// point of reference for defining things like degree and closeness +// centrality. Plus, the bibliography seems fairly complete. +// +// @article{citeulike:1144245, +// author = {Borgatti, Stephen P. and Everett, Martin G.}, +// citeulike-article-id = {1144245}, +// doi = {10.1016/j.socnet.2005.11.005}, +// journal = {Social Networks}, +// month = {October}, +// number = {4}, +// pages = {466--484}, +// priority = {0}, +// title = {A Graph-theoretic perspective on centrality}, +// url = {http://dx.doi.org/10.1016/j.socnet.2005.11.005}, +// volume = {28}, +// year = {2006} +// } +// } + +namespace detail { + // Note that this assumes T == property_traits::value_type + // and that the args and return of combine are also T. + template + inline Distance + combine_distances(const Graph& g, + DistanceMap dist, + Combinator combine, + Distance init) + { + function_requires< VertexListGraphConcept >(); + typedef typename graph_traits::vertex_descriptor Vertex; + typedef typename graph_traits::vertex_iterator VertexIterator; + function_requires< ReadablePropertyMapConcept >(); + function_requires< NumericValueConcept >(); + typedef numeric_values DistanceNumbers; + function_requires< AdaptableBinaryFunction >(); + + // If there's ever an infinite distance, then we simply return + // infinity. Note that this /will/ include the a non-zero + // distance-to-self in the combined values. However, this is usually + // zero, so it shouldn't be too problematic. + Distance ret = init; + VertexIterator i, end; + for(tie(i, end) = vertices(g); i != end; ++i) { + Vertex v = *i; + if(get(dist, v) != DistanceNumbers::infinity()) { + ret = combine(ret, get(dist, v)); + } + else { + ret = DistanceNumbers::infinity(); + break; + } + } + return ret; + } + + // Similar to std::plus, but maximizes parameters + // rather than adding them. + template + struct maximize : public std::binary_function + { + T operator ()(T x, T y) const + { return std::max(x, y); } + }; + + // Another helper, like maximize() to help abstract functional + // concepts. This is trivially instantiated for builtin numeric + // types, but should be specialized for those types that have + // discrete notions of reciprocals. + template + struct reciprocal : public std::unary_function + { + typedef std::unary_function function_type; + typedef typename function_type::result_type result_type; + typedef typename function_type::argument_type argument_type; + T operator ()(T t) + { return T(1) / t; } + }; +} /* namespace detail */ + +// This type defines the basic facilities used for computing values +// based on the geodesic distances between vertices. Examples include +// closeness centrality and mean geodesic distance. +template +struct geodesic_measure +{ + typedef DistanceType distance_type; + typedef ResultType result_type; + typedef typename graph_traits::vertices_size_type size_type; + + typedef numeric_values distance_values; + typedef numeric_values result_values; + + static inline distance_type infinite_distance() + { return distance_values::infinity(); } + + static inline result_type infinite_result() + { return result_values::infinity(); } + + static inline result_type zero_result() + { return result_values::zero(); } +}; + +} /* namespace boost */ + +#endif diff --git a/include/boost/graph/detail/index.hpp b/include/boost/graph/detail/index.hpp new file mode 100644 index 00000000..db1152f8 --- /dev/null +++ b/include/boost/graph/detail/index.hpp @@ -0,0 +1,74 @@ +// (C) Copyright 2007-2009 Andrew Sutton +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0 (See accompanying file +// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GRAPH_DETAIL_INDEX_HPP +#define BOOST_GRAPH_DETAIL_INDEX_HPP + +#include + +// The structures in this module are responsible for selecting and defining +// types for accessing a builting index map. Note that the selection of these +// types requires the Graph parameter to model either VertexIndexGraph or +// EdgeIndexGraph. + +namespace boost +{ + namespace detail + { + template + struct vertex_indexer + { + typedef vertex_index_t index_type; + typedef typename property_map::type map_type; + typedef typename property_map::const_type const_map_type; + typedef typename property_traits::value_type value_type; + typedef typename graph_traits::vertex_descriptor key_type; + + static const_map_type index_map(const Graph& g) + { return get(vertex_index, g); } + + static map_type index_map(Graph& g) + { return get(vertex_index, g); } + + static value_type index(key_type k, const Graph& g) + { return get(vertex_index, g, k); } + }; + + template + struct edge_indexer + { + typedef edge_index_t index_type; + typedef typename property_map::type map_type; + typedef typename property_map::const_type const_map_type; + typedef typename property_traits::value_type value_type; + typedef typename graph_traits::edge_descriptor key_type; + + static const_map_type index_map(const Graph& g) + { return get(edge_index, g); } + + static map_type index_map(Graph& g) + { return get(edge_index, g); } + + static value_type index(key_type k, const Graph& g) + { return get(edge_index, g, k); } + }; + + // NOTE: The Graph parameter MUST be a model of VertexIndexGraph or + // VertexEdgeGraph - whichever type Key is selecting. + template + struct choose_indexer + { + typedef typename mpl::if_< + is_same::vertex_descriptor>, + vertex_indexer, + edge_indexer + >::type indexer_type; + typedef typename indexer_type::index_type index_type; + }; + } +} + +#endif diff --git a/include/boost/graph/exterior_property.hpp b/include/boost/graph/exterior_property.hpp new file mode 100644 index 00000000..af6df818 --- /dev/null +++ b/include/boost/graph/exterior_property.hpp @@ -0,0 +1,117 @@ +// (C) Copyright 2007-2009 Andrew Sutton +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0 (See accompanying file +// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GRAPH_EXTERIOR_PROPERTY_HPP +#define BOOST_GRAPH_EXTERIOR_PROPERTY_HPP + +#include +#include +#include + +namespace boost { +namespace detail { + // The vector matrix provides a little abstraction over vector + // types that makes matrices easier to work with. Note that it's + // non-copyable, meaning you should be passing it by value. + template + struct vector_matrix + { + typedef std::vector container_type; + typedef std::vector matrix_type; + + typedef container_type value_type; + typedef container_type& reference; + typedef const container_type const_reference; + typedef container_type* pointer; + typedef typename matrix_type::size_type size_type; + + // Instantiate the matrix over n elements (creates an nxn matrix). + // The graph has to be passed in order to ensure the index maps + // are constructed correctly when returning indexible elements. + inline vector_matrix(size_type n) + : m_matrix(n, container_type(n)) + { } + + inline reference operator [](size_type n) + { return m_matrix[n]; } + + inline const_reference operator [](size_type n) const + { return m_matrix[n]; } + + matrix_type m_matrix; + }; +} /* namespace detail */ + +/** + * The exterior_property metafunction defines an appropriate set of types for + * creating an exterior property. An exterior property is comprised of a both + * a container and a property map that acts as its abstraction. An extension + * of this metafunction will select an appropriate "matrix" property that + * records values for pairs of vertices. + * + * @todo This does not currently support the ability to define exterior + * properties for graph types that do not model the IndexGraph concepts. A + * solution should not be especially difficult, but will require an extension + * of type traits to affect the type selection. + */ +template +struct exterior_property +{ + typedef Key key_type; + typedef Value value_type; + + typedef std::vector container_type; + typedef container_property_map map_type; + + typedef detail::vector_matrix matrix_type; + typedef matrix_property_map matrix_map_type; + +private: + exterior_property() { } + exterior_property(const exterior_property&) { } +}; + +/** + * Define a the container and property map types requried to create an exterior + * vertex property for the given value type. The Graph parameter is required to + * model the VertexIndexGraph concept. + */ +template +struct exterior_vertex_property +{ + typedef exterior_property< + Graph, typename graph_traits::vertex_descriptor, Value + > property_type; + typedef typename property_type::key_type key_type; + typedef typename property_type::value_type value_type; + typedef typename property_type::container_type container_type; + typedef typename property_type::map_type map_type; + typedef typename property_type::matrix_type matrix_type; + typedef typename property_type::matrix_map_type matrix_map_type; +}; + +/** + * Define a the container and property map types requried to create an exterior + * edge property for the given value type. The Graph parameter is required to + * model the EdgeIndexGraph concept. + */ +template +struct exterior_edge_property +{ + typedef exterior_property< + Graph, typename graph_traits::edge_descriptor, Value + > property_type; + typedef typename property_type::key_type key_type; + typedef typename property_type::value_type value_type; + typedef typename property_type::container_type container_type; + typedef typename property_type::map_type map_type; + typedef typename property_type::matrix_type matrix_type; + typedef typename property_type::matrix_map_type matrix_map_type; +}; + +} /* namespace boost */ + +#endif diff --git a/include/boost/graph/property_maps/constant_property_map.hpp b/include/boost/graph/property_maps/constant_property_map.hpp new file mode 100644 index 00000000..99ac72d8 --- /dev/null +++ b/include/boost/graph/property_maps/constant_property_map.hpp @@ -0,0 +1,59 @@ +// (C) Copyright 2007-2009 Andrew Sutton +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0 (See accompanying file +// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GRAPH_CONSTANT_PROPERTY_HPP +#define BOOST_GRAPH_CONSTANT_PROPERTY_HPP + +#include + + +// TODO: This should really be part of the property maps library rather than +// the Boost.Graph library. + +namespace boost { + +/** + * A constant property is one, that regardless of the edge or vertex given, + * will always return a constant value. + */ +template +struct constant_property_map + : public boost::put_get_helper< + const Value&, + constant_property_map + > +{ + typedef Key key_type; + typedef Value value_type; + typedef const Value& reference; + typedef boost::readable_property_map_tag category; + + constant_property_map() + : m_value() + { } + + constant_property_map(const value_type &value) + : m_value(value) + { } + + constant_property_map(const constant_property_map& copy) + : m_value(copy.m_value) + { } + + inline reference operator [](const key_type& v) const + { return m_value; } + + value_type m_value; +}; + +template +inline constant_property_map +make_constant_property(const Value& value) +{ return constant_property_map(value); } + +} /* namespace boost */ + +#endif diff --git a/include/boost/graph/property_maps/container_property_map.hpp b/include/boost/graph/property_maps/container_property_map.hpp new file mode 100644 index 00000000..f29e28bb --- /dev/null +++ b/include/boost/graph/property_maps/container_property_map.hpp @@ -0,0 +1,75 @@ +// (C) Copyright 2007-2009 Andrew Sutton +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0 (See accompanying file +// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GRAPH_CONTAINER_PROPERTY_MAP_HPP +#define BOOST_GRAPH_CONTAINER_PROPERTY_MAP_HPP + +#include +#include + +namespace boost +{ + // This is an adapter built over the iterator property map with + // more useful uniform construction semantics. Specifically, this + // requires the container rather than the iterator and the graph + // rather than the optional index map. + template + struct container_property_map + : public boost::put_get_helper< + typename iterator_property_map< + typename Container::iterator, + typename property_map< + Graph, + typename detail::choose_indexer::index_type + >::type + >::reference, + container_property_map + > + { + typedef typename detail::choose_indexer::indexer_type indexer_type; + typedef typename indexer_type::index_type index_type; + typedef iterator_property_map< + typename Container::iterator, + typename property_map::type + > map_type; + typedef typename map_type::key_type key_type; + typedef typename map_type::value_type value_type; + typedef typename map_type::reference reference; + typedef typename map_type::category category; + + // The default constructor will *probably* crash if its actually + // used for referencing vertices since the underlying iterator + // map points past the end of an unknown container. + inline container_property_map() + : m_map() + { } + + // This is the preferred constructor. It is invoked over the container + // and the graph explicitly. This requires that the underlying iterator + // map use the indices of the vertices in g rather than the default + // identity map. + // + // Note the const-cast this ensures the reference type of the + // vertex index map is non-const, which happens to be an + // artifact of passing const graph references. + inline container_property_map(Container& c, const Graph& g) + : m_map(c.begin(), indexer_type::index_map(const_cast(g))) + { } + + // Typical copy constructor. + inline container_property_map(const container_property_map& x) + : m_map(x.m_map) + { } + + // The [] operator delegates to the underlying map/ + inline reference operator [](const key_type& k) const + { return m_map[k]; } + + map_type m_map; + }; +} + +#endif diff --git a/include/boost/graph/property_maps/matrix_property_map.hpp b/include/boost/graph/property_maps/matrix_property_map.hpp new file mode 100644 index 00000000..bf4f2c9c --- /dev/null +++ b/include/boost/graph/property_maps/matrix_property_map.hpp @@ -0,0 +1,67 @@ +// (C) Copyright 2007-2009 Andrew Sutton +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0 (See accompanying file +// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GRAPH_MATRIX_PROPERTY_MAP_HPP +#define BOOST_GRAPH_MATRIX_PROPERTY_MAP_HPP + +#include + +namespace boost +{ + // This property map is built specifically for property maps over + // matrices. Like the basic property map over a container, this builds + // the property abstraction over a matrix (usually a vector of vectors) + // and returns property maps over the nested containers. + template + struct matrix_property_map + : boost::put_get_helper< + container_property_map, + matrix_property_map > + { + // abstract the indexing keys + typedef typename detail::choose_indexer::indexer_type indexer_type; + + // aliases for the nested container and its corresponding map + typedef typename Matrix::value_type container_type; + typedef container_property_map map_type; + + typedef Key key_type; + + // This property map doesn't really provide access to nested containers, + // but returns property maps over them. Since property maps are all + // copy-constructible (or should be anyways), we never return references. + // As such, this property is only readable, but not writable. Curiously, + // the inner property map is actually an lvalue pmap. + typedef map_type value_type; + typedef map_type reference; + typedef readable_property_map_tag category; + + matrix_property_map() + : m_matrix(0), m_graph(0) + { } + + matrix_property_map(Matrix& m, const Graph& g) + : m_matrix(&m), m_graph(const_cast(&g)) + { } + + matrix_property_map(const matrix_property_map& x) + : m_matrix(x.m_matrix), m_graph(x.m_graph) + { } + + inline reference operator [](key_type k) const + { + typedef typename indexer_type::value_type Index; + Index x = indexer_type::index(k, *m_graph); + return map_type((*m_matrix)[x], *m_graph); + } + + private: + mutable Matrix* m_matrix; + mutable Graph* m_graph; + }; +} + +#endif diff --git a/include/boost/graph/tiernan_all_cycles.hpp b/include/boost/graph/tiernan_all_cycles.hpp index 5465ba68..6c1339c5 100644 --- a/include/boost/graph/tiernan_all_cycles.hpp +++ b/include/boost/graph/tiernan_all_cycles.hpp @@ -4,8 +4,8 @@ // Boost Software License, Version 1.0 (See accompanying file // LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_GRAPH_CYCLE_HXX -#define BOOST_GRAPH_CYCLE_HXX +#ifndef BOOST_GRAPH_CYCLE_HPP +#define BOOST_GRAPH_CYCLE_HPP #include