Last active
September 21, 2019 06:42
-
-
Save ChenZhongPu/f4e84190ecdf2f641aa2d49d02ea7646 to your computer and use it in GitHub Desktop.
Bidirectional Dijkstra Algorithm in Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn bi_dij(&self, reverse_graph: &Graph2, start: usize, end: usize) -> Option<f64> { | |
let mut fwd_dists = vec![std::f64::MAX; self.adj_list.len()]; | |
let mut fwd_visited = vec![false; self.adj_list.len()]; | |
let mut rev_dists = vec![std::f64::MAX; self.adj_list.len()]; | |
let mut rev_visited = vec![false; self.adj_list.len()]; | |
let mut fwd_heap = BinaryHeap::new(); | |
fwd_heap.push(State {node: start, dist: 0.0}); | |
let mut rev_heap = BinaryHeap::new(); | |
rev_heap.push(State {node: end, dist: 0.0}); | |
fwd_dists[start] = 0.0; | |
rev_dists[end] = 0.0; | |
fn expand(graph: &Graph2, first_heap: &mut BinaryHeap<State>, first_visited: &mut Vec<bool>, first_dists: &mut Vec<f64>, | |
second_heap: &BinaryHeap<State>, second_visited: &Vec<bool>, second_dists: &Vec<f64>, mu: &mut f64) -> Option<f64> { | |
if let Some(State {node, dist}) = first_heap.pop() { | |
if let Some(second_state) = second_heap.peek() { | |
if dist + second_state.dist >= *mu { return Some(*mu); } | |
} | |
if !first_visited[node] { | |
first_visited[node] = true; | |
for neighbor in &graph.adj_list[node] { | |
let next = State {dist: dist + neighbor.cost, node: neighbor.node}; | |
if next.dist < first_dists[next.node] && !first_visited[next.node] { | |
first_heap.push(next); | |
first_dists[next.node] = next.dist; | |
} | |
if second_visited[next.node] && next.dist + second_dists[next.node] < *mu { | |
*mu = next.dist + second_dists[next.node]; | |
} | |
} | |
} | |
} | |
None | |
} | |
let mut mu = std::f64::MAX; | |
for _ in 0..self.adj_list.len() { | |
if let Some(n) = expand(&self, &mut fwd_heap, &mut fwd_visited, &mut fwd_dists, | |
&rev_heap, &rev_visited, &rev_dists, &mut mu) { | |
return Some(n); | |
} | |
if let Some(n) = expand(&reverse_graph, &mut rev_heap, &mut rev_visited, &mut rev_dists, | |
&fwd_heap, &fwd_visited, &fwd_dists, &mut mu) { | |
return Some(n); | |
} | |
} | |
None | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Be careful of the stopping condition! see more at https://www.cs.princeton.edu/courses/archive/spr06/cos423/Handouts/EPP%20shortest%20path%20algorithms.pdf