annotate DEPENDENCIES/generic/include/boost/graph/clustering_coefficient.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // (C) Copyright 2007-2009 Andrew Sutton
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_CLUSTERING_COEFFICIENT_HPP
Chris@16 8 #define BOOST_GRAPH_CLUSTERING_COEFFICIENT_HPP
Chris@16 9
Chris@16 10 #include <boost/next_prior.hpp>
Chris@16 11 #include <boost/graph/graph_traits.hpp>
Chris@16 12 #include <boost/graph/graph_concepts.hpp>
Chris@16 13 #include <boost/graph/lookup_edge.hpp>
Chris@16 14 #include <boost/concept/assert.hpp>
Chris@16 15
Chris@16 16 namespace boost
Chris@16 17 {
Chris@16 18 namespace detail
Chris@16 19 {
Chris@16 20 template <class Graph>
Chris@16 21 inline typename graph_traits<Graph>::degree_size_type
Chris@16 22 possible_edges(const Graph& g, std::size_t k, directed_tag)
Chris@16 23 {
Chris@16 24 BOOST_CONCEPT_ASSERT(( GraphConcept<Graph> ));
Chris@16 25 typedef typename graph_traits<Graph>::degree_size_type T;
Chris@16 26 return T(k) * (T(k) - 1);
Chris@16 27 }
Chris@16 28
Chris@16 29 template <class Graph>
Chris@16 30 inline typename graph_traits<Graph>::degree_size_type
Chris@16 31 possible_edges(const Graph& g, size_t k, undirected_tag)
Chris@16 32 {
Chris@16 33 // dirty little trick...
Chris@16 34 return possible_edges(g, k, directed_tag()) / 2;
Chris@16 35 }
Chris@16 36
Chris@16 37 // This template matches directedS and bidirectionalS.
Chris@16 38 template <class Graph>
Chris@16 39 inline typename graph_traits<Graph>::degree_size_type
Chris@16 40 count_edges(const Graph& g,
Chris@16 41 typename graph_traits<Graph>::vertex_descriptor u,
Chris@16 42 typename graph_traits<Graph>::vertex_descriptor v,
Chris@16 43 directed_tag)
Chris@16 44
Chris@16 45 {
Chris@16 46 BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept<Graph> ));
Chris@16 47 return (lookup_edge(u, v, g).second ? 1 : 0) +
Chris@16 48 (lookup_edge(v, u, g).second ? 1 : 0);
Chris@16 49 }
Chris@16 50
Chris@16 51 // This template matches undirectedS
Chris@16 52 template <class Graph>
Chris@16 53 inline typename graph_traits<Graph>::degree_size_type
Chris@16 54 count_edges(const Graph& g,
Chris@16 55 typename graph_traits<Graph>::vertex_descriptor u,
Chris@16 56 typename graph_traits<Graph>::vertex_descriptor v,
Chris@16 57 undirected_tag)
Chris@16 58 {
Chris@16 59 BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept<Graph> ));
Chris@16 60 return lookup_edge(u, v, g).second ? 1 : 0;
Chris@16 61 }
Chris@16 62 }
Chris@16 63
Chris@16 64 template <typename Graph, typename Vertex>
Chris@16 65 inline typename graph_traits<Graph>::degree_size_type
Chris@16 66 num_paths_through_vertex(const Graph& g, Vertex v)
Chris@16 67 {
Chris@16 68 BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept<Graph> ));
Chris@16 69 typedef typename graph_traits<Graph>::directed_category Directed;
Chris@16 70 typedef typename graph_traits<Graph>::adjacency_iterator AdjacencyIterator;
Chris@16 71
Chris@16 72 // TODO: There should actually be a set of neighborhood functions
Chris@16 73 // for things like this (num_neighbors() would be great).
Chris@16 74
Chris@16 75 AdjacencyIterator i, end;
Chris@16 76 boost::tie(i, end) = adjacent_vertices(v, g);
Chris@16 77 std::size_t k = std::distance(i, end);
Chris@16 78 return detail::possible_edges(g, k, Directed());
Chris@16 79 }
Chris@16 80
Chris@16 81 template <typename Graph, typename Vertex>
Chris@16 82 inline typename graph_traits<Graph>::degree_size_type
Chris@16 83 num_triangles_on_vertex(const Graph& g, Vertex v)
Chris@16 84 {
Chris@16 85 BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept<Graph> ));
Chris@16 86 BOOST_CONCEPT_ASSERT(( AdjacencyGraphConcept<Graph> ));
Chris@16 87 typedef typename graph_traits<Graph>::degree_size_type Degree;
Chris@16 88 typedef typename graph_traits<Graph>::directed_category Directed;
Chris@16 89 typedef typename graph_traits<Graph>::adjacency_iterator AdjacencyIterator;
Chris@16 90
Chris@16 91 // TODO: I might be able to reduce the requirement from adjacency graph
Chris@16 92 // to incidence graph by using out edges.
Chris@16 93
Chris@16 94 Degree count(0);
Chris@16 95 AdjacencyIterator i, j, end;
Chris@16 96 for(boost::tie(i, end) = adjacent_vertices(v, g); i != end; ++i) {
Chris@16 97 for(j = boost::next(i); j != end; ++j) {
Chris@16 98 count += detail::count_edges(g, *i, *j, Directed());
Chris@16 99 }
Chris@16 100 }
Chris@16 101 return count;
Chris@16 102 } /* namespace detail */
Chris@16 103
Chris@16 104 template <typename T, typename Graph, typename Vertex>
Chris@16 105 inline T
Chris@16 106 clustering_coefficient(const Graph& g, Vertex v)
Chris@16 107 {
Chris@16 108 T zero(0);
Chris@16 109 T routes = T(num_paths_through_vertex(g, v));
Chris@16 110 return (routes > zero) ?
Chris@16 111 T(num_triangles_on_vertex(g, v)) / routes : zero;
Chris@16 112 }
Chris@16 113
Chris@16 114 template <typename Graph, typename Vertex>
Chris@16 115 inline double
Chris@16 116 clustering_coefficient(const Graph& g, Vertex v)
Chris@16 117 { return clustering_coefficient<double>(g, v); }
Chris@16 118
Chris@16 119 template <typename Graph, typename ClusteringMap>
Chris@16 120 inline typename property_traits<ClusteringMap>::value_type
Chris@16 121 all_clustering_coefficients(const Graph& g, ClusteringMap cm)
Chris@16 122 {
Chris@16 123 BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<Graph> ));
Chris@16 124 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
Chris@16 125 typedef typename graph_traits<Graph>::vertex_iterator VertexIterator;
Chris@16 126 BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept<ClusteringMap,Vertex> ));
Chris@16 127 typedef typename property_traits<ClusteringMap>::value_type Coefficient;
Chris@16 128
Chris@16 129 Coefficient sum(0);
Chris@16 130 VertexIterator i, end;
Chris@16 131 for(boost::tie(i, end) = vertices(g); i != end; ++i) {
Chris@16 132 Coefficient cc = clustering_coefficient<Coefficient>(g, *i);
Chris@16 133 put(cm, *i, cc);
Chris@16 134 sum += cc;
Chris@16 135 }
Chris@16 136 return sum / Coefficient(num_vertices(g));
Chris@16 137 }
Chris@16 138
Chris@16 139 template <typename Graph, typename ClusteringMap>
Chris@16 140 inline typename property_traits<ClusteringMap>::value_type
Chris@16 141 mean_clustering_coefficient(const Graph& g, ClusteringMap cm)
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<ClusteringMap,Vertex> ));
Chris@16 147 typedef typename property_traits<ClusteringMap>::value_type Coefficient;
Chris@16 148
Chris@16 149 Coefficient cc(0);
Chris@16 150 VertexIterator i, end;
Chris@16 151 for(boost::tie(i, end) = vertices(g); i != end; ++i) {
Chris@16 152 cc += get(cm, *i);
Chris@16 153 }
Chris@16 154 return cc / Coefficient(num_vertices(g));
Chris@16 155 }
Chris@16 156
Chris@16 157 } /* namespace boost */
Chris@16 158
Chris@16 159 #endif