FloydWarshall Module
Floyd-Warshall algorithm for all-pairs shortest paths in weighted graphs.
The Floyd-Warshall algorithm finds the shortest paths between all pairs of nodes in a single execution. It uses dynamic programming to iteratively improve shortest path estimates by considering each node as a potential intermediate vertex.
Algorithm
Algorithm |
Function |
Complexity |
Best For |
|---|---|---|---|
Floyd-Warshall |
floydWarshall |
O(V³) |
Dense graphs, all-pairs paths |
Key Concepts
- Dynamic Programming: Builds solution from smaller subproblems
- K-Intermediate Nodes: After k iterations, paths use only nodes {1,...,k} as intermediates
- Path Reconstruction: Predecessor matrix allows full path recovery
- Transitive Closure: Can be adapted for reachability (boolean weights)
The DP Recurrence
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
For each intermediate node k, check if going through k improves the path from i to j.
Comparison with Running Dijkstra V Times
Approach |
Complexity |
Best For |
|---|---|---|
Floyd-Warshall |
O(V³) |
Dense graphs (E ≈ V²) |
V × Dijkstra |
O(V(V+E) log V) |
Sparse graphs |
Johnson's |
O(V² log V + VE) |
Sparse graphs with negative weights |
Rule of thumb: Use Floyd-Warshall when E > V × log V (fairly dense)
Negative Cycles
The algorithm can detect negative cycles: after completion, if any node has dist[node][node] < 0, a negative cycle exists.
Use Cases
- All-pairs routing: Precompute distances for fast lookup
- Transitive closure: Reachability queries in databases
- Centrality metrics: Closeness and betweenness calculations
- Graph analysis: Detecting negative cycles
History
Published independently by Robert Floyd (1962), Stephen Warshall (1962), and Bernard Roy (1959). Floyd's version included path reconstruction.
Functions and values
| Function or value |
Description
|
||||
|
Detects if there's a negative cycle by checking if any node has negative distance to itself.
Parameters
AlgorithmAfter Floyd-Warshall completes, if any node has dist[node][node] < 0, there's a negative cycle reachable from that node.
|
||||
|
Computes shortest paths between all pairs of nodes using Floyd-Warshall.
Type Parameters
Parameters
AlgorithmDynamic programming approach with relaxation:
Example
WarningReturns val min: e1: 'T -> e2: 'T -> 'T (requires comparison)
val compare: e1: 'T -> e2: 'T -> int (requires comparison)
union case Result.Ok: ResultValue: 'T -> Result<'T,'TError>
Multiple items
module Map from Microsoft.FSharp.Collections -------------------- type Map<'Key,'Value (requires comparison)> = interface IReadOnlyDictionary<'Key,'Value> interface IReadOnlyCollection<KeyValuePair<'Key,'Value>> interface IEnumerable interface IStructuralEquatable interface IComparable interface IEnumerable<KeyValuePair<'Key,'Value>> interface ICollection<KeyValuePair<'Key,'Value>> interface IDictionary<'Key,'Value> new: elements: ('Key * 'Value) seq -> Map<'Key,'Value> member Add: key: 'Key * value: 'Value -> Map<'Key,'Value> ... -------------------- new: elements: ('Key * 'Value) seq -> Map<'Key,'Value> val tryFind: key: 'Key -> table: Map<'Key,'T> -> 'T option (requires comparison)
union case Result.Error: ErrorValue: 'TError -> Result<'T,'TError>
val printfn: format: Printf.TextWriterFormat<'T> -> 'T
|
||||
Computes all-pairs shortest paths with float weights.
Parameters
NoteUses
|
|||||
Computes all-pairs shortest paths with integer weights.
Parameters
Example
val result: Result<Map<(int * int),obj>,unit>
union case Result.Ok: ResultValue: 'T -> Result<'T,'TError>
val d: Map<(int * int),obj>
Multiple items
module Map from Microsoft.FSharp.Collections -------------------- type Map<'Key,'Value (requires comparison)> = interface IReadOnlyDictionary<'Key,'Value> interface IReadOnlyCollection<KeyValuePair<'Key,'Value>> interface IEnumerable interface IStructuralEquatable interface IComparable interface IEnumerable<KeyValuePair<'Key,'Value>> interface ICollection<KeyValuePair<'Key,'Value>> interface IDictionary<'Key,'Value> new: elements: ('Key * 'Value) seq -> Map<'Key,'Value> member Add: key: 'Key * value: 'Value -> Map<'Key,'Value> ... -------------------- new: elements: ('Key * 'Value) seq -> Map<'Key,'Value> val tryFind: key: 'Key -> table: Map<'Key,'T> -> 'T option (requires comparison)
union case Result.Error: ErrorValue: 'TError -> Result<'T,'TError>
union case Option.None: Option<'T>
|