use crate::algo::graph::{Edge, WeightedAdjacencyList};
impl WeightedAdjacencyList {
pub fn bellman_ford(&self, start: usize) -> Vec<f64> {
let n = self.node_count();
let mut dists = vec![f64::INFINITY; n];
dists[start] = 0.;
for _ in 1..n {
for (from, edges) in self.nodes() {
for &Edge { to, weight: cost } in edges {
let new_cost = dists[from] + cost;
if new_cost < dists[to] {
dists[to] = new_cost;
}
}
}
}
for _ in 1..n {
for (from, edges) in self.nodes() {
for &Edge { to, weight: cost } in edges {
if dists[from] + cost < dists[to] {
dists[to] = f64::NEG_INFINITY;
}
}
}
}
dists
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bellman_ford() {
let graph = WeightedAdjacencyList::new_directed(
9,
&[
(0, 1, 1.),
(1, 2, 1.),
(2, 4, 1.),
(4, 3, -3.),
(3, 2, 1.),
(1, 5, 4.),
(1, 6, 4.),
(5, 6, 5.),
(6, 7, 4.),
(5, 7, 3.),
],
);
let dists = graph.bellman_ford(0);
assert_eq!(
&dists,
&[
0.00, 1.00, -f64::INFINITY, -f64::INFINITY, -f64::INFINITY, 5.00, 5.00, 8.00, f64::INFINITY, ]
);
}
}