@statelyai/graph 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -19
- package/dist/{algorithms-CsGNehct.d.mts → algorithms-D1cgly0g.d.mts} +145 -6
- package/dist/{algorithms-DF1pSQGv.mjs → algorithms-DBpH74hR.mjs} +673 -891
- package/dist/algorithms.d.mts +2 -2
- package/dist/algorithms.mjs +2 -2
- package/dist/config-Dt5u1gSf.mjs +793 -0
- package/dist/{converter-DyCJJfTe.mjs → converter-DB6Rg6Vd.mjs} +2 -2
- package/dist/formats/adjacency-list/index.d.mts +1 -1
- package/dist/formats/adjacency-list/index.mjs +1 -1
- package/dist/formats/converter/index.d.mts +1 -1
- package/dist/formats/converter/index.mjs +1 -1
- package/dist/formats/cytoscape/index.d.mts +4 -4
- package/dist/formats/cytoscape/index.mjs +8 -4
- package/dist/formats/d2/index.d.mts +1 -1
- package/dist/formats/d2/index.mjs +1 -1
- package/dist/formats/d3/index.d.mts +4 -4
- package/dist/formats/d3/index.mjs +8 -4
- package/dist/formats/dot/index.d.mts +1 -1
- package/dist/formats/dot/index.mjs +1 -1
- package/dist/formats/edge-list/index.d.mts +1 -1
- package/dist/formats/edge-list/index.mjs +1 -1
- package/dist/formats/elk/index.d.mts +1 -1
- package/dist/formats/elk/index.mjs +43 -11
- package/dist/formats/gexf/index.d.mts +1 -1
- package/dist/formats/gexf/index.mjs +22 -2
- package/dist/formats/gml/index.d.mts +4 -4
- package/dist/formats/gml/index.mjs +8 -4
- package/dist/formats/graphml/index.d.mts +1 -1
- package/dist/formats/graphml/index.mjs +24 -2
- package/dist/formats/jgf/index.d.mts +4 -4
- package/dist/formats/jgf/index.mjs +8 -4
- package/dist/formats/mermaid/index.d.mts +1 -1
- package/dist/formats/mermaid/index.mjs +1 -1
- package/dist/formats/tgf/index.d.mts +4 -4
- package/dist/formats/tgf/index.mjs +4 -4
- package/dist/formats/xyflow/index.d.mts +12 -6
- package/dist/formats/xyflow/index.mjs +11 -6
- package/dist/{index-D51lJnt2.d.mts → index-BlbSWUvH.d.mts} +1 -1
- package/dist/{index-DWmo1mIp.d.mts → index-CNvqxPLJ.d.mts} +82 -14
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +152 -17
- package/dist/layout/cytoscape.d.mts +66 -0
- package/dist/layout/cytoscape.mjs +114 -0
- package/dist/layout/d3-force.d.mts +52 -0
- package/dist/layout/d3-force.mjs +127 -0
- package/dist/layout/d3-hierarchy.d.mts +39 -0
- package/dist/layout/d3-hierarchy.mjs +135 -0
- package/dist/layout/dagre.d.mts +32 -0
- package/dist/layout/dagre.mjs +99 -0
- package/dist/layout/elk.d.mts +47 -0
- package/dist/layout/elk.mjs +73 -0
- package/dist/layout/forceatlas2.d.mts +48 -0
- package/dist/layout/forceatlas2.mjs +100 -0
- package/dist/layout/graphviz.d.mts +50 -0
- package/dist/layout/graphviz.mjs +179 -0
- package/dist/layout/index.d.mts +185 -0
- package/dist/layout/index.mjs +181 -0
- package/dist/layout/webcola.d.mts +40 -0
- package/dist/layout/webcola.mjs +104 -0
- package/dist/{queries-BfXeTXRf.d.mts → queries-B6quF529.d.mts} +1 -1
- package/dist/{queries-KirMDR7e.mjs → queries-BMM0XAv_.mjs} +23 -17
- package/dist/queries.d.mts +1 -1
- package/dist/queries.mjs +1 -1
- package/dist/schemas.d.mts +19 -1
- package/dist/schemas.mjs +10 -1
- package/dist/{types-DNYdIU21.d.mts → types-BAEQTwK_.d.mts} +46 -3
- package/package.json +47 -5
- package/schemas/edge.schema.json +27 -0
- package/schemas/graph.schema.json +27 -0
- /package/dist/{adjacency-list-GeL1Cu-L.mjs → adjacency-list-DQ32Mmhx.mjs} +0 -0
- /package/dist/{edge-list-BcZ0h6zz.mjs → edge-list-CA9UTvn2.mjs} +0 -0
- /package/dist/{mode-D8OnHFBk.mjs → mode-gu_mhKKs.mjs} +0 -0
- /package/dist/{validate-TtH-x3JV.mjs → validate-BsfSOv0S.mjs} +0 -0
package/README.md
CHANGED
|
@@ -14,14 +14,19 @@ Optional peers are only needed for specific adapters:
|
|
|
14
14
|
|
|
15
15
|
<!-- optional peer dependencies derived from package.json#peerDependencies -->
|
|
16
16
|
|
|
17
|
-
| Package
|
|
18
|
-
|
|
|
19
|
-
| `fast-xml-parser`
|
|
20
|
-
| `dotparser`
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
24
|
-
| `
|
|
17
|
+
| Package | Needed for |
|
|
18
|
+
| ------------------------------------------- | --------------------------------------------------- |
|
|
19
|
+
| `fast-xml-parser` | `@statelyai/graph/gexf`, `@statelyai/graph/graphml` |
|
|
20
|
+
| `dotparser` | `@statelyai/graph/dot` parsing |
|
|
21
|
+
| `zod` | `@statelyai/graph/schemas` |
|
|
22
|
+
| `elkjs` | `@statelyai/graph/elk`, `@statelyai/graph/layout/elk` |
|
|
23
|
+
| `@dagrejs/dagre` | `@statelyai/graph/layout/dagre` |
|
|
24
|
+
| `@hpcc-js/wasm-graphviz` | `@statelyai/graph/layout/graphviz` |
|
|
25
|
+
| `d3-force` | `@statelyai/graph/layout/d3-force` |
|
|
26
|
+
| `graphology`, `graphology-layout-forceatlas2` | `@statelyai/graph/layout/forceatlas2` |
|
|
27
|
+
| `d3-hierarchy` | `@statelyai/graph/layout/d3-hierarchy` |
|
|
28
|
+
| `webcola` | `@statelyai/graph/layout/webcola` |
|
|
29
|
+
| `cytoscape` | `@statelyai/graph/layout/cytoscape`, Cytoscape format typing |
|
|
25
30
|
|
|
26
31
|
## Highlights
|
|
27
32
|
|
|
@@ -29,7 +34,8 @@ Optional peers are only needed for specific adapters:
|
|
|
29
34
|
- Standalone functions with a consistent `get*`/`gen*`/`is*`/`add*` naming model
|
|
30
35
|
- Directed, undirected, hierarchical, and visual graph support
|
|
31
36
|
- Ports for node-editor and dataflow-style graphs
|
|
32
|
-
- Algorithms for traversal, paths, centrality, communities, connectivity, isomorphism, ordering, MST, and walks
|
|
37
|
+
- Algorithms for traversal, paths, centrality, communities, connectivity, flow/cuts, matching, cores, isomorphism, ordering, MST, and walks
|
|
38
|
+
- Pluggable layout over eight external engines (ELK, Graphviz, dagre, d3-force, ForceAtlas2, tidy tree, WebCola, cytoscape) — pure functions, optional peers
|
|
33
39
|
- Diff/patch utilities for graph state changes
|
|
34
40
|
- Multi-format conversion via package subpaths, with fidelity claims tested against fixtures
|
|
35
41
|
- Small, fast test suite with broad format coverage
|
|
@@ -96,10 +102,10 @@ updateNode(graph, 'a', { color: null }); // unset
|
|
|
96
102
|
|
|
97
103
|
## Hierarchy
|
|
98
104
|
|
|
99
|
-
Nodes support parent-child relationships for compound/nested graphs. Query children, ancestors, descendants, depth, and least common ancestor. Use `
|
|
105
|
+
Nodes support parent-child relationships for compound/nested graphs. Query children, ancestors, descendants, depth, and least common ancestor. Use `getFlattenedGraph()` to decompose into a flat leaf-node graph.
|
|
100
106
|
|
|
101
107
|
```ts
|
|
102
|
-
import { createGraph, getChildren, getLCA,
|
|
108
|
+
import { createGraph, getChildren, getLCA, getFlattenedGraph } from '@statelyai/graph';
|
|
103
109
|
|
|
104
110
|
const graph = createGraph({
|
|
105
111
|
nodes: [
|
|
@@ -117,7 +123,7 @@ const graph = createGraph({
|
|
|
117
123
|
});
|
|
118
124
|
|
|
119
125
|
const children = getChildren(graph, 'b'); // [b1, b2]
|
|
120
|
-
const flat =
|
|
126
|
+
const flat = getFlattenedGraph(graph); // only leaf nodes, edges resolved
|
|
121
127
|
```
|
|
122
128
|
|
|
123
129
|
## Ports
|
|
@@ -188,14 +194,14 @@ const parsed = GraphSchema.parse(unknownValue);
|
|
|
188
194
|
|
|
189
195
|
<!-- algorithm functions exported from src/algorithms.ts -->
|
|
190
196
|
|
|
191
|
-
Includes traversal (BFS, DFS, preorder/postorder), pathfinding (shortest path, simple paths, all-pairs shortest paths, A
|
|
197
|
+
Includes traversal (BFS, DFS, preorder/postorder), pathfinding (shortest path, simple paths, all-pairs shortest paths, A*, bidirectional Dijkstra), centrality/link analysis (degree, closeness, betweenness, PageRank, HITS, eigenvector, Katz), community detection (Louvain, label propagation, Girvan-Newman, greedy modularity, modularity scoring), flow & cuts (`getMaxFlow`, `getMinCut`), bipartite analysis (`isBipartite`, Hopcroft–Karp `getMaximumBipartiteMatching`), k-cores (`getCoreNumbers`, `getKCore`), cycle detection, connected/strongly-connected components, bridges, articulation points, biconnected components, dominator trees, transitive reduction, isomorphism, topological sort, minimum spanning tree, and seeded graph generators (`createCompleteGraph`, `createGridGraph`, `createRandomGraph`). Many algorithms have lazy generator variants (`gen*`) for early exit. See [docs/algorithms.md](./docs/algorithms.md) for the full reference.
|
|
192
198
|
|
|
193
199
|
Hot algorithm loops (centrality, components) run on an internal compressed-sparse-row snapshot — cached and invalidated transparently like the rest of the index — so they stay fast on large graphs without changing the plain-JSON model. Algorithm results are differential-tested against graphology on seeded random graphs.
|
|
194
200
|
|
|
195
201
|
```ts
|
|
196
202
|
import {
|
|
197
|
-
|
|
198
|
-
|
|
203
|
+
genBFS,
|
|
204
|
+
genDFS,
|
|
199
205
|
hasPath,
|
|
200
206
|
isAcyclic,
|
|
201
207
|
getShortestPath,
|
|
@@ -214,10 +220,10 @@ import {
|
|
|
214
220
|
isIsomorphic,
|
|
215
221
|
} from '@statelyai/graph';
|
|
216
222
|
|
|
217
|
-
for (const node of
|
|
223
|
+
for (const node of genBFS(graph, 'a')) {
|
|
218
224
|
/* breadth-first */
|
|
219
225
|
}
|
|
220
|
-
for (const node of
|
|
226
|
+
for (const node of genDFS(graph, 'a')) {
|
|
221
227
|
/* depth-first */
|
|
222
228
|
}
|
|
223
229
|
|
|
@@ -238,13 +244,44 @@ getTransitiveReduction(graph); // minimal equivalent DAG
|
|
|
238
244
|
isIsomorphic(graph, otherGraph); // structural equivalence
|
|
239
245
|
```
|
|
240
246
|
|
|
247
|
+
## Layout
|
|
248
|
+
|
|
249
|
+
<!-- layout adapters under src/layout/*.ts and helpers exported from src/layout/index.ts -->
|
|
250
|
+
|
|
251
|
+
Plug-and-play layout over external engines — pure functions in, positioned `VisualGraph` out. No layout algorithms of our own; each adapter is a subpath with an optional peer dependency. The hierarchical engines (ELK, dagre, Graphviz) also produce routed edge `points` and computed edge-label rects; the physics/tree/cytoscape engines position nodes only.
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
import { getElkLayout } from '@statelyai/graph/layout/elk'; // elkjs
|
|
255
|
+
import { getDagreLayout } from '@statelyai/graph/layout/dagre'; // @dagrejs/dagre
|
|
256
|
+
import { getGraphvizLayout } from '@statelyai/graph/layout/graphviz'; // @hpcc-js/wasm-graphviz (8 engines)
|
|
257
|
+
import { genForceLayout } from '@statelyai/graph/layout/d3-force'; // d3-force
|
|
258
|
+
import { getForceAtlas2Layout } from '@statelyai/graph/layout/forceatlas2'; // graphology FA2
|
|
259
|
+
import { getTidyTreeLayout } from '@statelyai/graph/layout/d3-hierarchy'; // d3-hierarchy
|
|
260
|
+
import { getColaLayout } from '@statelyai/graph/layout/webcola'; // webcola (constraints)
|
|
261
|
+
import { getCytoscapeLayout } from '@statelyai/graph/layout/cytoscape'; // cytoscape ecosystem
|
|
262
|
+
import { applyLayoutFrame, getLayoutBounds, centerGraph } from '@statelyai/graph/layout';
|
|
263
|
+
|
|
264
|
+
const laidOut = await getElkLayout(graph, {
|
|
265
|
+
measure: (node) => measureText(node.label), // text measurement stays yours
|
|
266
|
+
constraints: { layer: (node) => node.data?.tier }, // portable layer constraint
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// Physics layouts are generators — one tick per frame, cancel by stopping
|
|
270
|
+
for (const frame of genForceLayout(graph, { seed: 42 })) {
|
|
271
|
+
applyLayoutFrame(graph, frame);
|
|
272
|
+
render(graph);
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Edge `x`/`y`/`width`/`height` are canonically the edge-label rect; routes live in `edge.points` (`routing` says how to interpret them). Layouts are plain JSON — tween between engines with `genLayoutTransition`, or diff them with `getPatches`. See [docs/layout.md](./docs/layout.md) and [docs/layout-transitions.md](./docs/layout-transitions.md).
|
|
277
|
+
|
|
241
278
|
## Diff & Walks
|
|
242
279
|
|
|
243
280
|
Beyond classic graph algorithms, the library also includes utilities for evolving and exploring graph state:
|
|
244
281
|
|
|
245
|
-
- `getDiff()`, `getPatches()`, `
|
|
282
|
+
- `getDiff()`, `getPatches()`, `updateGraphWithPatches()` for graph change tracking
|
|
246
283
|
- `genRandomWalk()`, `genWeightedRandomWalk()`, and coverage helpers for model-based testing and simulation
|
|
247
|
-
- `getSubgraph()` and `
|
|
284
|
+
- `getSubgraph()` and `getReversedGraph()` for structural transforms
|
|
248
285
|
|
|
249
286
|
## Visual Graphs
|
|
250
287
|
|
|
@@ -347,6 +384,17 @@ Format-specific docs live alongside the source:
|
|
|
347
384
|
- [xyflow](./src/formats/xyflow/README.md)
|
|
348
385
|
- [Converter helpers](./src/formats/converter/README.md)
|
|
349
386
|
|
|
387
|
+
## Guides
|
|
388
|
+
|
|
389
|
+
<!-- guide documents under docs/*.md -->
|
|
390
|
+
|
|
391
|
+
- [Layout guide](./docs/layout.md) — the adapter contract, all eight engines, constraints, sizing, web workers
|
|
392
|
+
- [Layout transitions](./docs/layout-transitions.md) — tween between engines; layouts are just data
|
|
393
|
+
- [Algorithms reference](./docs/algorithms.md) — every algorithm with complexity and semantics notes
|
|
394
|
+
- [Benchmarks](./docs/benchmarks.md) — measured against graphology, ngraph, graphlib, and cytoscape
|
|
395
|
+
- [Migrating from graphlib](./docs/migrating-from-graphlib.md)
|
|
396
|
+
- [React Flow + ELK pipeline](./docs/react-flow-elk-pipeline.md) — measured nodes, worker layout, live re-layout
|
|
397
|
+
|
|
350
398
|
## Examples
|
|
351
399
|
|
|
352
400
|
<!-- runnable example files under examples/ -->
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { M as SinglePathOptions, O as PathOptions, P as TraversalOptions, f as Graph, h as GraphEdge, n as AllPairsShortestPathsOptions, t as AStarOptions, w as MSTOptions, x as GraphPath, y as GraphNode } from "./types-BAEQTwK_.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/algorithms/traversal.d.ts
|
|
4
|
+
declare function genBFS<N>(graph: Graph<N>, startId: string): Generator<GraphNode<N>>;
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated Use {@link genBFS}.
|
|
7
|
+
*/
|
|
4
8
|
declare function bfs<N>(graph: Graph<N>, startId: string): Generator<GraphNode<N>>;
|
|
9
|
+
declare function genDFS<N>(graph: Graph<N>, startId: string): Generator<GraphNode<N>>;
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated Use {@link genDFS}.
|
|
12
|
+
*/
|
|
5
13
|
declare function dfs<N>(graph: Graph<N>, startId: string): Generator<GraphNode<N>>;
|
|
6
14
|
declare function isAcyclic(graph: Graph): boolean;
|
|
7
15
|
declare function getConnectedComponents<N>(graph: Graph<N>): GraphNode<N>[][];
|
|
@@ -35,6 +43,10 @@ declare function getCycles<N, E>(graph: Graph<N, E>): GraphPath<N, E>[];
|
|
|
35
43
|
declare function genCycles<N, E>(graph: Graph<N, E>): Generator<GraphPath<N, E>>;
|
|
36
44
|
declare function getAllPairsShortestPaths<N, E>(graph: Graph<N, E>, opts?: AllPairsShortestPathsOptions<E>): GraphPath<N, E>[];
|
|
37
45
|
declare function getAStarPath<N, E>(graph: Graph<N, E>, opts: AStarOptions<E>): GraphPath<N, E> | undefined;
|
|
46
|
+
declare function getJoinedPath<N, E>(headPath: GraphPath<N, E>, tailPath: GraphPath<N, E>): GraphPath<N, E>;
|
|
47
|
+
/**
|
|
48
|
+
* @deprecated Use {@link getJoinedPath}.
|
|
49
|
+
*/
|
|
38
50
|
declare function joinPaths<N, E>(headPath: GraphPath<N, E>, tailPath: GraphPath<N, E>): GraphPath<N, E>;
|
|
39
51
|
//#endregion
|
|
40
52
|
//#region src/algorithms/ordering.d.ts
|
|
@@ -54,6 +66,16 @@ interface IterativeCentralityOptions {
|
|
|
54
66
|
maxIterations?: number;
|
|
55
67
|
tolerance?: number;
|
|
56
68
|
}
|
|
69
|
+
interface EigenvectorCentralityOptions<E = any> extends IterativeCentralityOptions {
|
|
70
|
+
/** Edge weight accessor. Defaults to unweighted (every edge counts 1). */
|
|
71
|
+
getWeight?: (edge: GraphEdge<E>) => number;
|
|
72
|
+
}
|
|
73
|
+
interface KatzCentralityOptions<E = any> extends IterativeCentralityOptions {
|
|
74
|
+
/** Constant added to every node each iteration. Defaults to `1`. */
|
|
75
|
+
beta?: number;
|
|
76
|
+
/** Edge weight accessor. Defaults to unweighted (every edge counts 1). */
|
|
77
|
+
getWeight?: (edge: GraphEdge<E>) => number;
|
|
78
|
+
}
|
|
57
79
|
interface HITSResult {
|
|
58
80
|
hubs: Record<string, number>;
|
|
59
81
|
authorities: Record<string, number>;
|
|
@@ -111,10 +133,81 @@ declare function getHITS(graph: Graph, options?: IterativeCentralityOptions): HI
|
|
|
111
133
|
/**
|
|
112
134
|
* Returns eigenvector centrality scores for all nodes.
|
|
113
135
|
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
136
|
+
* Power iteration with the `A + I` shift (same scheme as graphology and
|
|
137
|
+
* networkx, so bipartite structures converge instead of oscillating).
|
|
138
|
+
* Scores flow along edge direction: a node's score is fed by its incoming
|
|
139
|
+
* neighbors; undirected edges feed both endpoints. The result vector is
|
|
140
|
+
* Euclidean (L2) normalized.
|
|
141
|
+
*
|
|
142
|
+
* Throws when the iteration has not converged (L1 error < `n × tolerance`)
|
|
143
|
+
* within `maxIterations`.
|
|
144
|
+
*/
|
|
145
|
+
declare function getEigenvectorCentrality<N, E>(graph: Graph<N, E>, options?: EigenvectorCentralityOptions<E>): Record<string, number>;
|
|
146
|
+
/**
|
|
147
|
+
* Returns Katz centrality scores for all nodes.
|
|
148
|
+
*
|
|
149
|
+
* Iterates `x' = alpha · Aᵀx + beta` to its fixed point (networkx-style),
|
|
150
|
+
* then Euclidean (L2) normalizes the result. Scores flow along edge
|
|
151
|
+
* direction: a node's score is fed by its incoming neighbors; undirected
|
|
152
|
+
* edges feed both endpoints.
|
|
153
|
+
*
|
|
154
|
+
* Converges only when `alpha` is below the reciprocal of the largest
|
|
155
|
+
* eigenvalue of the adjacency matrix; throws when the iteration has not
|
|
156
|
+
* converged (L1 error < `n × tolerance`) within `maxIterations`.
|
|
157
|
+
*/
|
|
158
|
+
declare function getKatzCentrality<N, E>(graph: Graph<N, E>, options?: KatzCentralityOptions<E>): Record<string, number>;
|
|
159
|
+
//#endregion
|
|
160
|
+
//#region src/algorithms/cores.d.ts
|
|
161
|
+
/**
|
|
162
|
+
* Returns the core number of every node (largest `k` such that the node
|
|
163
|
+
* belongs to the k-core).
|
|
164
|
+
*
|
|
165
|
+
* Uses Batagelj–Zaveršnik bucket peeling — O(m). Edges are treated as
|
|
166
|
+
* undirected (the standard k-core definition); self-loops are ignored.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```ts
|
|
170
|
+
* const cores = getCoreNumbers(graph);
|
|
171
|
+
* console.log(cores.a); // 3
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
declare function getCoreNumbers(graph: Graph): Record<string, number>;
|
|
175
|
+
/**
|
|
176
|
+
* Returns the ids of all nodes in the k-core: the maximal subgraph in which
|
|
177
|
+
* every node has at least `k` neighbors (edges treated as undirected).
|
|
178
|
+
*
|
|
179
|
+
* Node order follows `graph.nodes`. `k <= 0` returns every node id.
|
|
116
180
|
*/
|
|
117
|
-
declare function
|
|
181
|
+
declare function getKCore(graph: Graph, k: number): string[];
|
|
182
|
+
//#endregion
|
|
183
|
+
//#region src/algorithms/bipartite.d.ts
|
|
184
|
+
interface BipartiteMatch {
|
|
185
|
+
/** Source node id of the matched edge (as stored on the edge). */
|
|
186
|
+
sourceId: string;
|
|
187
|
+
/** Target node id of the matched edge (as stored on the edge). */
|
|
188
|
+
targetId: string;
|
|
189
|
+
/** Id of the edge realizing the match. */
|
|
190
|
+
edgeId: string;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Returns whether the graph is bipartite (2-colorable).
|
|
194
|
+
*
|
|
195
|
+
* Edges are treated as undirected; self-loops make a graph non-bipartite.
|
|
196
|
+
* Runs a BFS 2-coloring per connected component — O(n + m).
|
|
197
|
+
*/
|
|
198
|
+
declare function isBipartite(graph: Graph): boolean;
|
|
199
|
+
/**
|
|
200
|
+
* Returns a maximum-cardinality matching of a bipartite graph using
|
|
201
|
+
* Hopcroft–Karp — O(m·√n).
|
|
202
|
+
*
|
|
203
|
+
* The bipartition is derived by 2-coloring (edges treated as undirected).
|
|
204
|
+
* Each match reports the realizing edge with its stored `sourceId`/
|
|
205
|
+
* `targetId` orientation; for parallel edges between a matched pair, the
|
|
206
|
+
* first edge used by the algorithm is reported.
|
|
207
|
+
*
|
|
208
|
+
* Throws if the graph is not bipartite, naming the offending edge.
|
|
209
|
+
*/
|
|
210
|
+
declare function getMaximumBipartiteMatching(graph: Graph): BipartiteMatch[];
|
|
118
211
|
//#endregion
|
|
119
212
|
//#region src/algorithms/community.d.ts
|
|
120
213
|
interface GirvanNewmanOptions {
|
|
@@ -123,13 +216,21 @@ interface GirvanNewmanOptions {
|
|
|
123
216
|
}
|
|
124
217
|
interface LabelPropagationOptions {
|
|
125
218
|
maxIterations?: number;
|
|
219
|
+
/**
|
|
220
|
+
* When provided, runs *asynchronous* label propagation with a shuffled
|
|
221
|
+
* node order per round and random tie-breaking, seeded with mulberry32 —
|
|
222
|
+
* deterministic per seed. Without a seed, ties break lexicographically.
|
|
223
|
+
*/
|
|
224
|
+
seed?: number;
|
|
126
225
|
}
|
|
127
226
|
type Community<N = any> = GraphNode<N>[];
|
|
128
227
|
/**
|
|
129
228
|
* Returns label-propagation communities for the graph.
|
|
130
229
|
*
|
|
131
230
|
* The implementation is deterministic: ties are broken by lexicographic label
|
|
132
|
-
* order so test results remain stable.
|
|
231
|
+
* order so test results remain stable. Pass `options.seed` for the classic
|
|
232
|
+
* asynchronous variant (shuffled node order per round, random tie-breaking)
|
|
233
|
+
* — still deterministic per seed.
|
|
133
234
|
*/
|
|
134
235
|
declare function getLabelPropagationCommunities<N>(graph: Graph<N>, options?: LabelPropagationOptions): Community<N>[];
|
|
135
236
|
/**
|
|
@@ -238,6 +339,25 @@ interface MaxFlowResult<E = any> {
|
|
|
238
339
|
/** Edges in the minimum cut (max-flow-min-cut theorem). */
|
|
239
340
|
cutEdges: GraphEdge<E>[];
|
|
240
341
|
}
|
|
342
|
+
interface MinCutOptions<E = any> {
|
|
343
|
+
/** Source node id. */
|
|
344
|
+
source: string;
|
|
345
|
+
/** Sink node id. */
|
|
346
|
+
sink: string;
|
|
347
|
+
/** Edge capacity accessor. Defaults to `edge.weight ?? 1`. */
|
|
348
|
+
getCapacity?: (edge: GraphEdge<E>) => number;
|
|
349
|
+
}
|
|
350
|
+
interface MinCutResult {
|
|
351
|
+
/** Total capacity of the cut (equals the max-flow value). */
|
|
352
|
+
value: number;
|
|
353
|
+
/** Ids of the edges crossing the cut. */
|
|
354
|
+
cutEdges: string[];
|
|
355
|
+
/** Node ids on each side of the cut, in `graph.nodes` order. */
|
|
356
|
+
partition: {
|
|
357
|
+
source: string[];
|
|
358
|
+
sink: string[];
|
|
359
|
+
};
|
|
360
|
+
}
|
|
241
361
|
/**
|
|
242
362
|
* Returns the maximum flow from `from` to `to` using the Edmonds-Karp
|
|
243
363
|
* algorithm (BFS augmenting paths).
|
|
@@ -257,6 +377,25 @@ interface MaxFlowResult<E = any> {
|
|
|
257
377
|
* ```
|
|
258
378
|
*/
|
|
259
379
|
declare function getMaxFlow<N, E>(graph: Graph<N, E>, options: MaxFlowOptions<E>): MaxFlowResult<E>;
|
|
380
|
+
/**
|
|
381
|
+
* Returns a minimum s-t cut between `source` and `sink` via the max-flow
|
|
382
|
+
* min-cut theorem: runs the same Edmonds-Karp solver as {@link getMaxFlow},
|
|
383
|
+
* then splits the nodes by residual reachability from the source.
|
|
384
|
+
*
|
|
385
|
+
* `partition.source` holds every node reachable from `source` in the final
|
|
386
|
+
* residual graph; `partition.sink` holds the rest (both in `graph.nodes`
|
|
387
|
+
* order). `cutEdges` are the ids of the edges crossing the cut, and their
|
|
388
|
+
* total capacity equals `value` (the max-flow value).
|
|
389
|
+
*
|
|
390
|
+
* @example
|
|
391
|
+
* ```ts
|
|
392
|
+
* const { value, cutEdges, partition } = getMinCut(graph, {
|
|
393
|
+
* source: 's',
|
|
394
|
+
* sink: 't',
|
|
395
|
+
* });
|
|
396
|
+
* ```
|
|
397
|
+
*/
|
|
398
|
+
declare function getMinCut<N, E>(graph: Graph<N, E>, options: MinCutOptions<E>): MinCutResult;
|
|
260
399
|
//#endregion
|
|
261
400
|
//#region src/algorithms/dominators.d.ts
|
|
262
401
|
interface DominatorTreeOptions {
|
|
@@ -310,4 +449,4 @@ declare function getDominatorTree(graph: Graph, options?: DominatorTreeOptions):
|
|
|
310
449
|
*/
|
|
311
450
|
declare function getTransitiveReduction<N, E, G, P>(graph: Graph<N, E, G, P>): Graph<N, E, G, P>;
|
|
312
451
|
//#endregion
|
|
313
|
-
export {
|
|
452
|
+
export { getAllPairsShortestPaths as $, HITSResult as A, getOutDegreeCentrality as B, getModularity as C, getCoreNumbers as D, isBipartite as E, getDegreeCentrality as F, getPostorder as G, getMinimumSpanningTree as H, getEigenvectorCentrality as I, getPreorders as J, getPostorders as K, getHITS as L, KatzCentralityOptions as M, getBetweennessCentrality as N, getKCore as O, getClosenessCentrality as P, getAStarPath as Q, getInDegreeCentrality as R, getLabelPropagationCommunities as S, getMaximumBipartiteMatching as T, genPostorders as U, getPageRank as V, genPreorders as W, genShortestPaths as X, genCycles as Y, genSimplePaths as Z, GirvanNewmanOptions as _, isTree as _t, MaxFlowResult as a, getSimplePaths as at, getGirvanNewmanCommunities as b, getMaxFlow as c, bfs as ct, getLouvainCommunities as d, genDFS as dt, getCycles as et, IsomorphismOptions as f, getConnectedComponents as ft, getBridges as g, isConnected as gt, getBiconnectedComponents as h, isAcyclic as ht, MaxFlowOptions as i, getSimplePath as it, IterativeCentralityOptions as j, EigenvectorCentralityOptions as k, getMinCut as l, dfs as lt, getArticulationPoints as m, hasPath as mt, DominatorTreeOptions as n, getShortestPath as nt, MinCutOptions as o, getStronglyConnectedComponents as ot, isIsomorphic as p, getTopologicalSort as pt, getPreorder as q, getDominatorTree as r, getShortestPaths as rt, MinCutResult as s, joinPaths as st, getTransitiveReduction as t, getJoinedPath as tt, LouvainOptions as u, genBFS as ut, LabelPropagationOptions as v, BipartiteMatch as w, getGreedyModularityCommunities as x, genGirvanNewmanCommunities as y, getKatzCentrality as z };
|