os/ossrv/stdcpp/tsrc/Boost_test/graph/src/bfs.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 //=======================================================================
     2 // Copyright 2001 University of Notre Dame.
     3 // Author: Andrew Janiszewski, Jeremy G. Siek
     4 //
     5 // Distributed under the Boost Software License, Version 1.0. (See
     6 // accompanying file LICENSE_1_0.txt or copy at
     7 // http://www.boost.org/LICENSE_1_0.txt)
     8 //=======================================================================
     9 
    10 #include <boost/test/minimal.hpp>
    11 #include <boost/graph/adjacency_list.hpp>
    12 #include <boost/graph/random.hpp>
    13 #include <boost/graph/graph_utility.hpp>
    14 #include <boost/graph/graph_archetypes.hpp>
    15 #include <boost/graph/breadth_first_search.hpp>
    16 
    17 #include <boost/random/mersenne_twister.hpp>
    18 #ifdef __SYMBIAN32__
    19 #include "std_log_result.h"
    20 #define LOG_FILENAME_LINE __FILE__, __LINE__
    21 #endif
    22 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
    23 using namespace boost;
    24 #endif
    25 
    26 template <typename DistanceMap, typename ParentMap,
    27           typename Graph, typename ColorMap>
    28 class bfs_testing_visitor
    29 {
    30   typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
    31   typedef typename boost::graph_traits<Graph>::edge_descriptor Edge;
    32   typedef typename boost::color_traits<
    33     typename boost::property_traits<ColorMap>::value_type
    34   > Color;
    35 public:
    36 
    37   bfs_testing_visitor(Vertex s, DistanceMap d, ParentMap p, ColorMap c)
    38     : current_distance(0), distance(d), parent(p), color(c), src(s) { }
    39 
    40   void initialize_vertex(const Vertex& u, const Graph& ) const {
    41     BOOST_CHECK(get(color, u) == Color::white());
    42   }
    43   void examine_vertex(const Vertex& u, const Graph& ) const {
    44     current_vertex = u;
    45     // Ensure that the distances monotonically increase.
    46     BOOST_CHECK( distance[u] == current_distance
    47                        || distance[u] == current_distance + 1 );
    48     if (distance[u] == current_distance + 1) // new level
    49       ++current_distance;
    50   }
    51   void discover_vertex(const Vertex& u, const Graph& ) const {
    52     BOOST_CHECK( get(color, u) == Color::gray() );
    53     if (u == src) {
    54       current_vertex = src;
    55     } else {
    56       BOOST_CHECK( parent[u] == current_vertex );
    57       BOOST_CHECK( distance[u] == current_distance + 1 );
    58       BOOST_CHECK( distance[u] == distance[parent[u]] + 1 );
    59     }
    60   }
    61   void examine_edge(const Edge& e, const Graph& g) const {
    62     BOOST_CHECK( source(e, g) == current_vertex );
    63   }
    64   void tree_edge(const Edge& e, const Graph& g) const {
    65     BOOST_CHECK( get(color, target(e, g)) == Color::white() );
    66     Vertex u = source(e, g), v = target(e, g);
    67     BOOST_CHECK( distance[u] == current_distance );
    68     parent[v] = u;
    69     distance[v] = distance[u] + 1;
    70   }
    71   void non_tree_edge(const Edge& e, const Graph& g) const {
    72     BOOST_CHECK( color[target(e, g)] != Color::white() );
    73 
    74     if (boost::is_directed(g))
    75       // cross or back edge
    76       BOOST_CHECK(distance[target(e, g)] <= distance[source(e, g)] + 1);
    77     else {
    78       // cross edge (or going backwards on a tree edge)
    79       BOOST_CHECK(distance[target(e, g)] == distance[source(e, g)]
    80                         || distance[target(e, g)] == distance[source(e, g)] + 1
    81                         || distance[target(e, g)] == distance[source(e, g)] - 1
    82                         );
    83     }
    84   }
    85 
    86   void gray_target(const Edge& e, const Graph& g) const {
    87     BOOST_CHECK( color[target(e, g)] == Color::gray() );
    88   }
    89 
    90   void black_target(const Edge& e, const Graph& g) const {
    91     BOOST_CHECK( color[target(e, g)] == Color::black() );
    92 
    93     // All vertices adjacent to a black vertex must already be discovered
    94     typename boost::graph_traits<Graph>::adjacency_iterator ai, ai_end;
    95     for (boost::tie(ai, ai_end) = adjacent_vertices(target(e, g), g);
    96          ai != ai_end; ++ai)
    97       BOOST_CHECK( color[*ai] != Color::white() );
    98   }
    99   void finish_vertex(const Vertex& u, const Graph& ) const {
   100     BOOST_CHECK( color[u] == Color::black() );
   101 
   102   }
   103 private:
   104   mutable Vertex current_vertex;
   105   mutable typename boost::property_traits<DistanceMap>::value_type
   106     current_distance;
   107   DistanceMap distance;
   108   ParentMap parent;
   109   ColorMap color;
   110   Vertex src;
   111 };
   112 
   113 
   114 template <class Graph>
   115 struct bfs_test
   116 {
   117   typedef boost::graph_traits<Graph> Traits;
   118   typedef typename Traits::vertices_size_type
   119     vertices_size_type;
   120   static void go(vertices_size_type max_V) {
   121     typedef typename Traits::vertex_descriptor vertex_descriptor;
   122     typedef boost::color_traits<boost::default_color_type> Color;
   123 
   124     vertices_size_type i;
   125     typename Traits::edges_size_type j;
   126     typename Traits::vertex_iterator ui, ui_end;
   127 
   128     boost::mt19937 gen;
   129 
   130     for (i = 0; i < max_V; ++i)
   131       for (j = 0; j < i*i; ++j) {
   132         Graph g;
   133         boost::generate_random_graph(g, i, j, gen);
   134 
   135         // declare the "start" variable
   136         vertex_descriptor start = boost::random_vertex(g, gen);
   137 
   138         // vertex properties
   139         std::vector<int> distance(i, (std::numeric_limits<int>::max)());
   140         distance[start] = 0;
   141         std::vector<vertex_descriptor> parent(i);
   142         for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
   143           parent[*ui] = *ui;
   144         std::vector<boost::default_color_type> color(i);
   145 
   146         // Create the testing visitor.
   147         bfs_testing_visitor<int*,vertex_descriptor*,Graph,
   148           boost::default_color_type*>
   149           vis(start, &distance[0], &parent[0], &color[0]);
   150 
   151         boost::breadth_first_search(g, start,
   152                                     visitor(vis).
   153                                     color_map(&color[0]));
   154 
   155         // All white vertices should be unreachable from the source.
   156         for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
   157           if (color[*ui] == Color::white()) {
   158             std::vector<boost::default_color_type> color2(i, Color::white());
   159             BOOST_CHECK(!boost::is_reachable(start, *ui, g, &color2[0]));
   160           }
   161 
   162         // The shortest path to a child should be one longer than
   163         // shortest path to the parent.
   164         for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
   165           if (parent[*ui] != *ui) // *ui not the root of the bfs tree
   166             BOOST_CHECK(distance[*ui] == distance[parent[*ui]] + 1);
   167       }
   168   }
   169 };
   170 
   171 
   172 int test_main(int argc, char* argv[])
   173 {
   174   using namespace boost;
   175   int max_V = 7;
   176   if (argc > 1)
   177     max_V = atoi(argv[1]);
   178 
   179   bfs_test< adjacency_list<vecS, vecS, directedS> >::go(max_V);
   180   bfs_test< adjacency_list<vecS, vecS, undirectedS> >::go(max_V);
   181   
   182   #ifdef __SYMBIAN32__
   183 	std_log(LOG_FILENAME_LINE,"[End Test Case ]");
   184 
   185 	testResultXml("bfs");
   186 	close_log_file();
   187 #endif
   188   return 0;
   189 }