summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/graph/test/incremental_components_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/graph/test/incremental_components_test.cpp')
-rw-r--r--src/boost/libs/graph/test/incremental_components_test.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/boost/libs/graph/test/incremental_components_test.cpp b/src/boost/libs/graph/test/incremental_components_test.cpp
new file mode 100644
index 00000000..d64faadf
--- /dev/null
+++ b/src/boost/libs/graph/test/incremental_components_test.cpp
@@ -0,0 +1,162 @@
+//=======================================================================
+// Copyright 2009 Trustees of Indiana University.
+// Authors: Michael Hansen, Andrew Lumsdaine
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//=======================================================================
+
+#include <iostream>
+#include <map>
+#include <set>
+
+#include <boost/foreach.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/incremental_components.hpp>
+#include <boost/graph/random.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/random.hpp>
+#include <boost/test/minimal.hpp>
+
+using namespace boost;
+
+typedef adjacency_list<vecS, vecS, undirectedS> VectorGraph;
+
+typedef adjacency_list<listS, listS, undirectedS,
+ property<vertex_index_t, unsigned int> > ListGraph;
+
+template <typename Graph>
+void test_graph(const Graph& graph) {
+ typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
+ typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
+ typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
+
+ typedef typename property_map<Graph, vertex_index_t>::type IndexPropertyMap;
+
+ typedef std::map<vertex_descriptor, vertices_size_type> RankMap;
+ typedef associative_property_map<RankMap> RankPropertyMap;
+
+ typedef std::vector<vertex_descriptor> ParentMap;
+ typedef iterator_property_map<typename ParentMap::iterator,
+ IndexPropertyMap, vertex_descriptor, vertex_descriptor&> IndexParentMap;
+
+ RankMap rank_map;
+ RankPropertyMap rank_property_map(rank_map);
+
+ ParentMap parent_map(num_vertices(graph));
+ IndexParentMap index_parent_map(parent_map.begin());
+
+ // Create disjoint sets of vertices from the graph
+ disjoint_sets<RankPropertyMap, IndexParentMap>
+ vertex_sets(rank_property_map, index_parent_map);
+
+ initialize_incremental_components(graph, vertex_sets);
+ incremental_components(graph, vertex_sets);
+
+ // Build component index from the graph's vertices, its index map,
+ // and the disjoint sets.
+ typedef component_index<vertices_size_type> Components;
+ Components vertex_components(parent_map.begin(),
+ parent_map.end(),
+ get(boost::vertex_index, graph));
+
+ // Create a reverse-lookup map for vertex indices
+ std::vector<vertex_descriptor> reverse_index_map(num_vertices(graph));
+
+ BOOST_FOREACH(vertex_descriptor vertex, vertices(graph)) {
+ reverse_index_map[get(get(boost::vertex_index, graph), vertex)] = vertex;
+ }
+
+ // Verify that components are really connected
+ BOOST_FOREACH(vertices_size_type component_index,
+ vertex_components) {
+
+ std::set<vertex_descriptor> component_vertices;
+
+ BOOST_FOREACH(vertices_size_type child_index,
+ vertex_components[component_index]) {
+
+ vertex_descriptor child_vertex = reverse_index_map[child_index];
+ component_vertices.insert(child_vertex);
+
+ } // foreach child_index
+
+ // Verify that children are connected to each other in some
+ // manner, but not to vertices outside their component.
+ BOOST_FOREACH(vertex_descriptor child_vertex,
+ component_vertices) {
+
+ // Skip orphan vertices
+ if (out_degree(child_vertex, graph) == 0) {
+ continue;
+ }
+
+ // Make sure at least one edge exists between [child_vertex] and
+ // another vertex in the component.
+ bool edge_exists = false;
+
+ BOOST_FOREACH(edge_descriptor child_edge,
+ out_edges(child_vertex, graph)) {
+
+ if (component_vertices.count(target(child_edge, graph)) > 0) {
+ edge_exists = true;
+ break;
+ }
+
+ } // foreach child_edge
+
+ BOOST_REQUIRE(edge_exists);
+
+ } // foreach child_vertex
+
+ } // foreach component_index
+
+} // test_graph
+
+int test_main(int argc, char* argv[])
+{
+ std::size_t vertices_to_generate = 100,
+ edges_to_generate = 50,
+ random_seed = time(0);
+
+ // Parse command-line arguments
+
+ if (argc > 1) {
+ vertices_to_generate = lexical_cast<std::size_t>(argv[1]);
+ }
+
+ if (argc > 2) {
+ edges_to_generate = lexical_cast<std::size_t>(argv[2]);
+ }
+
+ if (argc > 3) {
+ random_seed = lexical_cast<std::size_t>(argv[3]);
+ }
+
+ minstd_rand generator(random_seed);
+
+ // Generate random vector and list graphs
+ VectorGraph vector_graph;
+ generate_random_graph(vector_graph, vertices_to_generate,
+ edges_to_generate, generator, false);
+
+ test_graph(vector_graph);
+
+ ListGraph list_graph;
+ generate_random_graph(list_graph, vertices_to_generate,
+ edges_to_generate, generator, false);
+
+ // Assign indices to list_graph's vertices
+ graph_traits<ListGraph>::vertices_size_type index = 0;
+ BOOST_FOREACH(graph_traits<ListGraph>::vertex_descriptor vertex,
+ vertices(list_graph)) {
+ put(get(boost::vertex_index, list_graph), vertex, index++);
+ }
+
+ test_graph(list_graph);
+
+ return 0;
+
+}