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