inclusive_mean_geodesic.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // (C) Copyright Andrew Sutton 2007
  2. //
  3. // Use, modification and distribution are subject to the
  4. // Boost Software License, Version 1.0 (See accompanying file
  5. // LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  6. //[inclusive_mean_geodesic_example
  7. #include <iostream>
  8. #include <iomanip>
  9. #include <boost/graph/directed_graph.hpp>
  10. #include <boost/graph/exterior_property.hpp>
  11. #include <boost/graph/floyd_warshall_shortest.hpp>
  12. #include <boost/graph/geodesic_distance.hpp>
  13. #include "helper.hpp"
  14. using namespace std;
  15. using namespace boost;
  16. // This template structure defines the function that we will apply
  17. // to compute both the per-vertex mean geodesic distances and the
  18. // graph's mean geodesic distance.
  19. template <typename Graph,
  20. typename DistanceType,
  21. typename ResultType,
  22. typename Divides = divides<ResultType> >
  23. struct inclusive_average
  24. {
  25. typedef DistanceType distance_type;
  26. typedef ResultType result_type;
  27. result_type operator ()(distance_type d, const Graph& g)
  28. {
  29. if(d == numeric_values<distance_type>::infinity()) {
  30. return numeric_values<result_type>::infinity();
  31. }
  32. else {
  33. return div(result_type(d), result_type(num_vertices(g)));
  34. }
  35. }
  36. Divides div;
  37. };
  38. // The Page type stores the name of each vertex in the graph and
  39. // represents web pages that can be navigated to.
  40. struct WebPage
  41. {
  42. string name;
  43. };
  44. // The Link type stores an associated probability of traveling
  45. // from one page to another.
  46. struct Link
  47. {
  48. float probability;
  49. };
  50. // Declare the graph type and its vertex and edge types.
  51. typedef directed_graph<WebPage, Link> Graph;
  52. typedef graph_traits<Graph>::vertex_descriptor Vertex;
  53. typedef graph_traits<Graph>::edge_descriptor Edge;
  54. // The name map provides an abstract accessor for the names of
  55. // each vertex. This is used during graph creation.
  56. typedef property_map<Graph, string WebPage::*>::type NameMap;
  57. // Declare a matrix type and its corresponding property map that
  58. // will contain the distances between each pair of vertices.
  59. typedef exterior_vertex_property<Graph, float> DistanceProperty;
  60. typedef DistanceProperty::matrix_type DistanceMatrix;
  61. typedef DistanceProperty::matrix_map_type DistanceMatrixMap;
  62. // Declare the weight map as an accessor into the bundled
  63. // edge property.
  64. typedef property_map<Graph, float Link::*>::type WeightMap;
  65. // Declare a container and its corresponding property map that
  66. // will contain the resulting mean geodesic distances of each
  67. // vertex in the graph.
  68. typedef exterior_vertex_property<Graph, float> GeodesicProperty;
  69. typedef GeodesicProperty::container_type GeodesicContainer;
  70. typedef GeodesicProperty::map_type GeodesicMap;
  71. static float exclusive_geodesics(const Graph&, DistanceMatrixMap, GeodesicMap);
  72. static float inclusive_geodesics(const Graph&, DistanceMatrixMap, GeodesicMap);
  73. int
  74. main(int argc, char *argv[])
  75. {
  76. // Create the graph, a name map that providse abstract access
  77. // to the web page names, and the weight map as an accessor to
  78. // the edge weights (or probabilities).
  79. Graph g;
  80. NameMap nm(get(&WebPage::name, g));
  81. WeightMap wm(get(&Link::probability, g));
  82. // Read the weighted graph from standard input.
  83. read_weighted_graph(g, nm, wm, cin);
  84. // Compute the distances between all pairs of vertices using
  85. // the Floyd-Warshall algorithm. The weight map was created
  86. // above so it could be populated when the graph was read in.
  87. DistanceMatrix distances(num_vertices(g));
  88. DistanceMatrixMap dm(distances, g);
  89. floyd_warshall_all_pairs_shortest_paths(g, dm, weight_map(wm));
  90. // Create the containers and the respective property maps that
  91. // will contain the mean geodesics averaged both including
  92. // self-loop distances and excluding them.
  93. GeodesicContainer exclude(num_vertices(g));
  94. GeodesicContainer include(num_vertices(g));
  95. GeodesicMap exmap(exclude, g);
  96. GeodesicMap inmap(include, g);
  97. float ex = exclusive_geodesics(g, dm, exmap);
  98. float in = inclusive_geodesics(g, dm, inmap);
  99. // Print the mean geodesic distance of each vertex and finally,
  100. // the graph itself.
  101. cout << setw(12) << setiosflags(ios::left) << "vertex";
  102. cout << setw(12) << setiosflags(ios::left) << "excluding";
  103. cout << setw(12) << setiosflags(ios::left) << "including" << endl;
  104. graph_traits<Graph>::vertex_iterator i, end;
  105. for(boost::tie(i, end) = vertices(g); i != end; ++i) {
  106. cout << setw(12) << setiosflags(ios::left)
  107. << g[*i].name
  108. << setw(12) << get(exmap, *i)
  109. << setw(12) << get(inmap, *i) << endl;
  110. }
  111. cout << "small world (excluding self-loops): " << ex << endl;
  112. cout << "small world (including self-loops): " << in << endl;
  113. return 0;
  114. }
  115. float
  116. exclusive_geodesics(const Graph& g, DistanceMatrixMap dm, GeodesicMap gm)
  117. {
  118. // Compute the mean geodesic distances, which excludes distances
  119. // of self-loops by default. Return the measure for the entire graph.
  120. return all_mean_geodesics(g, dm, gm);
  121. }
  122. float
  123. inclusive_geodesics(const Graph &g, DistanceMatrixMap dm, GeodesicMap gm)
  124. {
  125. // Create a new measure object for computing the mean geodesic
  126. // distance of all vertices. This measure will actually be used
  127. // for both averages.
  128. inclusive_average<Graph, float, float> m;
  129. // Compute the mean geodesic distance using the inclusive average
  130. // to account for self-loop distances. Return the measure for the
  131. // entire graph.
  132. return all_mean_geodesics(g, dm, gm, m);
  133. }
  134. //]