andres::graph
minimum-spanning-tree.hxx
1 #pragma once
2 #ifndef ANDRES_GRAPH_MINIMUM_SPANNING_TREE_HXX
3 #define ANDRES_GRAPH_MINIMUM_SPANNING_TREE_HXX
4 
5 #include <queue>
6 #include <stdexcept>
7 #include <vector>
8 
9 #include "andres/functional.hxx"
10 #include "subgraph.hxx"
11 
12 namespace andres {
13 namespace graph {
14 
15 template<typename GRAPH, typename ECA, typename PRED, typename FUNC = Identity<typename ECA::value_type>>
16 inline typename ECA::value_type
18  const GRAPH&,
19  const ECA&,
20  PRED&,
21  const FUNC& = FUNC()
22 );
23 
24 template<typename GRAPH, typename ECA, typename SUBGRAPH, typename PRED, typename FUNC = Identity<typename ECA::value_type>>
25 inline typename ECA::value_type
27  const GRAPH&,
28  const ECA&,
29  const SUBGRAPH&,
30  PRED&,
31  const FUNC& = FUNC()
32 );
33 
34 template<typename GRAPH, typename ECA, typename SUBGRAPH, typename PRED, typename FUNC = Identity<typename ECA::value_type>>
35 inline typename ECA::value_type
37  const GRAPH&,
38  const ECA&,
39  const SUBGRAPH&,
40  std::size_t,
41  PRED&,
42  const FUNC& = FUNC()
43 );
44 
45 template<typename GRAPH, typename ECA, typename PRED, typename FUNC = Identity<typename ECA::value_type>>
46 inline typename ECA::value_type
48  const GRAPH&,
49  const ECA&,
50  PRED&,
51  const FUNC& = FUNC()
52 );
53 
54 template<typename GRAPH, typename ECA, typename SUBGRAPH, typename PRED, typename FUNC = Identity<typename ECA::value_type>>
55 inline typename ECA::value_type
57  const GRAPH&,
58  const ECA&,
59  const SUBGRAPH&,
60  PRED&,
61  const FUNC& = FUNC()
62 );
63 
64 template<typename GRAPH, typename ECA, typename SUBGRAPH, typename PRED, typename FUNC = Identity<typename ECA::value_type>>
65 inline typename ECA::value_type
67  const GRAPH&,
68  const ECA&,
69  const SUBGRAPH&,
70  std::size_t,
71  PRED&,
72  const FUNC& = FUNC()
73 );
74 
87 template<typename GRAPH, typename ECA, typename PRED, typename FUNC>
88 inline typename ECA::value_type
90  const GRAPH& graph,
91  const ECA& edge_weights,
92  PRED& predecessor,
93  const FUNC& f
94 )
95 {
96  return findMSTPrim(graph, edge_weights, DefaultSubgraphMask<>(), predecessor, f);
97 }
98 
112 template<typename GRAPH, typename ECA, typename SUBGRAPH, typename PRED, typename FUNC>
113 inline typename ECA::value_type
115  const GRAPH& graph,
116  const ECA& edge_weights,
117  const SUBGRAPH& subgraph_mask,
118  PRED& predecessor,
119  const FUNC& f
120 )
121 {
122  typedef typename ECA::value_type value_type;
123 
124  std::fill(std::begin(predecessor), std::end(predecessor), graph.numberOfEdges());
125 
126  value_type mst_value = value_type();
127  for (std::size_t i = 0; i < graph.numberOfVertices(); ++i)
128  if (predecessor[i] == graph.numberOfEdges() && subgraph_mask.vertex(i))
129  mst_value += findMSTPrim(graph, edge_weights, subgraph_mask, i, predecessor, f);
130 
131  return mst_value;
132 }
133 
148 template<typename GRAPH, typename ECA, typename SUBGRAPH, typename PRED, typename FUNC>
149 inline typename ECA::value_type
151  const GRAPH& graph,
152  const ECA& edge_weights,
153  const SUBGRAPH& subgraph_mask,
154  std::size_t starting_vertex,
155  PRED& predecessor,
156  const FUNC& f
157 )
158 {
159  typedef typename ECA::value_type value_type;
160 
161  struct element
162  {
163  element(value_type weight, std::size_t vertex_index) :
164  weight_(weight), vertex_index_(vertex_index)
165  {}
166 
167  bool operator<(const element& other) const
168  {
169  // as std::priority_queue is a max heap, invert comparison's logic
170  return weight_ > other.weight_;
171  }
172 
173  value_type weight_;
174  std::size_t vertex_index_;
175  };
176 
177  std::vector<value_type> min_edge(graph.numberOfVertices(), std::numeric_limits<value_type>::max());
178  std::vector<char> visited(graph.numberOfVertices());
179 
180  std::priority_queue<element> Q;
181  Q.push(element(value_type(), starting_vertex));
182 
183  predecessor[starting_vertex] = graph.numberOfEdges();
184 
185  value_type mst_value = value_type();
186 
187  while (!Q.empty())
188  {
189  auto v = Q.top();
190  Q.pop();
191 
192  if (visited[v.vertex_index_])
193  continue;
194 
195  visited[v.vertex_index_] = 1;
196  mst_value += v.weight_;
197 
198  auto e = graph.edgesFromVertexBegin(v.vertex_index_);
199  for (auto w = graph.verticesFromVertexBegin(v.vertex_index_); w != graph.verticesFromVertexEnd(v.vertex_index_); ++w, ++e)
200  if (subgraph_mask.vertex(*w) &&
201  subgraph_mask.edge(*e) &&
202  !visited[*w] &&
203  *w != v.vertex_index_ &&
204  f(edge_weights[*e]) < min_edge[*w]
205  )
206  {
207  min_edge[*w] = f(edge_weights[*e]);
208  predecessor[*w] = *e;
209  Q.push(element(f(edge_weights[*e]), *w));
210  }
211  }
212 
213  return mst_value;
214 }
215 
225 template<typename GRAPH, typename ECA, typename PRED, typename FUNC>
226 inline typename ECA::value_type
228  const GRAPH& graph,
229  const ECA& edge_weights,
230  PRED& predecessor,
231  const FUNC& f
232 )
233 {
234  return findMSTDynamicProgramming(graph, edge_weights, DefaultSubgraphMask<>(), predecessor, f);
235 }
236 
247 template<typename GRAPH, typename ECA, typename SUBGRAPH, typename PRED, typename FUNC>
248 inline typename ECA::value_type
250  const GRAPH& graph,
251  const ECA& edge_weights,
252  const SUBGRAPH& subgraph_mask,
253  PRED& predecessor,
254  const FUNC& f
255 )
256 {
257  typedef typename ECA::value_type value_type;
258 
259  std::fill(std::begin(predecessor), std::end(predecessor), graph.numberOfEdges());
260 
261  value_type mst_value = value_type();
262  for (std::size_t i = 0; i < graph.numberOfVertices(); ++i)
263  if (predecessor[i] == graph.numberOfEdges() && subgraph_mask.vertex(i))
264  mst_value += findMSTDynamicProgramming(graph, edge_weights, subgraph_mask, i, predecessor, f);
265 
266  return mst_value;
267 }
268 
280 template<typename GRAPH, typename ECA, typename SUBGRAPH, typename PRED, typename FUNC>
281 inline typename ECA::value_type
283  const GRAPH& graph,
284  const ECA& edge_weights,
285  const SUBGRAPH& subgraph_mask,
286  std::size_t starting_vertex,
287  PRED& predecessor,
288  const FUNC& f
289 )
290 {
291  typedef typename ECA::value_type value_type;
292 
293  std::vector<value_type> min_edge(graph.numberOfVertices(), std::numeric_limits<value_type>::max());
294  std::vector<char> visited(graph.numberOfVertices());
295 
296  min_edge[starting_vertex] = value_type();
297  predecessor[starting_vertex] = graph.numberOfEdges();
298 
299  value_type mst_value = value_type();
300 
301  for (std::size_t i = 0; i < graph.numberOfVertices(); ++i)
302  {
303  int v = -1;
304 
305  for (std::size_t j = 0; j < graph.numberOfVertices(); ++j)
306  if (subgraph_mask.vertex(j) &&
307  !visited[j] &&
308  (v == -1 || min_edge[j] < min_edge[v])
309  )
310  v = j;
311 
312  if (v == -1)
313  return mst_value;
314 
315  mst_value += min_edge[v];
316  visited[v] = 1;
317 
318  auto e = graph.edgesFromVertexBegin(v);
319  for (auto w = graph.verticesFromVertexBegin(v); w != graph.verticesFromVertexEnd(v); ++w, ++e)
320  if (subgraph_mask.vertex(*w) &&
321  subgraph_mask.edge(*e) &&
322  !visited[*w] &&
323  *w != v &&
324  f(edge_weights[*e]) < min_edge[*w]
325  )
326  {
327  min_edge[*w] = f(edge_weights[*e]);
328  predecessor[*w] = *e;
329  }
330  }
331 
332  return mst_value;
333 }
334 
335 } // namespace graph
336 } // namespace andres
337 
338 #endif
339