Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

BFS.h
Go to the documentation of this file.
1 
31 #pragma once
32 
33 #ifdef OGDF_INCLUDE_CGAL
34 
37 
38 # include <iostream>
39 # include <queue>
40 
41 namespace ogdf {
42 namespace internal {
43 namespace gcm {
44 namespace graph {
45 
46 template<typename Graph = OGDFGraphWrapper, typename Flags = datastructure::TimestampFlags>
47 class BFS {
48 private:
49  using Node = typename Graph::Node;
50  using Edge = typename Graph::Edge;
51 
52  const Graph& graph;
53  std::queue<Node> queue;
54  Flags visited;
55 
56  static void settle_nothing(Node) { /* nothing to do*/
57  }
58 
59  static bool expand_all(Node, typename Graph::Edge) { return true; }
60 
61  static void traverse_nothing(Node, Edge) { /* nothing to do*/
62  }
63 
64 public:
65  BFS(const Graph& graph_) : graph(graph_), visited(graph.max_node_index() + 1) {
66  /*nothing to do*/
67  }
68 
69  template<typename Range, typename FSettle, typename FExpandEdge, typename FTraverseEdge,
70  typename InitVisit, typename AlreadyVisited, typename MarkVisited>
71  void traverse2(Range& sources, InitVisit&& init_visit, AlreadyVisited&& already_visited,
72  MarkVisited&& mark_visited, FSettle&& settle_node = settle_nothing,
73  FExpandEdge&& expand_edge = expand_all, FTraverseEdge&& traverse_edge = traverse_nothing) {
74  init_visit();
75  for (auto v : sources) {
76  queue.push(v);
77  mark_visited(v);
78  }
79  unsigned int iterations = 0;
80  while (!queue.empty()) {
81  OGDF_ASSERT(iterations <= graph.number_of_nodes());
82  ++iterations;
83  Node current_node = queue.front();
84  queue.pop();
85  settle_node(current_node);
86  for (const Edge& edge : graph.edges(current_node)) {
87  Node opposite = edge->opposite(current_node);
88  if (expand_edge(current_node, edge) && !already_visited(opposite)) {
89  traverse_edge(current_node, edge);
90  queue.push(opposite);
91  mark_visited(opposite);
92  }
93  }
94  }
95  }
96 
97  template<typename Range, typename FSettle, typename FExpandEdge, typename FTraverseEdge>
98  void traverse(Range sources, FSettle&& settle_node = settle_nothing,
99  FExpandEdge&& expand_edge = expand_all, FTraverseEdge&& traverse_edge = traverse_nothing) {
100  traverse2(
101  sources, [&]() { visited.clear(); },
102  [&](Node u) { return visited.is_set(u->index()); },
103  [&](Node u) { visited.set(u->index()); }, settle_node, expand_edge, traverse_edge);
104  }
105 
106  template<typename Range, typename FSettle>
107  void traverse(Range& source, FSettle&& settle_node) {
108  traverse(source, settle_node, expand_all, traverse_nothing);
109  }
110 
111  template<typename FSettle, typename FExpandEdge, typename FTraverseEdge>
112  void traverse(Node& source, FSettle&& settle_node = settle_nothing,
113  FExpandEdge&& expand_edge = expand_all, FTraverseEdge&& traverse_edge = traverse_nothing) {
114  std::vector<Node> sources = {source};
115  traverse(sources, settle_node, expand_edge, traverse_edge);
116  }
117 };
118 }
119 }
120 }
121 }
122 
123 #endif
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
OGDFGraphWrapper.h
ogdf::gml::Key::Node
@ Node
ogdf::gml::Key::Edge
@ Edge
ogdf::edge
EdgeElement * edge
The type of edges.
Definition: Graph_d.h:74
ogdf::gml::Key::Graph
@ Graph
ogdf::EdgeElement::opposite
node opposite(node v) const
Returns the adjacent node different from v.
Definition: Graph_d.h:413
TimestampFlags.h