os/ossrv/stdcpp/tsrc/Boost_test/graph/src/isomorphism.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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  * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
    19 */
    20 
    21 #include <iostream>
    22 #include <fstream>
    23 #include <map>
    24 #include <algorithm>
    25 #include <cstdlib>
    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>
    36 #ifdef __SYMBIAN32__
    37 #include "std_log_result.h"
    38 #define LOG_FILENAME_LINE __FILE__, __LINE__
    39 #endif
    40 using namespace boost;
    41 
    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> >
    48       x(g, distrib);
    49     return x();
    50   }
    51   Generator& g;
    52 };
    53 
    54 template<typename Graph1, typename Graph2>
    55 void randomly_permute_graph(const Graph1& g1, Graph2& g2)
    56 {
    57   // Need a clean graph to start with
    58   BOOST_REQUIRE(num_vertices(g2) == 0);
    59   BOOST_REQUIRE(num_edges(g2) == 0);
    60 
    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;
    64 
    65   boost::mt19937 gen;
    66   random_functor<boost::mt19937> rand_fun(gen);
    67 
    68   // Decide new order
    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;
    73 
    74   for (std::size_t i = 0; i < num_vertices(g1); ++i) {
    75     vertex_map[orig_vertices[i]] = add_vertex(g2);
    76   }
    77 
    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);
    80   }
    81 }
    82 
    83 template<typename Graph>
    84 void generate_random_digraph(Graph& g, double edge_probability)
    85 {
    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);
    91 
    92   for (vertex_iterator u = vertices(g).first; u != vertices(g).second; ++u) {
    93     vertex_iterator v = u;
    94     ++v;
    95     for (; v != vertices(g).second; ++v) {
    96       if (random_dist() <= edge_probability)
    97         add_edge(*u, *v, g);
    98     }
    99   }
   100 }
   101 
   102 void test_isomorphism(int n, double edge_probability)
   103 {
   104   typedef adjacency_list<vecS, vecS, bidirectionalS> graph1;
   105   typedef adjacency_list<listS, listS, bidirectionalS,
   106                          property<vertex_index_t, int> > graph2;
   107 
   108   graph1 g1(n);
   109   generate_random_digraph(g1, edge_probability);
   110   graph2 g2;
   111   randomly_permute_graph(g1, g2);
   112 
   113   int v_idx = 0;
   114   for (graph2::vertex_iterator v = vertices(g2).first;
   115        v != vertices(g2).second; ++v) {
   116     put(vertex_index_t(), g2, *v, v_idx++);
   117   }
   118 
   119   std::map<graph1::vertex_descriptor, graph2::vertex_descriptor> mapping;
   120 
   121   bool isomorphism_correct = true;
   122   clock_t start = clock();
   123   
   124   isomorphism_correct = isomorphism(g1, g2, isomorphism_map(make_assoc_property_map(mapping)));
   125  
   126   BOOST_CHECK(isomorphism_correct);
   127               
   128   clock_t end = clock();
   129 
   130   std::cout << "Elapsed time (clock cycles): " << (end - start) << std::endl;
   131 
   132   bool verify_correct = true;
   133   
   134   verify_correct = verify_isomorphism(g1, g2, make_assoc_property_map(mapping));
   135   
   136   BOOST_CHECK(verify_correct);
   137 
   138   if (!isomorphism_correct || !verify_correct) {
   139     // Output graph 1
   140     {
   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;
   147       }
   148     }
   149 
   150     // Output graph 2
   151     {
   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;
   158       }
   159     }
   160   }
   161 }
   162 
   163 int test_main(int argc, char* argv[])
   164 {
   165   if (argc < 3) {
   166     test_isomorphism(30, 0.45);
   167 #ifdef __SYMBIAN32__
   168     std_log(LOG_FILENAME_LINE,"[End Test Case ]");
   169 
   170 	testResultXml("isomorphism");
   171 	close_log_file();
   172 #endif
   173     return 0;
   174   }
   175 
   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);
   179  
   180 #ifdef __SYMBIAN32__
   181 std_log(LOG_FILENAME_LINE,"[End Test Case ]");
   182 
   183 	testResultXml("isomorphism");
   184 	close_log_file();
   185 #endif
   186   return 0;
   187 }