<E>(cost: (edgeData: E) => number): <N, T extends Kind = "directed">(
graph: Graph<N, E, T> | MutableGraph<N, E, T>
) => AllPairsResult<E>
<N, E, T extends Kind = "directed">(
graph: Graph<N, E, T> | MutableGraph<N, E, T>,
cost: (edgeData: E) => number
): AllPairsResult<E>Finds shortest paths between all pairs of nodes using the Floyd-Warshall algorithm.
Details
Computes distances, reconstructed node paths, and edge-data paths for every
source and target pair in O(V^3) time. Negative edge weights are allowed, but
a GraphError is thrown if any negative cycle is detected.
Example (Finding all-pairs shortest paths)
import { Graph } from "effect"
const graph = Graph.directed<string, number>((mutable) => {
const a = Graph.addNode(mutable, "A")
const b = Graph.addNode(mutable, "B")
const c = Graph.addNode(mutable, "C")
Graph.addEdge(mutable, a, b, 3)
Graph.addEdge(mutable, b, c, 2)
Graph.addEdge(mutable, a, c, 7)
})
const result = Graph.floydWarshall(graph, (edgeData) => edgeData)
const distanceAToC = result.distances.get(0)?.get(2) // 5 (A->B->C)
const pathAToC = result.paths.get(0)?.get(2) // [0, 1, 2]export const const floydWarshall: {
<E>(cost: (edgeData: E) => number): <
N,
T extends Kind = "directed"
>(
graph: Graph<N, E, T> | MutableGraph<N, E, T>
) => AllPairsResult<E>
<N, E, T extends Kind = "directed">(
graph: Graph<N, E, T> | MutableGraph<N, E, T>,
cost: (edgeData: E) => number
): AllPairsResult<E>
}
Finds shortest paths between all pairs of nodes using the Floyd-Warshall
algorithm.
Details
Computes distances, reconstructed node paths, and edge-data paths for every
source and target pair in O(V^3) time. Negative edge weights are allowed, but
a GraphError is thrown if any negative cycle is detected.
Example (Finding all-pairs shortest paths)
import { Graph } from "effect"
const graph = Graph.directed<string, number>((mutable) => {
const a = Graph.addNode(mutable, "A")
const b = Graph.addNode(mutable, "B")
const c = Graph.addNode(mutable, "C")
Graph.addEdge(mutable, a, b, 3)
Graph.addEdge(mutable, b, c, 2)
Graph.addEdge(mutable, a, c, 7)
})
const result = Graph.floydWarshall(graph, (edgeData) => edgeData)
const distanceAToC = result.distances.get(0)?.get(2) // 5 (A->B->C)
const pathAToC = result.paths.get(0)?.get(2) // [0, 1, 2]
floydWarshall: {
<function (type parameter) E in <E>(cost: (edgeData: E) => number): <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => AllPairsResult<E>E>(
cost: (edgeData: E) => numbercost: (edgeData: EedgeData: function (type parameter) E in <E>(cost: (edgeData: E) => number): <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => AllPairsResult<E>E) => number
): <function (type parameter) N in <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): AllPairsResult<E>N, function (type parameter) T in <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): AllPairsResult<E>T extends type Kind = "directed" | "undirected"Graph type for distinguishing directed and undirected graphs.
When to use
Use when writing graph-polymorphic types or helpers that need to preserve
whether a graph is directed or undirected.
Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>graph: interface Graph<out N, out E, T extends Kind = "directed">Immutable graph interface.
When to use
Use as the immutable graph model for code that queries, traverses,
transforms, or analyzes graph structure without mutating it.
Graph<function (type parameter) N in <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): AllPairsResult<E>N, function (type parameter) E in <E>(cost: (edgeData: E) => number): <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => AllPairsResult<E>E, function (type parameter) T in <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): AllPairsResult<E>T> | interface MutableGraph<out N, out E, T extends Kind = "directed">Mutable graph interface.
When to use
Use when adding, removing, or updating nodes and edges inside a graph
mutation scope.
MutableGraph<function (type parameter) N in <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): AllPairsResult<E>N, function (type parameter) E in <E>(cost: (edgeData: E) => number): <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => AllPairsResult<E>E, function (type parameter) T in <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>): AllPairsResult<E>T>) => interface AllPairsResult<E>Result of an all-pairs shortest path computation.
When to use
Use when storing or passing around the complete output of floydWarshall so
callers can look up shortest distances, node paths, and edge data for any
source and target node pair.
Details
Contains distance, node-path, and edge-data maps keyed by source and target
node indices.
AllPairsResult<function (type parameter) E in <E>(cost: (edgeData: E) => number): <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => AllPairsResult<E>E>
<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>T extends type Kind = "directed" | "undirected"Graph type for distinguishing directed and undirected graphs.
When to use
Use when writing graph-polymorphic types or helpers that need to preserve
whether a graph is directed or undirected.
Kind = "directed">(
graph: Graph<N, E, T> | MutableGraph<N, E, T>graph: interface Graph<out N, out E, T extends Kind = "directed">Immutable graph interface.
When to use
Use as the immutable graph model for code that queries, traverses,
transforms, or analyzes graph structure without mutating it.
Graph<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>T> | interface MutableGraph<out N, out E, T extends Kind = "directed">Mutable graph interface.
When to use
Use when adding, removing, or updating nodes and edges inside a graph
mutation scope.
MutableGraph<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>T>,
cost: (edgeData: E) => numbercost: (edgeData: EedgeData: function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>E) => number
): interface AllPairsResult<E>Result of an all-pairs shortest path computation.
When to use
Use when storing or passing around the complete output of floydWarshall so
callers can look up shortest distances, node paths, and edge data for any
source and target node pair.
Details
Contains distance, node-path, and edge-data maps keyed by source and target
node indices.
AllPairsResult<function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>E>
} = import dualdual(2, <function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>T extends type Kind = "directed" | "undirected"Graph type for distinguishing directed and undirected graphs.
When to use
Use when writing graph-polymorphic types or helpers that need to preserve
whether a graph is directed or undirected.
Kind = "directed">(
graph: Graph<N, E, T> | MutableGraph<N, E, T>graph: interface Graph<out N, out E, T extends Kind = "directed">Immutable graph interface.
When to use
Use as the immutable graph model for code that queries, traverses,
transforms, or analyzes graph structure without mutating it.
Graph<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>T> | interface MutableGraph<out N, out E, T extends Kind = "directed">Mutable graph interface.
When to use
Use when adding, removing, or updating nodes and edges inside a graph
mutation scope.
MutableGraph<function (type parameter) N in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>N, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>E, function (type parameter) T in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>T>,
cost: (edgeData: E) => numbercost: (edgeData: EedgeData: function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>E) => number
): interface AllPairsResult<E>Result of an all-pairs shortest path computation.
When to use
Use when storing or passing around the complete output of floydWarshall so
callers can look up shortest distances, node paths, and edge data for any
source and target node pair.
Details
Contains distance, node-path, and edge-data maps keyed by source and target
node indices.
AllPairsResult<function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>E> => {
// Get all nodes for Floyd-Warshall algorithm (needs array for nested iteration)
const const allNodes: number[]allNodes = var Array: ArrayConstructorArray.ArrayConstructor.from<number>(iterable: Iterable<number> | ArrayLike<number>): number[] (+3 overloads)Creates an array from an iterable object.
from(graph: Graph<N, E, T> | MutableGraph<N, E, T>graph.Proto<out N, out E>.nodes: Map<NodeIndex, N>nodes.Map<number, N>.keys(): MapIterator<number>Returns an iterable of keys in the map
keys())
// Initialize distance matrix
const const distances: Map<
number,
Map<number, number>
>
distances = new var Map: MapConstructor
new <number, Map<number, number>>(iterable?: Iterable<readonly [number, Map<number, number>]> | null | undefined) => Map<number, Map<number, number>> (+3 overloads)
Map<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex, interface Map<K, V>Map<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex, number>>()
const const next: Map<
number,
Map<number, number | null>
>
next = new var Map: MapConstructor
new <number, Map<number, number | null>>(iterable?: Iterable<readonly [number, Map<number, number | null>]> | null | undefined) => Map<number, Map<number, number | null>> (+3 overloads)
Map<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex, interface Map<K, V>Map<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex, type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex | null>>()
const const edgeMatrix: Map<
number,
Map<number, E | null>
>
edgeMatrix = new var Map: MapConstructor
new <number, Map<number, E | null>>(iterable?: Iterable<readonly [number, Map<number, E | null>]> | null | undefined) => Map<number, Map<number, E | null>> (+3 overloads)
Map<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex, interface Map<K, V>Map<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex, function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>E | null>>()
// Initialize with infinity for all pairs
for (const const i: numberi of const allNodes: number[]allNodes) {
const distances: Map<
number,
Map<number, number>
>
distances.Map<number, Map<number, number>>.set(key: number, value: Map<number, number>): Map<number, Map<number, number>>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const i: numberi, new var Map: MapConstructor
new () => Map<any, any> (+3 overloads)
Map())
const next: Map<
number,
Map<number, number | null>
>
next.Map<number, Map<number, number | null>>.set(key: number, value: Map<number, number | null>): Map<number, Map<number, number | null>>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const i: numberi, new var Map: MapConstructor
new () => Map<any, any> (+3 overloads)
Map())
const edgeMatrix: Map<
number,
Map<number, E | null>
>
edgeMatrix.Map<number, Map<number, E | null>>.set(key: number, value: Map<number, E | null>): Map<number, Map<number, E | null>>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const i: numberi, new var Map: MapConstructor
new () => Map<any, any> (+3 overloads)
Map())
for (const const j: numberj of const allNodes: number[]allNodes) {
const distances: Map<
number,
Map<number, number>
>
distances.Map<number, Map<number, number>>.get(key: number): Map<number, number> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, number>.set(key: number, value: number): Map<number, number>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: numberj, const i: numberi === const j: numberj ? 0 : var Infinity: numberInfinity)
const next: Map<
number,
Map<number, number | null>
>
next.Map<number, Map<number, number | null>>.get(key: number): Map<number, number | null> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, number | null>.set(key: number, value: number | null): Map<number, number | null>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: numberj, null)
const edgeMatrix: Map<
number,
Map<number, E | null>
>
edgeMatrix.Map<number, Map<number, E | null>>.get(key: number): Map<number, E | null> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, E | null>.set(key: number, value: E | null): Map<number, E | null>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: numberj, null)
}
}
// Set edge weights
for (const [, const edgeData: Edge<E>const edgeData: {
source: number;
target: number;
data: E;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
edgeData] of graph: Graph<N, E, T> | MutableGraph<N, E, T>graph.Proto<out N, out E>.edges: Map<EdgeIndex, Edge<E>>edges) {
const const weight: numberweight = cost: (edgeData: E) => numbercost(const edgeData: Edge<E>const edgeData: {
source: number;
target: number;
data: E;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
edgeData.data)
const const i: anyi = const edgeData: Edge<E>const edgeData: {
source: number;
target: number;
data: E;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
edgeData.source
const const j: anyj = const edgeData: Edge<E>const edgeData: {
source: number;
target: number;
data: E;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
edgeData.target
// Use minimum weight if multiple edges exist
const const currentWeight: numbercurrentWeight = const distances: Map<
number,
Map<number, number>
>
distances.Map<number, Map<number, number>>.get(key: number): Map<number, number> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: anyi)!.Map<number, number>.get(key: number): number | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const j: anyj)!
if (const weight: numberweight < const currentWeight: numbercurrentWeight) {
const distances: Map<
number,
Map<number, number>
>
distances.Map<number, Map<number, number>>.get(key: number): Map<number, number> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: anyi)!.Map<number, number>.set(key: number, value: number): Map<number, number>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: anyj, const weight: numberweight)
const next: Map<
number,
Map<number, number | null>
>
next.Map<number, Map<number, number | null>>.get(key: number): Map<number, number | null> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: anyi)!.Map<number, number | null>.set(key: number, value: number | null): Map<number, number | null>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: anyj, const j: anyj)
const edgeMatrix: Map<
number,
Map<number, E | null>
>
edgeMatrix.Map<number, Map<number, E | null>>.get(key: number): Map<number, E | null> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: anyi)!.Map<number, E | null>.set(key: number, value: E | null): Map<number, E | null>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: anyj, const edgeData: Edge<E>const edgeData: {
source: number;
target: number;
data: E;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
edgeData.data)
}
if (graph: Graph<N, E, T> | MutableGraph<N, E, T>graph.type: T extends Kind = "directed"type === "undirected") {
const const reverseWeight: numberreverseWeight = const distances: Map<
number,
Map<number, number>
>
distances.Map<number, Map<number, number>>.get(key: number): Map<number, number> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const j: anyj)!.Map<number, number>.get(key: number): number | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: anyi)!
if (const weight: numberweight < const reverseWeight: numberreverseWeight) {
const distances: Map<
number,
Map<number, number>
>
distances.Map<number, Map<number, number>>.get(key: number): Map<number, number> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const j: anyj)!.Map<number, number>.set(key: number, value: number): Map<number, number>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const i: anyi, const weight: numberweight)
const next: Map<
number,
Map<number, number | null>
>
next.Map<number, Map<number, number | null>>.get(key: number): Map<number, number | null> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const j: anyj)!.Map<number, number | null>.set(key: number, value: number | null): Map<number, number | null>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const i: anyi, const i: anyi)
const edgeMatrix: Map<
number,
Map<number, E | null>
>
edgeMatrix.Map<number, Map<number, E | null>>.get(key: number): Map<number, E | null> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const j: anyj)!.Map<number, E | null>.set(key: number, value: E | null): Map<number, E | null>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const i: anyi, const edgeData: Edge<E>const edgeData: {
source: number;
target: number;
data: E;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
edgeData.data)
}
}
}
// Floyd-Warshall main loop
for (const const k: numberk of const allNodes: number[]allNodes) {
for (const const i: numberi of const allNodes: number[]allNodes) {
for (const const j: numberj of const allNodes: number[]allNodes) {
const const distIK: numberdistIK = const distances: Map<
number,
Map<number, number>
>
distances.Map<number, Map<number, number>>.get(key: number): Map<number, number> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, number>.get(key: number): number | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const k: numberk)!
const const distKJ: numberdistKJ = const distances: Map<
number,
Map<number, number>
>
distances.Map<number, Map<number, number>>.get(key: number): Map<number, number> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const k: numberk)!.Map<number, number>.get(key: number): number | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const j: numberj)!
const const distIJ: numberdistIJ = const distances: Map<
number,
Map<number, number>
>
distances.Map<number, Map<number, number>>.get(key: number): Map<number, number> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, number>.get(key: number): number | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const j: numberj)!
if (const distIK: numberdistIK !== var Infinity: numberInfinity && const distKJ: numberdistKJ !== var Infinity: numberInfinity && const distIK: numberdistIK + const distKJ: numberdistKJ < const distIJ: numberdistIJ) {
const distances: Map<
number,
Map<number, number>
>
distances.Map<number, Map<number, number>>.get(key: number): Map<number, number> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, number>.set(key: number, value: number): Map<number, number>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: numberj, const distIK: numberdistIK + const distKJ: numberdistKJ)
const next: Map<
number,
Map<number, number | null>
>
next.Map<number, Map<number, number | null>>.get(key: number): Map<number, number | null> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, number | null>.set(key: number, value: number | null): Map<number, number | null>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: numberj, const next: Map<
number,
Map<number, number | null>
>
next.Map<number, Map<number, number | null>>.get(key: number): Map<number, number | null> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, number | null>.get(key: number): number | null | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const k: numberk)!)
}
}
}
}
// Check for negative cycles
for (const const i: numberi of const allNodes: number[]allNodes) {
if (const distances: Map<
number,
Map<number, number>
>
distances.Map<number, Map<number, number>>.get(key: number): Map<number, number> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, number>.get(key: number): number | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)! < 0) {
throw new constructor GraphError(): GraphErrorError thrown by graph operations when the requested graph structure is
invalid, such as referencing a missing node or using unsupported edge
weights.
When to use
Use when handling failures thrown by graph operations that reject invalid
graph structure or unsupported algorithm inputs.
GraphError({ message: stringmessage: `Negative cycle detected involving node ${const i: numberi}` })
}
}
// Build result paths and edge weights
const const paths: Map<
number,
Map<number, number[] | null>
>
paths = new var Map: MapConstructor
new <number, Map<number, number[] | null>>(iterable?: Iterable<readonly [number, Map<number, number[] | null>]> | null | undefined) => Map<number, Map<number, number[] | null>> (+3 overloads)
Map<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex, interface Map<K, V>Map<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex, interface Array<T>Array<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex> | null>>()
const const costs: Map<number, Map<number, E[]>>costs = new var Map: MapConstructor
new <number, Map<number, E[]>>(iterable?: Iterable<readonly [number, Map<number, E[]>]> | null | undefined) => Map<number, Map<number, E[]>> (+3 overloads)
Map<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex, interface Map<K, V>Map<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex, interface Array<T>Array<function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>E>>>()
for (const const i: numberi of const allNodes: number[]allNodes) {
const paths: Map<
number,
Map<number, number[] | null>
>
paths.Map<number, Map<number, number[] | null>>.set(key: number, value: Map<number, number[] | null>): Map<number, Map<number, number[] | null>>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const i: numberi, new var Map: MapConstructor
new () => Map<any, any> (+3 overloads)
Map())
const costs: Map<number, Map<number, E[]>>costs.Map<number, Map<number, E[]>>.set(key: number, value: Map<number, E[]>): Map<number, Map<number, E[]>>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const i: numberi, new var Map: MapConstructor
new () => Map<any, any> (+3 overloads)
Map())
for (const const j: numberj of const allNodes: number[]allNodes) {
if (const i: numberi === const j: numberj) {
const paths: Map<
number,
Map<number, number[] | null>
>
paths.Map<number, Map<number, number[] | null>>.get(key: number): Map<number, number[] | null> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, number[] | null>.set(key: number, value: number[] | null): Map<number, number[] | null>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: numberj, [const i: numberi])
const costs: Map<number, Map<number, E[]>>costs.Map<number, Map<number, E[]>>.get(key: number): Map<number, E[]> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, E[]>.set(key: number, value: E[]): Map<number, E[]>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: numberj, [])
} else if (const distances: Map<
number,
Map<number, number>
>
distances.Map<number, Map<number, number>>.get(key: number): Map<number, number> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, number>.get(key: number): number | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const j: numberj)! === var Infinity: numberInfinity) {
const paths: Map<
number,
Map<number, number[] | null>
>
paths.Map<number, Map<number, number[] | null>>.get(key: number): Map<number, number[] | null> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, number[] | null>.set(key: number, value: number[] | null): Map<number, number[] | null>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: numberj, null)
const costs: Map<number, Map<number, E[]>>costs.Map<number, Map<number, E[]>>.get(key: number): Map<number, E[]> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, E[]>.set(key: number, value: E[]): Map<number, E[]>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: numberj, [])
} else {
// Reconstruct path iteratively
const const path: Array<NodeIndex>path: interface Array<T>Array<type NodeIndex = numberNode index for node identification using plain numbers.
When to use
Use when storing or passing the stable identifier of a graph node between
Graph operations.
Details
addNode allocates node identifiers from the graph's next node index.
Gotchas
A NodeIndex is an identifier, not an array offset. Removed node identifiers
are not reused.
NodeIndex> = []
const const weights: E[]weights: interface Array<T>Array<function (type parameter) E in <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>E> = []
let let current: numbercurrent = const i: numberi
const path: Array<NodeIndex>path.Array<number>.push(...items: number[]): numberAppends new elements to the end of an array, and returns the new length of the array.
push(let current: numbercurrent)
while (let current: numbercurrent !== const j: numberj) {
const const nextNode: numbernextNode = const next: Map<
number,
Map<number, number | null>
>
next.Map<number, Map<number, number | null>>.get(key: number): Map<number, number | null> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(let current: numbercurrent)!.Map<number, number | null>.get(key: number): number | null | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const j: numberj)!
if (const nextNode: numbernextNode === null) break
const const edgeData: NonNullable<E>edgeData = const edgeMatrix: Map<
number,
Map<number, E | null>
>
edgeMatrix.Map<number, Map<number, E | null>>.get(key: number): Map<number, E | null> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(let current: numbercurrent)!.Map<number, E | null>.get(key: number): E | null | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const nextNode: numbernextNode)!
if (const edgeData: NonNullable<E>edgeData !== null) {
const weights: E[]weights.Array<E>.push(...items: E[]): numberAppends new elements to the end of an array, and returns the new length of the array.
push(const edgeData: NonNullable<E>edgeData)
}
let current: numbercurrent = const nextNode: numbernextNode
const path: Array<NodeIndex>path.Array<number>.push(...items: number[]): numberAppends new elements to the end of an array, and returns the new length of the array.
push(let current: numbercurrent)
}
const paths: Map<
number,
Map<number, number[] | null>
>
paths.Map<number, Map<number, number[] | null>>.get(key: number): Map<number, number[] | null> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, number[] | null>.set(key: number, value: number[] | null): Map<number, number[] | null>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: numberj, const path: Array<NodeIndex>path)
const costs: Map<number, Map<number, E[]>>costs.Map<number, Map<number, E[]>>.get(key: number): Map<number, E[]> | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const i: numberi)!.Map<number, E[]>.set(key: number, value: E[]): Map<number, E[]>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const j: numberj, const weights: E[]weights)
}
}
}
return {
AllPairsResult<E>.distances: Map<number, Map<number, number>>distances,
AllPairsResult<E>.paths: Map<number, Map<number, number[] | null>>paths,
AllPairsResult<E>.costs: Map<number, Map<number, E[]>>costs
}
})