GraphLibrary  0.0.1
A simple library that implements various graph algorithms.
 All Classes Namespaces Files Functions Variables Typedefs Macros
BFS.hpp
Go to the documentation of this file.
1 #ifndef GL_BFS_HPP
2 #define GL_BFS_HPP
3 
4 #include <limits>
5 
6 #include "../structures/Graph.hpp"
7 
8 namespace gl {
9 namespace algorithm {
10 
12 // Class declaration
14 
20 template <class Graph>
21 class BFS {
22  using idx_t = typename Graph::idx_t;
24  using visit_list_t = typename Graph::visit_list_t;
25  using BFS_queue_t = std::deque<idx_t>;
26  using distance_list_t = std::vector<idx_t>;
27  using idx_list_t = typename Graph::idx_list_t;
28 
29 public:
36  explicit BFS(const Graph&, const idx_t);
37 
38  BFS();
39  BFS(const BFS &) = default;
40  BFS(BFS &&) noexcept = default;
41  BFS &operator=(const BFS &) = default;
42  BFS &operator=(BFS &&) = default;
43  ~BFS() = default;
44 
50  void compute(const Graph& graph, const idx_t src);
61  ordered_list_t getTraversalOrderMaxDistance (const idx_t& distance) const;
62 
68  idx_list_t getNodesExactDistance (const idx_t& distance) const;
74  idx_t getNodeDistance (const idx_t& dest) const;
80  idx_list_t getNodesMaxDistance (const idx_t& distance) const;
86  ordered_list_t getPath (const idx_t& dest) const;
87 
88 private:
89  bool isInitialized_ = false;
94 };
95 
97 // Member function implementations
99 
100 template <class Graph>
101 BFS<Graph>::BFS() : isInitialized_(false) {}
102 
103 template <class Graph>
104 BFS<Graph>::BFS(const Graph& graph, const idx_t src) : isInitialized_(false), src_(src)
105 {
106  compute(graph, src);
107 }
108 
109 template <class Graph>
110 void BFS<Graph>::compute (const Graph& graph, const idx_t src)
111 {
112  graph.checkRange(src);
113  idx_t INF = std::numeric_limits<idx_t>::max();
114 
115  BFS_queue_t queue; // nodes to check the neighbours of
116  ordered_list_t out; // result node lists
117  idx_list_t tempList; // temporary node lists
118  idx_list_t parents(graph.numNodes()); // parents on shortest path tree
119  visit_list_t visited(graph.numNodes(),false); // list of visited nodes
120  distance_list_t distances(graph.numNodes(),INF);
121  auto v = src;
122 
123  // traversal
124  queue.push_back(v);
125  visited[v] = true;
126  distances[v] = 0;
127  parents[v] = v;
128  while(!queue.empty()) {
129  v = queue.front();
130  queue.pop_front();
131  out.push_back(v);
132  tempList = graph.getUnvisitedNeighbours(v,visited);
133  for (auto elem : tempList) {
134  visited[elem] = true;
135  distances[elem] = distances[v] + 1;
136  parents[elem] = v;
137  queue.push_back(elem);
138  }
139  }
140  parents_ = parents;
141  final_ = out;
142  distances_ = distances;
143  isInitialized_ = true;
144 }
145 
146 template <class Graph>
148  GL_ASSERT(isInitialized_,"BFS::getTraversalOrder | BFS has not been initialized with a graph.")
149  return final_;
150 }
151 
152 template <class Graph>
154  GL_ASSERT(isInitialized_,"BFS::getTraversalOrderMaxDistance | BFS has not been initialized with a graph.")
155  ordered_list_t result;
156  for (auto x : final_) {
157  if (distances_[x] > distance) continue;
158  result.push_back(x);
159  }
160  return result;
161 }
162 
163 template <class Graph>
165  GL_ASSERT(isInitialized_,"BFS::getNodesExactDistance | BFS has not been initialized with a graph.")
166  idx_list_t result;
167  for (auto elem : final_) {
168  if (distances_[elem] == distance) result.push_back(elem);
169  }
170  return result;
171 }
172 
173 template <class Graph>
174 typename Graph::idx_t BFS<Graph>::getNodeDistance (const idx_t& dest) const {
175  GL_ASSERT(isInitialized_,"BFS::getNodeDistance | BFS has not been initialized with a graph.")
176  GL_ASSERT((0 <= dest), (std::string("Negative index: ") + std::to_string(dest) + std::string(" < 0")))
177  GL_ASSERT((dest < distances_.size()), ("Index " + std::to_string(dest) + " is larger than the max: " + std::to_string(distances_.size() - 1)))
178 
179  return distances_[dest];
180 }
181 
182 template <class Graph>
183 typename Graph::idx_list_t BFS<Graph>::getNodesMaxDistance (const idx_t& distance) const {
184  GL_ASSERT(isInitialized_,"BFS::getNodesMaxDistance | BFS has not been initialized with a graph.")
185  idx_list_t result;
186  for (auto elem : final_) {
187  if (distances_[elem] <= distance) result.push_back(elem);
188  }
189  return result;
190 }
191 
192 template <class Graph>
193 typename Graph::ordered_list_t BFS<Graph>::getPath (const idx_t& dest) const {
194  GL_ASSERT(isInitialized_,"BFS::getPath | BFS has not been initialized with a graph.")
195  GL_ASSERT((0 <= dest), (std::string("Negative index: ") + std::to_string(dest) + std::string(" < 0")))
196  GL_ASSERT((dest < distances_.size()), ("Index " + std::to_string(dest) + " is larger than the max: " + std::to_string(distances_.size() - 1)))
197  if (dest == src_)
198  {
199  return {src_};
200  }
201  ordered_list_t result;
202  idx_t parent = parents_[dest];
203  result.push_front(dest);
204  result.push_front(parent);
205  while (parent != src_)
206  {
207  parent = parents_[parent];
208  result.push_front(parent);
209  }
210  return result;
211 }
212 
213 } // namespace algorithm
214 } // namespace gl
215 
216 #endif // GL_BFS_HPP
Class that provides Graph traversal using the BFS scheme.
Definition: BFS.hpp:21
typename Graph::visit_list_t visit_list_t
Boolean list that stored previously visited nodes.
Definition: BFS.hpp:24
ordered_list_t getTraversalOrderMaxDistance(const idx_t &distance) const
Computes the BFS node traversal order from the source.
Definition: BFS.hpp:153
idx_list_t parents_
Parents on shortest path tree.
Definition: BFS.hpp:91
idx_list_t getNodesExactDistance(const idx_t &distance) const
Computes all nodes that are at the exact distance given from the source.
Definition: BFS.hpp:164
typename Graph::idx_t idx_t
Type of indices.
Definition: BFS.hpp:22
std::vector< idx_t > idx_list_t
Index List type.
Definition: Graph.hpp:48
gl::index_type idx_t
Index type.
Definition: Graph.hpp:44
Stores and implements a Graph.
Definition: Graph.hpp:39
ordered_list_t getTraversalOrder() const
Computes the BFS node traversal order from the source.
Definition: BFS.hpp:147
ordered_list_t getPath(const idx_t &dest) const
Computes the BFS shortest path from 'src' to 'dest'.
Definition: BFS.hpp:193
#define GL_ASSERT(EXPR, ERROR_MSG)
Custom assert that supports attaching a message.
Definition: gl_assert.hpp:14
std::deque< idx_t > BFS_queue_t
Data structure for BFS searches.
Definition: BFS.hpp:25
idx_t numNodes() const
Returns the number of nodes currently in the graph.
Definition: Graph.hpp:406
void compute(const Graph &graph, const idx_t src)
Computation. This is where the BFS algorithm is performed.
Definition: BFS.hpp:110
typename Graph::idx_list_t idx_list_t
Unordered node ID list.
Definition: BFS.hpp:27
idx_t getNodeDistance(const idx_t &dest) const
Returns the number of edges between 'src' and 'dest'.
Definition: BFS.hpp:174
std::list< idx_t > ordered_list_t
Ordered List type.
Definition: Graph.hpp:49
std::vector< idx_t > distance_list_t
Stores BFS distances of each node.
Definition: BFS.hpp:26
typename Graph::ordered_list_t ordered_list_t
Ordered node ID list.
Definition: BFS.hpp:23
BFS()
Default constructor.
Definition: BFS.hpp:101
idx_t src_
Source node.
Definition: BFS.hpp:90
std::vector< bool > visit_list_t
Visited-List type.
Definition: Graph.hpp:50
void checkRange(const idx_t &idx1) const
Only one index that gets range checked.
Definition: Graph.hpp:1389
idx_list_t getNodesMaxDistance(const idx_t &distance) const
Computes all nodes that are at within a maximum distance given from the source.
Definition: BFS.hpp:183
idx_list_t getUnvisitedNeighbours(const idx_t &node, const std::vector< bool > &visited) const
Returns a list of endpoints + edge weights of outgoing edges from start.
Definition: Graph.hpp:1096
distance_list_t distances_
List containing distances from source.
Definition: BFS.hpp:93
ordered_list_t final_
BFS Traversal order.
Definition: BFS.hpp:92
bool isInitialized_
Boolean storing initialization status.
Definition: BFS.hpp:89