andres::graph
bridges.hxx
1 #pragma once
2 #ifndef ANDRES_GRAPH_BRIDGES_HXX
3 #define ANDRES_GRAPH_BRIDGES_HXX
4 
5 #include <stack>
6 #include <vector>
7 #include "subgraph.hxx"
8 
9 namespace andres {
10 namespace graph {
11 
12 template<class GRAPH>
14 {
15  typedef GRAPH GraphType;
16 
17  BridgesBuffers(const GraphType&);
18 
19  std::vector<std::size_t> depth_;
20  std::vector<std::size_t> min_successor_depth_;
21  std::vector<typename GraphType::VertexIterator> next_out_arc_;
22  std::vector<int> parent_;
23  std::vector<char> visited_;
24 };
25 
26 template<typename GRAPH, typename ARRAY>
27 inline void
29  const GRAPH&,
30  ARRAY&
31 );
32 
33 template<typename GRAPH, typename ARRAY>
34 inline void
36  const GRAPH&,
37  ARRAY&,
39 );
40 
41 template<typename GRAPH, typename SUBGRAPH, typename ARRAY>
42 inline void
44  const GRAPH&,
45  const SUBGRAPH&,
46  ARRAY&
47 );
48 
49 template<typename GRAPH, typename SUBGRAPH, typename ARRAY>
50 inline void
52  const GRAPH&,
53  const SUBGRAPH&,
54  ARRAY&,
56 );
57 
58 template<typename GRAPH, typename SUBGRAPH, typename ARRAY>
59 inline void
61  const GRAPH&,
62  const SUBGRAPH&,
63  std::size_t,
64  ARRAY&
65 );
66 
67 template<typename GRAPH, typename SUBGRAPH, typename ARRAY>
68 inline void
70  const GRAPH&,
71  const SUBGRAPH&,
72  std::size_t,
73  ARRAY&,
75 );
76 
77 template<typename GRAPH>
79  depth_(graph.numberOfVertices()),
80  min_successor_depth_(graph.numberOfVertices()),
81  next_out_arc_(graph.numberOfVertices()),
82  parent_(graph.numberOfVertices()),
83  visited_(graph.numberOfVertices())
84 {}
85 
96 template<typename GRAPH, typename ARRAY>
97 inline void
99  const GRAPH& graph,
100  ARRAY& is_bridge
101 )
102 {
103  auto buffer = BridgesBuffers<GRAPH>(graph);
104  findBridges(graph, DefaultSubgraphMask<>(), is_bridge, buffer);
105 }
106 
118 template<typename GRAPH, typename ARRAY>
119 inline void
121  const GRAPH& graph,
122  ARRAY& is_bridge,
123  BridgesBuffers<GRAPH>& buffer
124 )
125 {
126  findBridges(graph, DefaultSubgraphMask<>(), is_bridge, buffer);
127 }
128 
140 template<typename GRAPH, typename SUBGRAPH, typename ARRAY>
141 inline void
143  const GRAPH& graph,
144  const SUBGRAPH& subgraph_mask,
145  ARRAY& is_bridge
146 )
147 {
148  auto buffer = BridgesBuffers<GRAPH>(graph);
149  findBridges(graph, subgraph_mask, is_bridge, buffer);
150 }
151 
164 template<typename GRAPH, typename SUBGRAPH, typename ARRAY>
165 inline void
167  const GRAPH& graph,
168  const SUBGRAPH& subgraph_mask,
169  ARRAY& is_bridge,
170  BridgesBuffers<GRAPH>& buffer
171 )
172 {
173  std::fill(buffer.parent_.begin(), buffer.parent_.end(), -2);
174 
175  for (std::size_t i = 0; i < graph.numberOfVertices(); ++i)
176  if (buffer.parent_[i] == -2 && subgraph_mask.vertex(i))
177  findBridges(graph, subgraph_mask, i, is_bridge, buffer);
178 }
179 
192 template<typename GRAPH, typename SUBGRAPH, typename ARRAY>
193 inline void
195  const GRAPH& graph,
196  const SUBGRAPH& subgraph_mask,
197  std::size_t starting_vertex,
198  ARRAY& is_bridge
199 )
200 {
201  auto buffer = BridgesBuffers<GRAPH>(graph);
202  findBridges(graph, subgraph_mask, starting_vertex, is_bridge, buffer);
203 }
204 
218 template<typename GRAPH, typename SUBGRAPH, typename ARRAY>
219 inline void
221  const GRAPH& graph,
222  const SUBGRAPH& subgraph_mask,
223  std::size_t starting_vertex,
224  ARRAY& is_bridge,
225  BridgesBuffers<GRAPH>& buffer
226 )
227 {
228  std::fill(buffer.visited_.begin(), buffer.visited_.end(), 0);
229 
230  std::stack<std::size_t> S;
231 
232  S.push(starting_vertex);
233  buffer.depth_[starting_vertex] = 0;
234  buffer.parent_[starting_vertex] = -1;
235 
236  while (!S.empty())
237  {
238  auto v = S.top();
239  S.pop();
240 
241  if (!buffer.visited_[v])
242  {
243  buffer.visited_[v] = 1;
244  buffer.next_out_arc_[v] = graph.verticesFromVertexBegin(v);
245  buffer.min_successor_depth_[v] = buffer.depth_[v];
246  }
247  else
248  {
249  auto to = *buffer.next_out_arc_[v];
250 
251  if (buffer.min_successor_depth_[to] > buffer.depth_[v])
252  {
253  typename GRAPH::EdgeIterator e = graph.edgesFromVertexBegin(v) + (buffer.next_out_arc_[v] - graph.verticesFromVertexBegin(v));
254  is_bridge[*e] = 1;
255  }
256 
257  buffer.min_successor_depth_[v] = std::min(buffer.min_successor_depth_[v], buffer.min_successor_depth_[to]);
258  ++buffer.next_out_arc_[v];
259  }
260 
261  while (buffer.next_out_arc_[v] != graph.verticesFromVertexEnd(v))
262  {
263  typename GRAPH::EdgeIterator e = graph.edgesFromVertexBegin(v) + (buffer.next_out_arc_[v] - graph.verticesFromVertexBegin(v));
264 
265  if (
266  !subgraph_mask.vertex(*buffer.next_out_arc_[v]) ||
267  !subgraph_mask.edge(*e)
268  )
269  {
270  ++buffer.next_out_arc_[v];
271  continue;
272  }
273 
274  auto to = *buffer.next_out_arc_[v];
275  if (buffer.visited_[to])
276  {
277  if(buffer.parent_[v] != to)
278  buffer.min_successor_depth_[v] = std::min(buffer.min_successor_depth_[v], buffer.depth_[to]);
279 
280  ++buffer.next_out_arc_[v];
281  }
282  else
283  {
284  S.push(v);
285  S.push(to);
286  buffer.parent_[to] = v;
287  buffer.depth_[to] = buffer.depth_[v] + 1;
288  is_bridge[*e] = 0;
289  break;
290  }
291  }
292  }
293 }
294 
295 }
296 }
297 
298 #endif