Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/graph/test/isomorphism.cpp @ 47

Last change on this file since 47 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 4.9 KB
Line 
1// Boost.Graph library isomorphism test
2
3// Copyright (C) 2001-20044 Douglas Gregor (dgregor at cs dot indiana dot edu)
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// For more information, see http://www.boost.org
10//
11// Revision History:
12//
13// 29 Nov 2001    Jeremy Siek
14//      Changed to use Boost.Random.
15// 29 Nov 2001    Doug Gregor
16//      Initial checkin.
17
18#include <iostream>
19#include <fstream>
20#include <map>
21#include <algorithm>
22#include <cstdlib>
23#include <time.h> // clock used without std:: qualifier?
24#include <boost/test/minimal.hpp>
25#include <boost/graph/adjacency_list.hpp>
26#include <boost/graph/isomorphism.hpp>
27#include <boost/property_map.hpp>
28#include <boost/random/variate_generator.hpp>
29#include <boost/random/uniform_real.hpp>
30#include <boost/random/uniform_int.hpp>
31#include <boost/random/mersenne_twister.hpp>
32#include <boost/lexical_cast.hpp>
33
34using namespace boost;
35
36template <typename Generator>
37struct random_functor {
38  random_functor(Generator& g) : g(g) { }
39  std::size_t operator()(std::size_t n) {
40    boost::uniform_int<std::size_t> distrib(0, n-1);
41    boost::variate_generator<boost::mt19937&, boost::uniform_int<std::size_t> >
42      x(g, distrib);
43    return x();
44  }
45  Generator& g;
46};
47
48template<typename Graph1, typename Graph2>
49void randomly_permute_graph(const Graph1& g1, Graph2& g2)
50{
51  // Need a clean graph to start with
52  BOOST_REQUIRE(num_vertices(g2) == 0);
53  BOOST_REQUIRE(num_edges(g2) == 0);
54
55  typedef typename graph_traits<Graph1>::vertex_descriptor vertex1;
56  typedef typename graph_traits<Graph2>::vertex_descriptor vertex2;
57  typedef typename graph_traits<Graph1>::edge_iterator edge_iterator;
58
59  boost::mt19937 gen;
60  random_functor<boost::mt19937> rand_fun(gen);
61
62  // Decide new order
63  std::vector<vertex1> orig_vertices;
64  std::copy(vertices(g1).first, vertices(g1).second, std::back_inserter(orig_vertices));
65  std::random_shuffle(orig_vertices.begin(), orig_vertices.end(), rand_fun);
66  std::map<vertex1, vertex2> vertex_map;
67
68  for (std::size_t i = 0; i < num_vertices(g1); ++i) {
69    vertex_map[orig_vertices[i]] = add_vertex(g2);
70  }
71
72  for (edge_iterator e = edges(g1).first; e != edges(g1).second; ++e) {
73    add_edge(vertex_map[source(*e, g1)], vertex_map[target(*e, g1)], g2);
74  }
75}
76
77template<typename Graph>
78void generate_random_digraph(Graph& g, double edge_probability)
79{
80  typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
81  boost::mt19937 random_gen;
82  boost::uniform_real<double> distrib(0.0, 1.0);
83  boost::variate_generator<boost::mt19937&, boost::uniform_real<double> >
84    random_dist(random_gen, distrib);
85
86  for (vertex_iterator u = vertices(g).first; u != vertices(g).second; ++u) {
87    vertex_iterator v = u;
88    ++v;
89    for (; v != vertices(g).second; ++v) {
90      if (random_dist() <= edge_probability)
91        add_edge(*u, *v, g);
92    }
93  }
94}
95
96void test_isomorphism(int n, double edge_probability)
97{
98  typedef adjacency_list<vecS, vecS, bidirectionalS> graph1;
99  typedef adjacency_list<listS, listS, bidirectionalS,
100                         property<vertex_index_t, int> > graph2;
101
102  graph1 g1(n);
103  generate_random_digraph(g1, edge_probability);
104  graph2 g2;
105  randomly_permute_graph(g1, g2);
106
107  int v_idx = 0;
108  for (graph2::vertex_iterator v = vertices(g2).first;
109       v != vertices(g2).second; ++v) {
110    put(vertex_index_t(), g2, *v, v_idx++);
111  }
112
113  std::map<graph1::vertex_descriptor, graph2::vertex_descriptor> mapping;
114
115  bool isomorphism_correct;
116  clock_t start = clock();
117  BOOST_CHECK(isomorphism_correct = isomorphism
118               (g1, g2, isomorphism_map(make_assoc_property_map(mapping))));
119  clock_t end = clock();
120
121  std::cout << "Elapsed time (clock cycles): " << (end - start) << std::endl;
122
123  bool verify_correct;
124  BOOST_CHECK(verify_correct =
125             verify_isomorphism(g1, g2, make_assoc_property_map(mapping)));
126
127  if (!isomorphism_correct || !verify_correct) {
128    // Output graph 1
129    {
130      std::ofstream out("isomorphism_failure.bg1");
131      out << num_vertices(g1) << std::endl;
132      for (graph1::edge_iterator e = edges(g1).first;
133           e != edges(g1).second; ++e) {
134        out << get(vertex_index_t(), g1, source(*e, g1)) << ' '
135            << get(vertex_index_t(), g1, target(*e, g1)) << std::endl;
136      }
137    }
138
139    // Output graph 2
140    {
141      std::ofstream out("isomorphism_failure.bg2");
142      out << num_vertices(g2) << std::endl;
143      for (graph2::edge_iterator e = edges(g2).first;
144           e != edges(g2).second; ++e) {
145        out << get(vertex_index_t(), g2, source(*e, g2)) << ' '
146            << get(vertex_index_t(), g2, target(*e, g2)) << std::endl;
147      }
148    }
149  }
150}
151
152int test_main(int argc, char* argv[])
153{
154  if (argc < 3) {
155    test_isomorphism(30, 0.45);
156    return 0;
157  }
158
159  int n = boost::lexical_cast<int>(argv[1]);
160  double edge_prob = boost::lexical_cast<double>(argv[2]);
161  test_isomorphism(n, edge_prob);
162
163  return 0;
164}
Note: See TracBrowser for help on using the repository browser.