refactor dijkstra
This commit is contained in:
+17
-15
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user