CMR  1.3.0
gen_network.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "gen_generic.hpp"
4 #include "matrix.hpp"
5 
6 #include <boost/graph/adjacency_list.hpp>
7 #include <boost/graph/depth_first_search.hpp>
8 #include <boost/graph/two_bit_color_map.hpp>
9 
10 template <typename OutputIterator, typename Graph, typename IndexMap, typename Vertex>
11 OutputIterator find_path(Graph graph, IndexMap index_map, Vertex s, Vertex t, OutputIterator result)
12 {
13  if (s == t)
14  {
15  *result++ = s;
16  return result;
17  }
18 
19  typedef boost::graph_traits <Graph> graph_traits_t;
20  typedef typename graph_traits_t::vertex_descriptor vertex_t;
21 
23  typedef boost::two_bit_color_map <> color_map_t;
24  color_map_t color_map(boost::num_vertices(graph));
25 
27  typedef std::vector <vertex_t> predecessors_t;
28  typedef boost::iterator_property_map <typename predecessors_t::iterator, IndexMap> predecessor_map_t;
29 
30  predecessors_t predecessors(boost::num_vertices(graph), graph_traits_t::null_vertex());
31  predecessor_map_t predecessor_map(predecessors.begin(), index_map);
32 
33  boost::depth_first_visit(graph, s, boost::make_dfs_visitor(record_predecessors(predecessor_map, boost::on_tree_edge())), color_map);
34 
35  vertex_t current_vertex = t;
36  while (current_vertex != s)
37  {
38  vertex_t next_vertex = boost::get(predecessor_map, current_vertex);
39  if (next_vertex == graph_traits_t::null_vertex())
40  return result;
41 
42  *result++ = current_vertex;
43 
44  current_vertex = next_vertex;
45  }
46 
47  *result++ = s;
48  return result;
49 }
50 
52 {
53 public:
54  network_matrix_generator(size_t height, size_t width, tu::log_level level) :
55  matrix_generator("network", height, width, level)
56  {
57 
58  }
59 
61  {
62 
63  }
64 
65  template <typename MatrixType>
66  void generate(MatrixType& matrix)
67  {
68  size_t nodes = matrix.size1() + 1;
69 
70  if (_level != tu::LOG_QUIET)
71  std::cerr << "Creating a spanning tree with " << nodes << " nodes..." << std::flush;
72 
74  typedef boost::adjacency_list <boost::vecS, boost::vecS, boost::undirectedS> tree_graph_t;
75  typedef boost::graph_traits <tree_graph_t> tree_traits_t;
76 
77  tree_graph_t tree_graph(nodes);
78  std::vector <tree_traits_t::vertex_descriptor> used_vertices;
79 
80  tree_traits_t::vertex_iterator vertex_iter, vertex_beyond;
81  for (boost::tie(vertex_iter, vertex_beyond) = boost::vertices(tree_graph); vertex_iter != vertex_beyond; ++vertex_iter)
82  {
83  if (!used_vertices.empty())
84  {
85  boost::uniform_int <int> dist(0, used_vertices.size() - 1);
86  tree_traits_t::vertex_descriptor other = used_vertices[dist(_rng)];
87 
88  boost::add_edge(*vertex_iter, other, tree_graph);
89  }
90  used_vertices.push_back(*vertex_iter);
91  }
92 
93  if (_level != tu::LOG_QUIET)
94  std::cerr << " done.\nAdding edges and filling matrix..." << std::flush;
95 
96  for (size_t column = 0; column < _matrix.size2(); ++column)
97  {
99  boost::uniform_int <int> dist(0, nodes - 1);
100  tree_traits_t::vertex_descriptor u, v;
101  do
102  {
103  u = boost::vertex(dist(_rng), tree_graph);
104  v = boost::vertex(dist(_rng), tree_graph);
105  }
106  while (u == v || boost::edge(u, v, tree_graph).second);
107 
108  std::set <tree_traits_t::vertex_descriptor> path_vertices;
109  find_path(tree_graph, boost::get(boost::vertex_index, tree_graph), u, v, std::inserter(path_vertices, path_vertices.end()));
110 
111  size_t row = 0;
112  tree_traits_t::edge_iterator edge_iter, edge_beyond;
113  for (boost::tie(edge_iter, edge_beyond) = boost::edges(tree_graph); edge_iter != edge_beyond; ++edge_iter)
114  {
115  u = boost::source(*edge_iter, tree_graph);
116  v = boost::target(*edge_iter, tree_graph);
117 
118  _matrix(row, column) = (path_vertices.find(u) != path_vertices.end() && path_vertices.find(v) != path_vertices.end()) ? 1 : 0;
119 
120  ++row;
121  }
122  }
123 
124  if (_level != tu::LOG_QUIET)
125  std::cerr << " done.\nCorrecting the signs..." << std::flush;
126  sign();
127  if (_level != tu::LOG_QUIET)
128  std::cerr << " done." << std::endl;
129  }
130 
131  virtual void generate()
132  {
133  if (_height <= _width)
134  {
135  generate(_matrix);
136  }
137  else
138  {
140  generate(transposed);
141  }
142  }
143 
144 };
Definition: gen_generic.hpp:11
boost::mt19937 _rng
Definition: gen_generic.hpp:16
tu::log_level _level
Definition: gen_generic.hpp:17
virtual void sign()
Definition: gen_generic.hpp:74
tu::integer_matrix _matrix
Definition: gen_generic.hpp:15
size_t _height
Definition: gen_generic.hpp:13
size_t _width
Definition: gen_generic.hpp:14
Definition: gen_network.hpp:52
void generate(MatrixType &matrix)
Definition: gen_network.hpp:66
network_matrix_generator(size_t height, size_t width, tu::log_level level)
Definition: gen_network.hpp:54
virtual ~network_matrix_generator()
Definition: gen_network.hpp:60
virtual void generate()
Definition: gen_network.hpp:131
Definition: matrix_transposed.hpp:47
OutputIterator find_path(Graph graph, IndexMap index_map, Vertex s, Vertex t, OutputIterator result)
Definition: gen_network.hpp:11
void used_vertices(const Graph &graph, VertexSet &vertex_set)
Definition: graph_utils.hpp:296
log_level
Definition: common.hpp:36
@ LOG_QUIET
Definition: common.hpp:37