1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
//=======================================================================
// Copyright 2009 Trustees of Indiana University.
// Authors: Michael Hansen
//
// 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 <fstream>
#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/iteration_macros.hpp>
#include <boost/graph/mcgregor_common_subgraphs.hpp>
#include <boost/property_map/shared_array_property_map.hpp>
using namespace boost;
// Callback that looks for the first common subgraph whose size
// matches the user's preference.
template <typename Graph>
struct example_callback {
typedef typename graph_traits<Graph>::vertices_size_type VertexSizeFirst;
example_callback(const Graph& graph1) :
m_graph1(graph1) { }
template <typename CorrespondenceMapFirstToSecond,
typename CorrespondenceMapSecondToFirst>
bool operator()(CorrespondenceMapFirstToSecond correspondence_map_1_to_2,
CorrespondenceMapSecondToFirst correspondence_map_2_to_1,
VertexSizeFirst subgraph_size) {
// Fill membership map for first graph
typedef typename property_map<Graph, vertex_index_t>::type VertexIndexMap;
typedef shared_array_property_map<bool, VertexIndexMap> MembershipMap;
MembershipMap membership_map1(num_vertices(m_graph1),
get(vertex_index, m_graph1));
fill_membership_map<Graph>(m_graph1, correspondence_map_1_to_2, membership_map1);
// Generate filtered graphs using membership map
typedef typename membership_filtered_graph_traits<Graph, MembershipMap>::graph_type
MembershipFilteredGraph;
MembershipFilteredGraph subgraph1 =
make_membership_filtered_graph(m_graph1, membership_map1);
// Print the graph out to the console
std::cout << "Found common subgraph (size " << subgraph_size << ")" << std::endl;
print_graph(subgraph1);
std::cout << std::endl;
// Explore the entire space
return (true);
}
private:
const Graph& m_graph1;
VertexSizeFirst m_max_subgraph_size;
};
int main (int argc, char *argv[]) {
// Using a vecS graph here so that we don't have to mess around with
// a vertex index map; it will be implicit.
typedef adjacency_list<listS, vecS, directedS,
property<vertex_name_t, unsigned int,
property<vertex_index_t, unsigned int> >,
property<edge_name_t, unsigned int> > Graph;
typedef property_map<Graph, vertex_name_t>::type VertexNameMap;
// Test maximum and unique variants on known graphs
Graph graph_simple1, graph_simple2;
example_callback<Graph> user_callback(graph_simple1);
VertexNameMap vname_map_simple1 = get(vertex_name, graph_simple1);
VertexNameMap vname_map_simple2 = get(vertex_name, graph_simple2);
// Graph that looks like a triangle
put(vname_map_simple1, add_vertex(graph_simple1), 1);
put(vname_map_simple1, add_vertex(graph_simple1), 2);
put(vname_map_simple1, add_vertex(graph_simple1), 3);
add_edge(0, 1, graph_simple1);
add_edge(0, 2, graph_simple1);
add_edge(1, 2, graph_simple1);
std::cout << "First graph:" << std::endl;
print_graph(graph_simple1);
std::cout << std::endl;
// Triangle with an extra vertex
put(vname_map_simple2, add_vertex(graph_simple2), 1);
put(vname_map_simple2, add_vertex(graph_simple2), 2);
put(vname_map_simple2, add_vertex(graph_simple2), 3);
put(vname_map_simple2, add_vertex(graph_simple2), 4);
add_edge(0, 1, graph_simple2);
add_edge(0, 2, graph_simple2);
add_edge(1, 2, graph_simple2);
add_edge(1, 3, graph_simple2);
std::cout << "Second graph:" << std::endl;
print_graph(graph_simple2);
std::cout << std::endl;
// All subgraphs
std::cout << "mcgregor_common_subgraphs:" << std::endl;
mcgregor_common_subgraphs
(graph_simple1, graph_simple2, true, user_callback,
vertices_equivalent(make_property_map_equivalent(vname_map_simple1, vname_map_simple2)));
std::cout << std::endl;
// Unique subgraphs
std::cout << "mcgregor_common_subgraphs_unique:" << std::endl;
mcgregor_common_subgraphs_unique
(graph_simple1, graph_simple2, true, user_callback,
vertices_equivalent(make_property_map_equivalent(vname_map_simple1, vname_map_simple2)));
std::cout << std::endl;
// Maximum subgraphs
std::cout << "mcgregor_common_subgraphs_maximum:" << std::endl;
mcgregor_common_subgraphs_maximum
(graph_simple1, graph_simple2, true, user_callback,
vertices_equivalent(make_property_map_equivalent(vname_map_simple1, vname_map_simple2)));
std::cout << std::endl;
// Maximum, unique subgraphs
std::cout << "mcgregor_common_subgraphs_maximum_unique:" << std::endl;
mcgregor_common_subgraphs_maximum_unique
(graph_simple1, graph_simple2, true, user_callback,
vertices_equivalent(make_property_map_equivalent(vname_map_simple1, vname_map_simple2)));
return 0;
}
|