Skip to content

Instantly share code, notes, and snippets.

@ChenZhongPu
Last active September 21, 2019 06:42
Show Gist options
  • Save ChenZhongPu/f4e84190ecdf2f641aa2d49d02ea7646 to your computer and use it in GitHub Desktop.
Save ChenZhongPu/f4e84190ecdf2f641aa2d49d02ea7646 to your computer and use it in GitHub Desktop.
Bidirectional Dijkstra Algorithm in Rust
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
}
@ChenZhongPu
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment