First public contribution.
1 // Boost.Graph library isomorphism test
3 // Copyright (C) 2001-20044 Douglas Gregor (dgregor at cs dot indiana dot edu)
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)
9 // For more information, see http://www.boost.org
13 // 29 Nov 2001 Jeremy Siek
14 // Changed to use Boost.Random.
15 // 29 Nov 2001 Doug Gregor
18 * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved.
26 #include <time.h> // clock used without std:: qualifier?
27 #include <boost/test/minimal.hpp>
28 #include <boost/graph/adjacency_list.hpp>
29 #include <boost/graph/isomorphism.hpp>
30 #include <boost/property_map.hpp>
31 #include <boost/random/variate_generator.hpp>
32 #include <boost/random/uniform_real.hpp>
33 #include <boost/random/uniform_int.hpp>
34 #include <boost/random/mersenne_twister.hpp>
35 #include <boost/lexical_cast.hpp>
37 #include "std_log_result.h"
38 #define LOG_FILENAME_LINE __FILE__, __LINE__
40 using namespace boost;
42 template <typename Generator>
43 struct random_functor {
44 random_functor(Generator& g) : g(g) { }
45 std::size_t operator()(std::size_t n) {
46 boost::uniform_int<std::size_t> distrib(0, n-1);
47 boost::variate_generator<boost::mt19937&, boost::uniform_int<std::size_t> >
54 template<typename Graph1, typename Graph2>
55 void randomly_permute_graph(const Graph1& g1, Graph2& g2)
57 // Need a clean graph to start with
58 BOOST_REQUIRE(num_vertices(g2) == 0);
59 BOOST_REQUIRE(num_edges(g2) == 0);
61 typedef typename graph_traits<Graph1>::vertex_descriptor vertex1;
62 typedef typename graph_traits<Graph2>::vertex_descriptor vertex2;
63 typedef typename graph_traits<Graph1>::edge_iterator edge_iterator;
66 random_functor<boost::mt19937> rand_fun(gen);
69 std::vector<vertex1> orig_vertices;
70 std::copy(vertices(g1).first, vertices(g1).second, std::back_inserter(orig_vertices));
71 std::random_shuffle(orig_vertices.begin(), orig_vertices.end(), rand_fun);
72 std::map<vertex1, vertex2> vertex_map;
74 for (std::size_t i = 0; i < num_vertices(g1); ++i) {
75 vertex_map[orig_vertices[i]] = add_vertex(g2);
78 for (edge_iterator e = edges(g1).first; e != edges(g1).second; ++e) {
79 add_edge(vertex_map[source(*e, g1)], vertex_map[target(*e, g1)], g2);
83 template<typename Graph>
84 void generate_random_digraph(Graph& g, double edge_probability)
86 typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
87 boost::mt19937 random_gen;
88 boost::uniform_real<double> distrib(0.0, 1.0);
89 boost::variate_generator<boost::mt19937&, boost::uniform_real<double> >
90 random_dist(random_gen, distrib);
92 for (vertex_iterator u = vertices(g).first; u != vertices(g).second; ++u) {
93 vertex_iterator v = u;
95 for (; v != vertices(g).second; ++v) {
96 if (random_dist() <= edge_probability)
102 void test_isomorphism(int n, double edge_probability)
104 typedef adjacency_list<vecS, vecS, bidirectionalS> graph1;
105 typedef adjacency_list<listS, listS, bidirectionalS,
106 property<vertex_index_t, int> > graph2;
109 generate_random_digraph(g1, edge_probability);
111 randomly_permute_graph(g1, g2);
114 for (graph2::vertex_iterator v = vertices(g2).first;
115 v != vertices(g2).second; ++v) {
116 put(vertex_index_t(), g2, *v, v_idx++);
119 std::map<graph1::vertex_descriptor, graph2::vertex_descriptor> mapping;
121 bool isomorphism_correct = true;
122 clock_t start = clock();
124 isomorphism_correct = isomorphism(g1, g2, isomorphism_map(make_assoc_property_map(mapping)));
126 BOOST_CHECK(isomorphism_correct);
128 clock_t end = clock();
130 std::cout << "Elapsed time (clock cycles): " << (end - start) << std::endl;
132 bool verify_correct = true;
134 verify_correct = verify_isomorphism(g1, g2, make_assoc_property_map(mapping));
136 BOOST_CHECK(verify_correct);
138 if (!isomorphism_correct || !verify_correct) {
141 std::ofstream out("isomorphism_failure.bg1");
142 out << num_vertices(g1) << std::endl;
143 for (graph1::edge_iterator e = edges(g1).first;
144 e != edges(g1).second; ++e) {
145 out << get(vertex_index_t(), g1, source(*e, g1)) << ' '
146 << get(vertex_index_t(), g1, target(*e, g1)) << std::endl;
152 std::ofstream out("isomorphism_failure.bg2");
153 out << num_vertices(g2) << std::endl;
154 for (graph2::edge_iterator e = edges(g2).first;
155 e != edges(g2).second; ++e) {
156 out << get(vertex_index_t(), g2, source(*e, g2)) << ' '
157 << get(vertex_index_t(), g2, target(*e, g2)) << std::endl;
163 int test_main(int argc, char* argv[])
166 test_isomorphism(30, 0.45);
168 std_log(LOG_FILENAME_LINE,"[End Test Case ]");
170 testResultXml("isomorphism");
176 int n = boost::lexical_cast<int>(argv[1]);
177 double edge_prob = boost::lexical_cast<double>(argv[2]);
178 test_isomorphism(n, edge_prob);
181 std_log(LOG_FILENAME_LINE,"[End Test Case ]");
183 testResultXml("isomorphism");