add basic dfs
This commit is contained in:
parent
6f8783b857
commit
0f7e3959f2
40
src/graph.rs
40
src/graph.rs
@ -42,20 +42,19 @@ where
|
||||
|
||||
/// find a path between two nodes using breadth-first-search.
|
||||
/// this finds a path with the least possible edges.
|
||||
pub fn find_path_bfs(&self, from: V, to: V) -> Option<Vec<V>> {
|
||||
pub fn find_path_bfs(&self, from: &V, to: &V) -> Option<Vec<V>> {
|
||||
let mut q = VecDeque::with_capacity(self.vertices.len());
|
||||
let mut visited = HashSet::with_capacity(self.vertices.len());
|
||||
|
||||
q.push_back(vec![&from]);
|
||||
visited.insert(&from);
|
||||
q.push_back(vec![from]);
|
||||
visited.insert(from);
|
||||
|
||||
while !q.is_empty() {
|
||||
let mut path = q.pop_front().unwrap();
|
||||
path.reserve(1);
|
||||
let current = path.last().unwrap();
|
||||
|
||||
for neighbor in self.neighbors(current) {
|
||||
if *neighbor == to {
|
||||
if neighbor == to {
|
||||
return path
|
||||
.into_iter()
|
||||
.cloned()
|
||||
@ -72,4 +71,35 @@ where
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// find a path between two nodes using depth-first-search.
|
||||
///
|
||||
/// this is short-circuiting and therefore does not guarantee
|
||||
/// the found path to contain the least possible edges.
|
||||
pub fn find_path_dfs(&self, from: &V, to: &V) -> Option<Vec<V>> {
|
||||
let mut q = Vec::with_capacity(self.vertices.len());
|
||||
|
||||
q.push(vec![from]);
|
||||
|
||||
while !q.is_empty() {
|
||||
let mut path = q.pop().unwrap();
|
||||
let ¤t = path.last().unwrap();
|
||||
|
||||
if current == to {
|
||||
return path.into_iter().cloned().collect::<Vec<_>>().into();
|
||||
}
|
||||
|
||||
for neighbor in self.neighbors(current).iter().rev() {
|
||||
if path.contains(&neighbor) {
|
||||
continue;
|
||||
}
|
||||
|
||||
path.push(neighbor);
|
||||
q.push(path.clone());
|
||||
path.pop();
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,13 +44,16 @@ fn main() {
|
||||
_ => 2,
|
||||
};
|
||||
|
||||
let path = g.find_path_bfs(a, b);
|
||||
assert!(path.is_some(), "Path from {a} to {b} should be found in G");
|
||||
let path = g.find_path_dfs(&a, &b);
|
||||
assert!(path.is_some(), "Path from {a} to {b} should be found in G with dfs");
|
||||
|
||||
let path = g.find_path_bfs(&a, &b);
|
||||
assert!(path.is_some(), "Path from {a} to {b} should be found in G with bfs");
|
||||
|
||||
let path = path.unwrap();
|
||||
assert_eq!(
|
||||
path.len(), shortest_path_length,
|
||||
"Shortest path from {a} to {b} in G should have length {shortest_path_length}\nFound path: {path:?}"
|
||||
"Shortest path (bfs) from {a} to {b} in G should have length {shortest_path_length}\nFound path: {path:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user