GraphLib
Bearbeitung der Aufgabe Mini Graph Library für OOP WiSe 2023/24
Loading...
Searching...
No Matches
dfs.h
Go to the documentation of this file.
1#ifndef GRAPHLIB_ALGORITHMS_DFS_H
2#define GRAPHLIB_ALGORITHMS_DFS_H
3
4#include <functional>
5#include <set>
6#include <vector>
7
9
20
21namespace GraphLib {
22
27
43template <Internal::valid_graph_type G>
44std::vector<typename G::id_type> depth_first_search(const G& graph, typename G::id_type root,
45 typename G::id_type target)
46{
47 using id_type = G::id_type;
48
49 if (!graph.node_exists(root)) {
50 throw std::runtime_error("Root ID does not exist in Graph, cannot conduct DFS");
51 } else if (!graph.node_exists(target)) {
52 throw std::runtime_error("Target ID does not exist in Graph, cannot conduct DFS");
53 }
54 std::set<id_type> seen {};
55 std::vector<id_type> path {};
56
57 // Helper-funktion für rekursives DFS
58 std::function<bool(id_type, std::vector<id_type>&)> dfs_recursive =
59 [&](id_type current, std::vector<id_type>& current_path) -> bool {
60 if (current == target) {
61 return true;
62 }
63
64 seen.insert(current);
65
66 for (id_type neighbor : graph.get_neighbors(current)) {
67 if (!seen.contains(neighbor)) {
68 current_path.push_back(neighbor);
69 if (dfs_recursive(neighbor, current_path)) {
70 return true;
71 }
72 current_path.pop_back();
73 }
74 }
75 return false;
76 };
77
78 path.push_back(root);
79 if (dfs_recursive(root, path)) {
80 return path;
81 }
82
83 return std::vector<id_type> {};
84}
85
100template <Internal::valid_graph_type G>
101G depth_first_search(const G& graph, typename G::id_type root)
102{
103 using id_type = G::id_type;
104
105 if (!graph.node_exists(root)) {
106 throw std::runtime_error("Root ID does not exist in Graph, cannot construct Spanning Tree");
107 }
108
109 G mst {};
110 std::set<id_type> seen {};
111
112 for (const auto& id : graph.get_nodes()) {
113 mst.add_node_with_id(id, graph.get_node_data(id));
114 }
115
116 std::function<void(id_type)> dfs_recursive = [&](id_type current) {
117 seen.insert(current);
118
119 for (id_type neighbor : graph.get_neighbors(current)) {
120 if (!seen.contains(neighbor)) {
122 mst.add_edge(current, neighbor, graph.get_edge_weight(current, neighbor));
123 } else {
124 mst.add_edge(current, neighbor);
125 }
126 dfs_recursive(neighbor);
127 }
128 }
129 };
130
131 dfs_recursive(root);
132 return mst;
133}
134
135} // namespace GraphLib
136
137#endif
Checks if a type derives from WeightedGraph.
Definition concepts.h:179
Defines C++20 concepts used for type constraints in the GraphLib library.
std::vector< typename G::id_type > depth_first_search(const G &graph, typename G::id_type root, typename G::id_type target)
Performs a depth-first search (DFS) to find a path from root to target node in a graph.
Definition dfs.h:44