<N, E>(
graph: Graph<N, E, "undirected"> | MutableGraph<N, E, "undirected">
): Array<Array<NodeIndex>>Finds connected components in an undirected graph. Each component is represented as an array of node indices.
Example (Finding connected components)
import { Graph } from "effect"
const graph = Graph.undirected<string, string>((mutable) => {
const a = Graph.addNode(mutable, "A")
const b = Graph.addNode(mutable, "B")
const c = Graph.addNode(mutable, "C")
const d = Graph.addNode(mutable, "D")
Graph.addEdge(mutable, a, b, "edge") // Component 1: A-B
Graph.addEdge(mutable, c, d, "edge") // Component 2: C-D
})
const components = Graph.connectedComponents(graph)
console.log(components) // [[0, 1], [2, 3]]export const const connectedComponents: <N, E>(
graph:
| Graph<N, E, "undirected">
| MutableGraph<N, E, "undirected">
) => Array<Array<NodeIndex>>
Finds connected components in an undirected graph.
Each component is represented as an array of node indices.
Example (Finding connected components)
import { Graph } from "effect"
const graph = Graph.undirected<string, string>((mutable) => {
const a = Graph.addNode(mutable, "A")
const b = Graph.addNode(mutable, "B")
const c = Graph.addNode(mutable, "C")
const d = Graph.addNode(mutable, "D")
Graph.addEdge(mutable, a, b, "edge") // Component 1: A-B
Graph.addEdge(mutable, c, d, "edge") // Component 2: C-D
})
const components = Graph.connectedComponents(graph)
console.log(components) // [[0, 1], [2, 3]]
connectedComponents = <function (type parameter) N in <N, E>(graph: Graph<N, E, "undirected"> | MutableGraph<N, E, "undirected">): Array<Array<NodeIndex>>N, function (type parameter) E in <N, E>(graph: Graph<N, E, "undirected"> | MutableGraph<N, E, "undirected">): Array<Array<NodeIndex>>E>(
graph: | Graph<N, E, "undirected">
| MutableGraph<N, E, "undirected">
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>(graph: Graph<N, E, "undirected"> | MutableGraph<N, E, "undirected">): Array<Array<NodeIndex>>N, function (type parameter) E in <N, E>(graph: Graph<N, E, "undirected"> | MutableGraph<N, E, "undirected">): Array<Array<NodeIndex>>E, "undirected"> | 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>(graph: Graph<N, E, "undirected"> | MutableGraph<N, E, "undirected">): Array<Array<NodeIndex>>N, function (type parameter) E in <N, E>(graph: Graph<N, E, "undirected"> | MutableGraph<N, E, "undirected">): Array<Array<NodeIndex>>E, "undirected">
): interface Array<T>Array<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 visited: Set<number>visited = new var Set: SetConstructor
new <number>(iterable?: Iterable<number> | null | undefined) => Set<number> (+1 overload)
Set<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 components: Array<Array<NodeIndex>>components: interface Array<T>Array<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>> = []
for (const const startNode: numberstartNode of graph: | Graph<N, E, "undirected">
| MutableGraph<N, E, "undirected">
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()) {
if (!const visited: Set<number>visited.Set<number>.has(value: number): booleanhas(const startNode: numberstartNode)) {
// DFS to find all nodes in this component
const const component: Array<NodeIndex>component: 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 stack: Array<NodeIndex>stack: 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 startNode: numberstartNode]
while (const stack: Array<NodeIndex>stack.Array<number>.length: numberGets or sets the length of the array. This is a number one higher than the highest index in the array.
length > 0) {
const const current: numbercurrent = const stack: Array<NodeIndex>stack.Array<number>.pop(): number | undefinedRemoves the last element from an array and returns it.
If the array is empty, undefined is returned and the array is not modified.
pop()!
if (!const visited: Set<number>visited.Set<number>.has(value: number): booleanhas(const current: numbercurrent)) {
const visited: Set<number>visited.Set<number>.add(value: number): Set<number>Appends a new element with a specified value to the end of the Set.
add(const current: numbercurrent)
const component: Array<NodeIndex>component.Array<number>.push(...items: number[]): numberAppends new elements to the end of an array, and returns the new length of the array.
push(const current: numbercurrent)
// Add all unvisited neighbors to stack
const const nodeNeighbors: number[]nodeNeighbors = const getUndirectedNeighbors: <N, E>(
graph:
| Graph<N, E, "undirected">
| MutableGraph<N, E, "undirected">,
nodeIndex: NodeIndex
) => Array<NodeIndex>
Get neighbors for undirected graphs by checking both adjacency and reverse adjacency.
For undirected graphs, we need to find the other endpoint of each edge incident to the node.
getUndirectedNeighbors(graph: | Graph<N, E, "undirected">
| MutableGraph<N, E, "undirected">
graph, const current: numbercurrent)
for (const const neighbor: numberneighbor of const nodeNeighbors: number[]nodeNeighbors) {
if (!const visited: Set<number>visited.Set<number>.has(value: number): booleanhas(const neighbor: numberneighbor)) {
const stack: Array<NodeIndex>stack.Array<number>.push(...items: number[]): numberAppends new elements to the end of an array, and returns the new length of the array.
push(const neighbor: numberneighbor)
}
}
}
}
const components: Array<Array<NodeIndex>>components.Array<number[]>.push(...items: number[][]): numberAppends new elements to the end of an array, and returns the new length of the array.
push(const component: Array<NodeIndex>component)
}
}
return const components: Array<Array<NodeIndex>>components
}