annotate DEPENDENCIES/generic/include/boost/graph/geodesic_distance.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // (C) Copyright Andrew Sutton 2007
Chris@16 2 //
Chris@16 3 // Use, modification and distribution are subject to the
Chris@16 4 // Boost Software License, Version 1.0 (See accompanying file
Chris@16 5 // LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6
Chris@16 7 #ifndef BOOST_GRAPH_GEODESIC_DISTANCE_HPP
Chris@16 8 #define BOOST_GRAPH_GEODESIC_DISTANCE_HPP
Chris@16 9
Chris@16 10 #include <boost/graph/detail/geodesic.hpp>
Chris@16 11 #include <boost/graph/exterior_property.hpp>
Chris@16 12 #include <boost/concept/assert.hpp>
Chris@16 13
Chris@16 14 namespace boost
Chris@16 15 {
Chris@16 16 template <typename Graph,
Chris@16 17 typename DistanceType,
Chris@16 18 typename ResultType,
Chris@16 19 typename Divides = std::divides<ResultType> >
Chris@16 20 struct mean_geodesic_measure
Chris@16 21 : public geodesic_measure<Graph, DistanceType, ResultType>
Chris@16 22 {
Chris@16 23 typedef geodesic_measure<Graph, DistanceType, ResultType> base_type;
Chris@16 24 typedef typename base_type::distance_type distance_type;
Chris@16 25 typedef typename base_type::result_type result_type;
Chris@16 26
Chris@16 27 result_type operator ()(distance_type d, const Graph& g)
Chris@16 28 {
Chris@16 29 BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<Graph> ));
Chris@16 30 BOOST_CONCEPT_ASSERT(( NumericValueConcept<DistanceType> ));
Chris@16 31 BOOST_CONCEPT_ASSERT(( NumericValueConcept<ResultType> ));
Chris@16 32 BOOST_CONCEPT_ASSERT(( AdaptableBinaryFunctionConcept<Divides,ResultType,ResultType,ResultType> ));
Chris@16 33
Chris@16 34 return (d == base_type::infinite_distance())
Chris@16 35 ? base_type::infinite_result()
Chris@16 36 : div(result_type(d), result_type(num_vertices(g) - 1));
Chris@16 37 }
Chris@16 38 Divides div;
Chris@16 39 };
Chris@16 40
Chris@16 41 template <typename Graph, typename DistanceMap>
Chris@16 42 inline mean_geodesic_measure<Graph, typename property_traits<DistanceMap>::value_type, double>
Chris@16 43 measure_mean_geodesic(const Graph&, DistanceMap)
Chris@16 44 {
Chris@16 45 return mean_geodesic_measure<Graph, typename property_traits<DistanceMap>::value_type, double>();
Chris@16 46 }
Chris@16 47
Chris@16 48 template <typename T, typename Graph, typename DistanceMap>
Chris@16 49 inline mean_geodesic_measure<Graph, typename property_traits<DistanceMap>::value_type, T>
Chris@16 50 measure_mean_geodesic(const Graph&, DistanceMap)
Chris@16 51 {
Chris@16 52 return mean_geodesic_measure<Graph, typename property_traits<DistanceMap>::value_type, T>();
Chris@16 53 }
Chris@16 54
Chris@16 55 // This is a little different because it's expected that the result type
Chris@16 56 // should (must?) be the same as the distance type. There's a type of
Chris@16 57 // transitivity in this thinking... If the average of distances has type
Chris@16 58 // X then the average of x's should also be type X. Is there a case where this
Chris@16 59 // is not true?
Chris@16 60 //
Chris@16 61 // This type is a little under-genericized... It needs generic parameters
Chris@16 62 // for addition and division.
Chris@16 63 template <typename Graph, typename DistanceType>
Chris@16 64 struct mean_graph_distance_measure
Chris@16 65 : public geodesic_measure<Graph, DistanceType, DistanceType>
Chris@16 66 {
Chris@16 67 typedef geodesic_measure<Graph, DistanceType, DistanceType> base_type;
Chris@16 68 typedef typename base_type::distance_type distance_type;
Chris@16 69 typedef typename base_type::result_type result_type;
Chris@16 70
Chris@16 71 inline result_type operator ()(distance_type d, const Graph& g)
Chris@16 72 {
Chris@16 73 BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<Graph> ));
Chris@16 74 BOOST_CONCEPT_ASSERT(( NumericValueConcept<DistanceType> ));
Chris@16 75
Chris@16 76 if(d == base_type::infinite_distance()) {
Chris@16 77 return base_type::infinite_result();
Chris@16 78 }
Chris@16 79 else {
Chris@16 80 return d / result_type(num_vertices(g));
Chris@16 81 }
Chris@16 82 }
Chris@16 83 };
Chris@16 84
Chris@16 85 template <typename Graph, typename DistanceMap>
Chris@16 86 inline mean_graph_distance_measure<Graph, typename property_traits<DistanceMap>::value_type>
Chris@16 87 measure_graph_mean_geodesic(const Graph&, DistanceMap)
Chris@16 88 {
Chris@16 89 typedef typename property_traits<DistanceMap>::value_type T;
Chris@16 90 return mean_graph_distance_measure<Graph, T>();
Chris@16 91 }
Chris@16 92
Chris@16 93 template <typename Graph,
Chris@16 94 typename DistanceMap,
Chris@16 95 typename Measure,
Chris@16 96 typename Combinator>
Chris@16 97 inline typename Measure::result_type
Chris@16 98 mean_geodesic(const Graph& g,
Chris@16 99 DistanceMap dist,
Chris@16 100 Measure measure,
Chris@16 101 Combinator combine)
Chris@16 102 {
Chris@16 103 BOOST_CONCEPT_ASSERT(( DistanceMeasureConcept<Measure,Graph> ));
Chris@16 104 typedef typename Measure::distance_type Distance;
Chris@16 105
Chris@16 106 Distance n = detail::combine_distances(g, dist, combine, Distance(0));
Chris@16 107 return measure(n, g);
Chris@16 108 }
Chris@16 109
Chris@16 110 template <typename Graph,
Chris@16 111 typename DistanceMap,
Chris@16 112 typename Measure>
Chris@16 113 inline typename Measure::result_type
Chris@16 114 mean_geodesic(const Graph& g, DistanceMap dist, Measure measure)
Chris@16 115 {
Chris@16 116 BOOST_CONCEPT_ASSERT(( DistanceMeasureConcept<Measure,Graph> ));
Chris@16 117 typedef typename Measure::distance_type Distance;
Chris@16 118
Chris@16 119 return mean_geodesic(g, dist, measure, std::plus<Distance>());
Chris@16 120 }
Chris@16 121
Chris@16 122 template <typename Graph, typename DistanceMap>
Chris@16 123 inline double
Chris@16 124 mean_geodesic(const Graph& g, DistanceMap dist)
Chris@16 125 { return mean_geodesic(g, dist, measure_mean_geodesic(g, dist)); }
Chris@16 126
Chris@16 127 template <typename T, typename Graph, typename DistanceMap>
Chris@16 128 inline T
Chris@16 129 mean_geodesic(const Graph& g, DistanceMap dist)
Chris@16 130 { return mean_geodesic(g, dist, measure_mean_geodesic<T>(g, dist)); }
Chris@16 131
Chris@16 132
Chris@16 133 template <typename Graph,
Chris@16 134 typename DistanceMatrixMap,
Chris@16 135 typename GeodesicMap,
Chris@16 136 typename Measure>
Chris@16 137 inline typename property_traits<GeodesicMap>::value_type
Chris@16 138 all_mean_geodesics(const Graph& g,
Chris@16 139 DistanceMatrixMap dist,
Chris@16 140 GeodesicMap geo,
Chris@16 141 Measure measure)
Chris@16 142 {
Chris@16 143 BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<Graph> ));
Chris@16 144 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
Chris@16 145 typedef typename graph_traits<Graph>::vertex_iterator VertexIterator;
Chris@16 146 BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<DistanceMatrixMap,Vertex> ));
Chris@16 147 typedef typename property_traits<DistanceMatrixMap>::value_type DistanceMap;
Chris@16 148 BOOST_CONCEPT_ASSERT(( DistanceMeasureConcept<Measure,Graph> ));
Chris@16 149 typedef typename Measure::result_type Result;
Chris@16 150 BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept<GeodesicMap,Vertex> ));
Chris@16 151 BOOST_CONCEPT_ASSERT(( NumericValueConcept<Result> ));
Chris@16 152
Chris@16 153 // NOTE: We could compute the mean geodesic here by performing additional
Chris@16 154 // computations (i.e., adding and dividing). However, I don't really feel
Chris@16 155 // like fully genericizing the entire operation yet so I'm not going to.
Chris@16 156
Chris@16 157 Result inf = numeric_values<Result>::infinity();
Chris@16 158 Result sum = numeric_values<Result>::zero();
Chris@16 159 VertexIterator i, end;
Chris@16 160 for(boost::tie(i, end) = vertices(g); i != end; ++i) {
Chris@16 161 DistanceMap dm = get(dist, *i);
Chris@16 162 Result r = mean_geodesic(g, dm, measure);
Chris@16 163 put(geo, *i, r);
Chris@16 164
Chris@16 165 // compute the sum along with geodesics
Chris@16 166 if(r == inf) {
Chris@16 167 sum = inf;
Chris@16 168 }
Chris@16 169 else if(sum != inf) {
Chris@16 170 sum += r;
Chris@16 171 }
Chris@16 172 }
Chris@16 173
Chris@16 174 // return the average of averages.
Chris@16 175 return sum / Result(num_vertices(g));
Chris@16 176 }
Chris@16 177
Chris@16 178 template <typename Graph, typename DistanceMatrixMap, typename GeodesicMap>
Chris@16 179 inline typename property_traits<GeodesicMap>::value_type
Chris@16 180 all_mean_geodesics(const Graph& g, DistanceMatrixMap dist, GeodesicMap geo)
Chris@16 181 {
Chris@16 182 BOOST_CONCEPT_ASSERT(( GraphConcept<Graph> ));
Chris@16 183 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
Chris@16 184 BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<DistanceMatrixMap,Vertex> ));
Chris@16 185 typedef typename property_traits<DistanceMatrixMap>::value_type DistanceMap;
Chris@16 186 BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept<GeodesicMap,Vertex> ));
Chris@16 187 typedef typename property_traits<GeodesicMap>::value_type Result;
Chris@16 188
Chris@16 189 return all_mean_geodesics(g, dist, geo, measure_mean_geodesic<Result>(g, DistanceMap()));
Chris@16 190 }
Chris@16 191
Chris@16 192
Chris@16 193 template <typename Graph, typename GeodesicMap, typename Measure>
Chris@16 194 inline typename Measure::result_type
Chris@16 195 small_world_distance(const Graph& g, GeodesicMap geo, Measure measure)
Chris@16 196 {
Chris@16 197 BOOST_CONCEPT_ASSERT(( DistanceMeasureConcept<Measure,Graph> ));
Chris@16 198 typedef typename Measure::result_type Result;
Chris@16 199
Chris@16 200 Result sum = detail::combine_distances(g, geo, std::plus<Result>(), Result(0));
Chris@16 201 return measure(sum, g);
Chris@16 202 }
Chris@16 203
Chris@16 204 template <typename Graph, typename GeodesicMap>
Chris@16 205 inline typename property_traits<GeodesicMap>::value_type
Chris@16 206 small_world_distance(const Graph& g, GeodesicMap geo)
Chris@16 207 { return small_world_distance(g, geo, measure_graph_mean_geodesic(g, geo)); }
Chris@16 208
Chris@16 209 }
Chris@16 210
Chris@16 211 #endif