800-floyd-warshall — Floyd-Warshall Algorithm
Tutorial Video
Text description (accessibility)
This video demonstrates the "800-floyd-warshall — Floyd-Warshall Algorithm" functional Rust example. Difficulty level: Fundamental. Key concepts covered: Functional Programming. Floyd-Warshall (1962) computes shortest paths between ALL pairs of vertices in a weighted graph in O(V³) time. Key difference from OCaml: 1. **All
Tutorial
The Problem
Floyd-Warshall (1962) computes shortest paths between ALL pairs of vertices in a weighted graph in O(V³) time. Unlike Dijkstra (single source) or Bellman-Ford (single source with negative weights), Floyd-Warshall solves the all-pairs problem directly. It is used in network distance matrices, routing table computation, social graph analysis (degree of separation), and computing transitive closures.
🎯 Learning Outcomes
dist[i][i] = 0dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])dist[i][i] < 0 after the algorithmCode Example
#![allow(clippy::all)]
//! # Floyd-Warshall Algorithm
pub fn floyd_warshall(n: usize, edges: &[(usize, usize, i32)]) -> Vec<Vec<i32>> {
let mut dist = vec![vec![i32::MAX / 2; n]; n];
for i in 0..n {
dist[i][i] = 0;
}
for &(u, v, w) in edges {
dist[u][v] = w;
}
for k in 0..n {
for i in 0..n {
for j in 0..n {
if dist[i][k] + dist[k][j] < dist[i][j] {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
dist
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_floyd() {
let edges = [(0, 1, 3), (0, 2, 8), (1, 2, 2), (2, 0, 5)];
let dist = floyd_warshall(3, &edges);
assert_eq!(dist[0][2], 5);
}
}Key Differences
i32::MAX/2 and OCaml's max_int/2 serve the same purpose.dist[v][v] < 0 after the algorithm indicates a negative cycle; both languages detect this the same way.|| instead of min) computes reachability; OCaml's Ocamlgraph.Fixpoint does this automatically for labeled graphs.OCaml Approach
OCaml uses Array.make_matrix n n max_int with max_int/2 as the convention. The triple for-loop is identical. OCaml's min function and array mutation follow the same structure. For transitive closure, replace int with bool and min with ||. The Ocamlgraph library implements Floyd-Warshall as part of its path algorithms suite.
Full Source
#![allow(clippy::all)]
//! # Floyd-Warshall Algorithm
pub fn floyd_warshall(n: usize, edges: &[(usize, usize, i32)]) -> Vec<Vec<i32>> {
let mut dist = vec![vec![i32::MAX / 2; n]; n];
for i in 0..n {
dist[i][i] = 0;
}
for &(u, v, w) in edges {
dist[u][v] = w;
}
for k in 0..n {
for i in 0..n {
for j in 0..n {
if dist[i][k] + dist[k][j] < dist[i][j] {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
dist
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_floyd() {
let edges = [(0, 1, 3), (0, 2, 8), (1, 2, 2), (2, 0, 5)];
let dist = floyd_warshall(3, &edges);
assert_eq!(dist[0][2], 5);
}
}#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_floyd() {
let edges = [(0, 1, 3), (0, 2, 8), (1, 2, 2), (2, 0, 5)];
let dist = floyd_warshall(3, &edges);
assert_eq!(dist[0][2], 5);
}
}
Deep Comparison
OCaml vs Rust: Floyd Warshall
Overview
See the example.rs and example.ml files for detailed implementations.
Key Differences
| Aspect | OCaml | Rust |
|---|---|---|
| Type system | Hindley-Milner | Ownership + traits |
| Memory | GC | Zero-cost abstractions |
| Mutability | Explicit ref | mut keyword |
| Error handling | Option/Result | Result<T, E> |
See README.md for detailed comparison.
Exercises
i32 with bool and use || and && instead of min/add.dist[v][v] < 0 and trace which cycle they belong to.