city_visitor.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //
  2. //=======================================================================
  3. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  4. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //=======================================================================
  10. //
  11. #include <boost/config.hpp>
  12. #include <iostream>
  13. #include <vector>
  14. #include <string>
  15. #include <boost/graph/adjacency_list.hpp>
  16. #include <boost/graph/depth_first_search.hpp>
  17. #include <boost/graph/breadth_first_search.hpp>
  18. #include <boost/property_map/property_map.hpp>
  19. #include <boost/graph/graph_utility.hpp> // for boost::make_list
  20. /*
  21. Example of using a visitor with the depth first search
  22. and breadth first search algorithm
  23. Sacramento ---- Reno ---- Salt Lake City
  24. |
  25. San Francisco
  26. |
  27. San Jose ---- Fresno
  28. |
  29. Los Angeles ---- Las Vegas ---- Phoenix
  30. |
  31. San Diego
  32. The visitor has three main functions:
  33. discover_vertex(u,g) is invoked when the algorithm first arrives at the
  34. vertex u. This will happen in the depth first or breadth first
  35. order depending on which algorithm you use.
  36. examine_edge(e,g) is invoked when the algorithm first checks an edge to see
  37. whether it has already been there. Whether using BFS or DFS, all
  38. the edges of vertex u are examined immediately after the call to
  39. visit(u).
  40. finish_vertex(u,g) is called when after all the vertices reachable from vertex
  41. u have already been visited.
  42. */
  43. using namespace std;
  44. using namespace boost;
  45. struct city_arrival : public base_visitor<city_arrival>
  46. {
  47. city_arrival(string* n) : names(n) { }
  48. typedef on_discover_vertex event_filter;
  49. template <class Vertex, class Graph>
  50. inline void operator()(Vertex u, Graph&) {
  51. cout << endl << "arriving at " << names[u] << endl
  52. << " neighboring cities are: ";
  53. }
  54. string* names;
  55. };
  56. struct neighbor_cities : public base_visitor<neighbor_cities>
  57. {
  58. neighbor_cities(string* n) : names(n) { }
  59. typedef on_examine_edge event_filter;
  60. template <class Edge, class Graph>
  61. inline void operator()(Edge e, Graph& g) {
  62. cout << names[ target(e, g) ] << ", ";
  63. }
  64. string* names;
  65. };
  66. struct finish_city : public base_visitor<finish_city>
  67. {
  68. finish_city(string* n) : names(n) { }
  69. typedef on_finish_vertex event_filter;
  70. template <class Vertex, class Graph>
  71. inline void operator()(Vertex u, Graph&) {
  72. cout << endl << "finished with " << names[u] << endl;
  73. }
  74. string* names;
  75. };
  76. int main(int, char*[])
  77. {
  78. enum { SanJose, SanFran, LA, SanDiego, Fresno, LasVegas, Reno,
  79. Sacramento, SaltLake, Phoenix, N };
  80. string names[] = { "San Jose", "San Francisco", "Los Angeles", "San Diego",
  81. "Fresno", "Las Vegas", "Reno", "Sacramento",
  82. "Salt Lake City", "Phoenix" };
  83. typedef std::pair<int,int> E;
  84. E edge_array[] = { E(Sacramento, Reno), E(Sacramento, SanFran),
  85. E(Reno, SaltLake),
  86. E(SanFran, SanJose),
  87. E(SanJose, Fresno), E(SanJose, LA),
  88. E(LA, LasVegas), E(LA, SanDiego),
  89. E(LasVegas, Phoenix) };
  90. /* Create the graph type we want. */
  91. typedef adjacency_list<vecS, vecS, undirectedS> Graph;
  92. #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
  93. // VC++ has trouble with the edge iterator constructor
  94. Graph G(N);
  95. for (std::size_t j = 0; j < sizeof(edge_array)/sizeof(E); ++j)
  96. add_edge(edge_array[j].first, edge_array[j].second, G);
  97. #else
  98. Graph G(edge_array, edge_array + sizeof(edge_array)/sizeof(E), N);
  99. #endif
  100. cout << "*** Depth First ***" << endl;
  101. depth_first_search
  102. (G,
  103. visitor(make_dfs_visitor(boost::make_list(city_arrival(names),
  104. neighbor_cities(names),
  105. finish_city(names)))));
  106. cout << endl;
  107. /* Get the source vertex */
  108. boost::graph_traits<Graph>::vertex_descriptor
  109. s = vertex(SanJose,G);
  110. cout << "*** Breadth First ***" << endl;
  111. breadth_first_search
  112. (G, s, visitor(make_bfs_visitor(boost::make_list(city_arrival(names),
  113. neighbor_cities(names),
  114. finish_city(names)))));
  115. return 0;
  116. }