refactor dijkstra

This commit is contained in:
Dr. Matthias Ratajczak
2022-09-26 18:53:19 +02:00
parent 0fda17961a
commit b54d45d5b5
+17 -15
View File
@@ -24,14 +24,14 @@ impl<T> Debug for dyn Matrix<T> {
pub struct Dijkstra<'a, T> { pub struct Dijkstra<'a, T> {
matrix: Box<&'a mut dyn Matrix<T>>, matrix: Box<&'a mut dyn Matrix<T>>,
has_distance: HashSet<Coordinate>, unvisited_with_distance: HashSet<Coordinate>,
unvisited: HashSet<Coordinate>, unvisited_without_distance: HashSet<Coordinate>,
} }
impl<'a, T> Debug for Dijkstra<'a, T> { impl<'a, T> Debug for Dijkstra<'a, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Dijkstra") f.debug_struct("Dijkstra")
.field("unvisited", &self.unvisited) .field("unvisited", &self.unvisited_without_distance)
.finish() .finish()
} }
} }
@@ -41,17 +41,19 @@ where
T: PartialOrd + Add<Output = T> + Display + Copy + Debug, T: PartialOrd + Add<Output = T> + Display + Copy + Debug,
{ {
pub fn new(matrix: Box<&'a mut dyn Matrix<T>>) -> Self { pub fn new(matrix: Box<&'a mut dyn Matrix<T>>) -> Self {
let has_distance = HashSet::from([START]); let unvisited_with_distance = HashSet::new();
let unvisited = Self::initialize_unvisited_set(*matrix, START); let unvisited_without_distance = Self::initialize_unvisited_set(*matrix, START);
Self { Self {
matrix, matrix,
has_distance, unvisited_with_distance,
unvisited, unvisited_without_distance,
} }
} }
pub fn solve(&mut self) { pub fn solve(&mut self) {
while !(self.unvisited.is_empty() && self.has_distance.is_empty()) { while !(self.unvisited_without_distance.is_empty()
&& self.unvisited_with_distance.is_empty())
{
let coord = self.get_unvisited_coord_with_smallest_distance_from_start(); let coord = self.get_unvisited_coord_with_smallest_distance_from_start();
let neighbours = self.get_neighbours(&coord); let neighbours = self.get_neighbours(&coord);
let previous_distance = *self.matrix.get(coord).unwrap().get_distance().unwrap(); let previous_distance = *self.matrix.get(coord).unwrap().get_distance().unwrap();
@@ -63,7 +65,7 @@ where
fn get_unvisited_coord_with_smallest_distance_from_start(&mut self) -> Coordinate { fn get_unvisited_coord_with_smallest_distance_from_start(&mut self) -> Coordinate {
let coord = self let coord = self
.has_distance .unvisited_with_distance
.iter() .iter()
.filter_map(|c| { .filter_map(|c| {
let node = self.matrix.get(*c).unwrap(); let node = self.matrix.get(*c).unwrap();
@@ -72,7 +74,7 @@ where
.reduce(|(c0, v0), (c1, v1)| if v0 < v1 { (c0, v0) } else { (c1, v1) }) .reduce(|(c0, v0), (c1, v1)| if v0 < v1 { (c0, v0) } else { (c1, v1) })
.map(|(c, _)| *c) .map(|(c, _)| *c)
.unwrap_or((0, 0)); .unwrap_or((0, 0));
self.has_distance.remove(&coord); self.unvisited_with_distance.remove(&coord);
coord coord
} }
@@ -94,11 +96,11 @@ where
if let Some(old_distance) = next_node.get_distance() { if let Some(old_distance) = next_node.get_distance() {
if new_distance < *old_distance { if new_distance < *old_distance {
Self::update_node(next_node, new_distance, previous); Self::update_node(next_node, new_distance, previous);
self.update_distances_hashset(next); self.update_distances_hashsets(next);
} }
} else { } else {
Self::update_node(next_node, new_distance, previous); Self::update_node(next_node, new_distance, previous);
self.update_distances_hashset(next); self.update_distances_hashsets(next);
} }
} }
@@ -115,9 +117,9 @@ where
next_node.set_previous(previous); next_node.set_previous(previous);
} }
fn update_distances_hashset(&mut self, next: Coordinate) { fn update_distances_hashsets(&mut self, next: Coordinate) {
self.unvisited.remove(&next); self.unvisited_without_distance.remove(&next);
self.has_distance.insert(next); self.unvisited_with_distance.insert(next);
} }
} }