801a11bf4a
r56013, r56014, r56015, r56016, r56017, r56089, r56097, r56116, r56117, r56126, r56127, r56128, r56140, r56147, r56300, r56301, r56339, r56360, r56454, r56473, r56563, r56651, r56654, r56658, r56682, r56732, r56796, r56855, r56856, r56868, r55667, r56860, r55473, r55507, r55528, r55749, r56147, r55723, r56109, r56859, and r55780. [SVN r56881]
163 lines
5.0 KiB
C++
163 lines
5.0 KiB
C++
//=======================================================================
|
|
// 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;
|
|
|
|
}
|