Use BinaryHeap for day15 dijkstra

This commit is contained in:
Shadowfacts 2021-12-15 13:56:18 -05:00
parent 926745701c
commit 4a407de45b
2 changed files with 20 additions and 20 deletions

View File

@ -8,3 +8,6 @@ edition = "2021"
[dependencies] [dependencies]
itertools = "0.10.3" itertools = "0.10.3"
ansi_term = "0.12.1" ansi_term = "0.12.1"
[profile.release]
debug = true

View File

@ -1,4 +1,4 @@
use std::collections::{HashMap, HashSet}; use std::collections::BinaryHeap;
pub fn day15() { pub fn day15() {
// let input = r#" // let input = r#"
@ -21,7 +21,7 @@ pub fn day15() {
let graph: Graph<100> = input.into(); let graph: Graph<100> = input.into();
let path = dijkstra(&graph, graph.size(), &(0, 0), &graph.bottom_right()); let path = dijkstra(&graph, graph.size(), &(0, 0), &graph.bottom_right());
println!("found path: {:?}", path); // println!("found path: {:?}", path);
println!("path risk: {}", path_risk(&graph, &path.unwrap())); println!("path risk: {}", path_risk(&graph, &path.unwrap()));
let path = dijkstra( let path = dijkstra(
@ -30,7 +30,7 @@ pub fn day15() {
&(0, 0), &(0, 0),
&(graph.size() * 5 - 1, graph.size() * 5 - 1), &(graph.size() * 5 - 1, graph.size() * 5 - 1),
); );
println!("{:?}", path); // println!("{:?}", path);
println!("path risk: {}", path_risk(&graph, &path.unwrap())); println!("path risk: {}", path_risk(&graph, &path.unwrap()));
} }
@ -88,21 +88,15 @@ fn dijkstra<const N: usize>(
source: &Point, source: &Point,
target: &Point, target: &Point,
) -> Option<Vec<Point>> { ) -> Option<Vec<Point>> {
let mut q: HashSet<Point> = HashSet::new(); let mut q: BinaryHeap<(isize, Point)> = BinaryHeap::new();
let mut dist = vec![vec![0; size]; size]; let mut dist = vec![vec![usize::MAX; size]; size];
let mut prev = vec![vec![None; size]; size]; let mut prev = vec![vec![None; size]; size];
for x in 0..size {
for y in 0..size {
dist[x][y] = usize::max_value();
q.insert((x, y));
}
}
dist[source.0][source.1] = 0; dist[source.0][source.1] = 0;
q.push((0, *source));
while let Some(u) = q.iter().min_by_key(|p| dist[p.0][p.1]) { while let Some((neg_cost, u)) = q.pop() {
let u = u.clone(); let cost = -neg_cost as usize;
q.remove(&u);
if u == *target { if u == *target {
let mut s = vec![]; let mut s = vec![];
@ -114,13 +108,16 @@ fn dijkstra<const N: usize>(
return Some(s); return Some(s);
} }
if cost > dist[u.0][u.1] {
continue;
}
for v in neighbors(u, size) { for v in neighbors(u, size) {
if q.contains(&v) { let alt = dist[u.0][u.1] + g.risk(&v);
let alt = dist[u.0][u.1] + g.risk(&v); if alt < dist[v.0][v.1] {
if alt < dist[v.0][v.1] { dist[v.0][v.1] = alt;
dist[v.0][v.1] = alt; prev[v.0][v.1] = Some(u);
prev[v.0][v.1] = Some(u); q.push((-(alt as isize), v));
}
} }
} }
} }