@graphty/algorithms 1.0.1 → 1.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 +827 -60
- package/dist/algorithms.d.ts +2 -0
- package/dist/algorithms.d.ts.map +1 -0
- package/dist/algorithms.js +2 -0
- package/dist/algorithms.js.map +1 -0
- package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/betweenness.js +22 -7
- package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
- package/dist/src/algorithms/centrality/closeness.js +7 -7
- package/dist/src/algorithms/centrality/closeness.js.map +1 -1
- package/dist/src/algorithms/centrality/degree.js +1 -1
- package/dist/src/algorithms/centrality/degree.js.map +1 -1
- package/dist/src/algorithms/centrality/eigenvector.d.ts +27 -0
- package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -0
- package/dist/src/algorithms/centrality/eigenvector.js +113 -0
- package/dist/src/algorithms/centrality/eigenvector.js.map +1 -0
- package/dist/src/algorithms/centrality/hits.d.ts +35 -0
- package/dist/src/algorithms/centrality/hits.d.ts.map +1 -0
- package/dist/src/algorithms/centrality/hits.js +146 -0
- package/dist/src/algorithms/centrality/hits.js.map +1 -0
- package/dist/src/algorithms/centrality/index.d.ts +6 -0
- package/dist/src/algorithms/centrality/index.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/index.js +3 -0
- package/dist/src/algorithms/centrality/index.js.map +1 -1
- package/dist/src/algorithms/centrality/katz.d.ts +30 -0
- package/dist/src/algorithms/centrality/katz.d.ts.map +1 -0
- package/dist/src/algorithms/centrality/katz.js +85 -0
- package/dist/src/algorithms/centrality/katz.js.map +1 -0
- package/dist/src/algorithms/centrality/pagerank.js +3 -3
- package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
- package/dist/src/algorithms/community/girvan-newman.d.ts +23 -0
- package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -0
- package/dist/src/algorithms/community/girvan-newman.js +297 -0
- package/dist/src/algorithms/community/girvan-newman.js.map +1 -0
- package/dist/src/algorithms/community/index.d.ts +12 -0
- package/dist/src/algorithms/community/index.d.ts.map +1 -0
- package/dist/src/algorithms/community/index.js +12 -0
- package/dist/src/algorithms/community/index.js.map +1 -0
- package/dist/src/algorithms/community/label-propagation.d.ts +42 -0
- package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -0
- package/dist/src/algorithms/community/label-propagation.js +307 -0
- package/dist/src/algorithms/community/label-propagation.js.map +1 -0
- package/dist/src/algorithms/community/leiden.d.ts +33 -0
- package/dist/src/algorithms/community/leiden.d.ts.map +1 -0
- package/dist/src/algorithms/community/leiden.js +434 -0
- package/dist/src/algorithms/community/leiden.js.map +1 -0
- package/dist/src/algorithms/community/louvain.d.ts +19 -0
- package/dist/src/algorithms/community/louvain.d.ts.map +1 -0
- package/dist/src/algorithms/community/louvain.js +219 -0
- package/dist/src/algorithms/community/louvain.js.map +1 -0
- package/dist/src/algorithms/components/connected.js +7 -7
- package/dist/src/algorithms/components/connected.js.map +1 -1
- package/dist/src/algorithms/index.d.ts +7 -0
- package/dist/src/algorithms/index.d.ts.map +1 -1
- package/dist/src/algorithms/index.js +14 -0
- package/dist/src/algorithms/index.js.map +1 -1
- package/dist/src/algorithms/matching/bipartite.d.ts +37 -0
- package/dist/src/algorithms/matching/bipartite.d.ts.map +1 -0
- package/dist/src/algorithms/matching/bipartite.js +127 -0
- package/dist/src/algorithms/matching/bipartite.js.map +1 -0
- package/dist/src/algorithms/matching/index.d.ts +8 -0
- package/dist/src/algorithms/matching/index.d.ts.map +1 -0
- package/dist/src/algorithms/matching/index.js +6 -0
- package/dist/src/algorithms/matching/index.js.map +1 -0
- package/dist/src/algorithms/matching/isomorphism.d.ts +32 -0
- package/dist/src/algorithms/matching/isomorphism.d.ts.map +1 -0
- package/dist/src/algorithms/matching/isomorphism.js +291 -0
- package/dist/src/algorithms/matching/isomorphism.js.map +1 -0
- package/dist/src/algorithms/mst/index.d.ts +4 -0
- package/dist/src/algorithms/mst/index.d.ts.map +1 -0
- package/dist/src/algorithms/mst/index.js +3 -0
- package/dist/src/algorithms/mst/index.js.map +1 -0
- package/dist/src/algorithms/mst/kruskal.d.ts +9 -0
- package/dist/src/algorithms/mst/kruskal.d.ts.map +1 -0
- package/dist/src/algorithms/mst/kruskal.js +43 -0
- package/dist/src/algorithms/mst/kruskal.js.map +1 -0
- package/dist/src/algorithms/mst/prim.d.ts +5 -0
- package/dist/src/algorithms/mst/prim.d.ts.map +1 -0
- package/dist/src/algorithms/mst/prim.js +63 -0
- package/dist/src/algorithms/mst/prim.js.map +1 -0
- package/dist/src/algorithms/shortest-path/bellman-ford.js +2 -2
- package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
- package/dist/src/algorithms/shortest-path/dijkstra.js +5 -5
- package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
- package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts +14 -0
- package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts.map +1 -0
- package/dist/src/algorithms/shortest-path/floyd-warshall.js +129 -0
- package/dist/src/algorithms/shortest-path/floyd-warshall.js.map +1 -0
- package/dist/src/algorithms/shortest-path/index.d.ts +2 -0
- package/dist/src/algorithms/shortest-path/index.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/index.js +1 -0
- package/dist/src/algorithms/shortest-path/index.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs.js +2 -2
- package/dist/src/algorithms/traversal/bfs.js.map +1 -1
- package/dist/src/algorithms/traversal/dfs.js +11 -11
- package/dist/src/algorithms/traversal/dfs.js.map +1 -1
- package/dist/src/clustering/hierarchical.d.ts +48 -0
- package/dist/src/clustering/hierarchical.d.ts.map +1 -0
- package/dist/src/clustering/hierarchical.js +439 -0
- package/dist/src/clustering/hierarchical.js.map +1 -0
- package/dist/src/clustering/index.d.ts +7 -0
- package/dist/src/clustering/index.d.ts.map +1 -0
- package/dist/src/clustering/index.js +5 -0
- package/dist/src/clustering/index.js.map +1 -0
- package/dist/src/clustering/k-core.d.ts +63 -0
- package/dist/src/clustering/k-core.d.ts.map +1 -0
- package/dist/src/clustering/k-core.js +377 -0
- package/dist/src/clustering/k-core.js.map +1 -0
- package/dist/src/clustering/mcl.d.ts +36 -0
- package/dist/src/clustering/mcl.d.ts.map +1 -0
- package/dist/src/clustering/mcl.js +343 -0
- package/dist/src/clustering/mcl.js.map +1 -0
- package/dist/src/clustering/spectral.d.ts +28 -0
- package/dist/src/clustering/spectral.d.ts.map +1 -0
- package/dist/src/clustering/spectral.js +447 -0
- package/dist/src/clustering/spectral.js.map +1 -0
- package/dist/src/core/graph.d.ts +9 -0
- package/dist/src/core/graph.d.ts.map +1 -1
- package/dist/src/core/graph.js +31 -11
- package/dist/src/core/graph.js.map +1 -1
- package/dist/src/data-structures/priority-queue.js +0 -2
- package/dist/src/data-structures/priority-queue.js.map +1 -1
- package/dist/src/data-structures/union-find.js +2 -5
- package/dist/src/data-structures/union-find.js.map +1 -1
- package/dist/src/flow/ford-fulkerson.d.ts +53 -0
- package/dist/src/flow/ford-fulkerson.d.ts.map +1 -0
- package/dist/src/flow/ford-fulkerson.js +355 -0
- package/dist/src/flow/ford-fulkerson.js.map +1 -0
- package/dist/src/flow/index.d.ts +3 -0
- package/dist/src/flow/index.d.ts.map +1 -0
- package/dist/src/flow/index.js +3 -0
- package/dist/src/flow/index.js.map +1 -0
- package/dist/src/flow/min-cut.d.ts +49 -0
- package/dist/src/flow/min-cut.d.ts.map +1 -0
- package/dist/src/flow/min-cut.js +383 -0
- package/dist/src/flow/min-cut.js.map +1 -0
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/link-prediction/adamic-adar.d.ts +56 -0
- package/dist/src/link-prediction/adamic-adar.d.ts.map +1 -0
- package/dist/src/link-prediction/adamic-adar.js +256 -0
- package/dist/src/link-prediction/adamic-adar.js.map +1 -0
- package/dist/src/link-prediction/common-neighbors.d.ts +50 -0
- package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -0
- package/dist/src/link-prediction/common-neighbors.js +155 -0
- package/dist/src/link-prediction/common-neighbors.js.map +1 -0
- package/dist/src/link-prediction/index.d.ts +7 -0
- package/dist/src/link-prediction/index.d.ts.map +1 -0
- package/dist/src/link-prediction/index.js +6 -0
- package/dist/src/link-prediction/index.js.map +1 -0
- package/dist/src/pathfinding/astar.d.ts +50 -0
- package/dist/src/pathfinding/astar.d.ts.map +1 -0
- package/dist/src/pathfinding/astar.js +180 -0
- package/dist/src/pathfinding/astar.js.map +1 -0
- package/dist/src/pathfinding/index.d.ts +3 -0
- package/dist/src/pathfinding/index.d.ts.map +1 -0
- package/dist/src/pathfinding/index.js +3 -0
- package/dist/src/pathfinding/index.js.map +1 -0
- package/dist/src/pathfinding/utils.d.ts +18 -0
- package/dist/src/pathfinding/utils.d.ts.map +1 -0
- package/dist/src/pathfinding/utils.js +68 -0
- package/dist/src/pathfinding/utils.js.map +1 -0
- package/dist/src/types/index.d.ts +9 -0
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/utils/graphNode.d.ts +8 -0
- package/dist/src/utils/graphNode.d.ts.map +1 -0
- package/dist/src/utils/graphNode.js +2 -0
- package/dist/src/utils/graphNode.js.map +1 -0
- package/dist/src/utils/priorityQueue.d.ts +21 -0
- package/dist/src/utils/priorityQueue.d.ts.map +1 -0
- package/dist/src/utils/priorityQueue.js +101 -0
- package/dist/src/utils/priorityQueue.js.map +1 -0
- package/package.json +3 -1
- package/src/algorithms/centrality/betweenness.ts +25 -7
- package/src/algorithms/centrality/closeness.ts +7 -7
- package/src/algorithms/centrality/degree.ts +1 -1
- package/src/algorithms/centrality/eigenvector.ts +162 -0
- package/src/algorithms/centrality/hits.ts +210 -0
- package/src/algorithms/centrality/index.ts +6 -0
- package/src/algorithms/centrality/katz.ts +139 -0
- package/src/algorithms/centrality/pagerank.ts +3 -3
- package/src/algorithms/community/girvan-newman.ts +372 -0
- package/src/algorithms/community/index.ts +13 -0
- package/src/algorithms/community/label-propagation.ts +392 -0
- package/src/algorithms/community/leiden.ts +572 -0
- package/src/algorithms/community/louvain.ts +298 -0
- package/src/algorithms/components/connected.ts +7 -7
- package/src/algorithms/index.ts +21 -0
- package/src/algorithms/matching/bipartite.ts +179 -0
- package/src/algorithms/matching/index.ts +8 -0
- package/src/algorithms/matching/isomorphism.ts +392 -0
- package/src/algorithms/mst/index.ts +4 -0
- package/src/algorithms/mst/kruskal.ts +61 -0
- package/src/algorithms/mst/prim.ts +80 -0
- package/src/algorithms/shortest-path/bellman-ford.ts +2 -2
- package/src/algorithms/shortest-path/dijkstra.ts +5 -5
- package/src/algorithms/shortest-path/floyd-warshall.ts +170 -0
- package/src/algorithms/shortest-path/index.ts +2 -0
- package/src/algorithms/traversal/bfs.ts +2 -2
- package/src/algorithms/traversal/dfs.ts +11 -11
- package/src/clustering/hierarchical.ts +555 -0
- package/src/clustering/index.ts +6 -0
- package/src/clustering/k-core.ts +460 -0
- package/src/clustering/mcl.ts +454 -0
- package/src/clustering/spectral.ts +545 -0
- package/src/core/graph.ts +34 -6
- package/src/data-structures/union-find.ts +2 -2
- package/src/flow/ford-fulkerson.ts +459 -0
- package/src/flow/index.ts +2 -0
- package/src/flow/min-cut.ts +482 -0
- package/src/index.ts +2 -0
- package/src/link-prediction/adamic-adar.ts +353 -0
- package/src/link-prediction/common-neighbors.ts +252 -0
- package/src/link-prediction/index.ts +20 -0
- package/src/pathfinding/astar.ts +229 -0
- package/src/pathfinding/index.ts +2 -0
- package/src/pathfinding/utils.ts +87 -0
- package/src/types/index.ts +11 -0
- package/src/utils/graphNode.ts +7 -0
- package/src/utils/priorityQueue.ts +120 -0
- package/dist/test/browser/basic.test.d.ts +0 -2
- package/dist/test/browser/basic.test.d.ts.map +0 -1
- package/dist/test/browser/basic.test.js +0 -70
- package/dist/test/browser/basic.test.js.map +0 -1
- package/dist/test/unit/bellman-ford.test.d.ts +0 -2
- package/dist/test/unit/bellman-ford.test.d.ts.map +0 -1
- package/dist/test/unit/bellman-ford.test.js +0 -231
- package/dist/test/unit/bellman-ford.test.js.map +0 -1
- package/dist/test/unit/betweenness-centrality.test.d.ts +0 -2
- package/dist/test/unit/betweenness-centrality.test.d.ts.map +0 -1
- package/dist/test/unit/betweenness-centrality.test.js +0 -311
- package/dist/test/unit/betweenness-centrality.test.js.map +0 -1
- package/dist/test/unit/bfs.test.d.ts +0 -2
- package/dist/test/unit/bfs.test.d.ts.map +0 -1
- package/dist/test/unit/bfs.test.js +0 -277
- package/dist/test/unit/bfs.test.js.map +0 -1
- package/dist/test/unit/closeness.test.d.ts +0 -2
- package/dist/test/unit/closeness.test.d.ts.map +0 -1
- package/dist/test/unit/closeness.test.js +0 -266
- package/dist/test/unit/closeness.test.js.map +0 -1
- package/dist/test/unit/connected-components.test.d.ts +0 -2
- package/dist/test/unit/connected-components.test.d.ts.map +0 -1
- package/dist/test/unit/connected-components.test.js +0 -355
- package/dist/test/unit/connected-components.test.js.map +0 -1
- package/dist/test/unit/degree-centrality.test.d.ts +0 -2
- package/dist/test/unit/degree-centrality.test.d.ts.map +0 -1
- package/dist/test/unit/degree-centrality.test.js +0 -260
- package/dist/test/unit/degree-centrality.test.js.map +0 -1
- package/dist/test/unit/dfs.test.d.ts +0 -2
- package/dist/test/unit/dfs.test.d.ts.map +0 -1
- package/dist/test/unit/dfs.test.js +0 -350
- package/dist/test/unit/dfs.test.js.map +0 -1
- package/dist/test/unit/dijkstra.test.d.ts +0 -2
- package/dist/test/unit/dijkstra.test.d.ts.map +0 -1
- package/dist/test/unit/dijkstra.test.js +0 -311
- package/dist/test/unit/dijkstra.test.js.map +0 -1
- package/dist/test/unit/graph.test.d.ts +0 -2
- package/dist/test/unit/graph.test.d.ts.map +0 -1
- package/dist/test/unit/graph.test.js +0 -175
- package/dist/test/unit/graph.test.js.map +0 -1
- package/dist/test/unit/pagerank.test.d.ts +0 -2
- package/dist/test/unit/pagerank.test.d.ts.map +0 -1
- package/dist/test/unit/pagerank.test.js +0 -281
- package/dist/test/unit/pagerank.test.js.map +0 -1
- package/dist/test/unit/priority-queue.test.d.ts +0 -2
- package/dist/test/unit/priority-queue.test.d.ts.map +0 -1
- package/dist/test/unit/priority-queue.test.js +0 -189
- package/dist/test/unit/priority-queue.test.js.map +0 -1
- package/dist/test/unit/union-find.test.d.ts +0 -2
- package/dist/test/unit/union-find.test.d.ts.map +0 -1
- package/dist/test/unit/union-find.test.js +0 -245
- package/dist/test/unit/union-find.test.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
# @graphty/algorithms
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/graphty-org/algorithms/actions)
|
|
4
|
+
[](https://codecov.io/gh/graphty-org/algorithms)
|
|
5
|
+
[](https://www.npmjs.com/package/@graphty/algorithms)
|
|
6
|
+
|
|
7
|
+
A comprehensive TypeScript graph algorithms library with 65+ algorithms optimized for browser environments and visualization applications.
|
|
4
8
|
|
|
5
9
|
## Features
|
|
6
10
|
|
|
7
11
|
- **TypeScript-first**: Full type safety with comprehensive type definitions
|
|
8
12
|
- **Browser-optimized**: Designed to run efficiently in web browsers
|
|
9
13
|
- **Modular**: Import only the algorithms you need
|
|
10
|
-
- **Comprehensive**:
|
|
14
|
+
- **Comprehensive**: 65+ graph algorithms including traversal, shortest paths, centrality, clustering, flow, and more
|
|
11
15
|
- **Well-tested**: Extensive test suite with high coverage
|
|
12
16
|
- **Standards-compliant**: Follows conventional commits and semantic versioning
|
|
13
17
|
|
|
@@ -20,7 +24,7 @@ npm install @graphty/algorithms
|
|
|
20
24
|
## Quick Start
|
|
21
25
|
|
|
22
26
|
```typescript
|
|
23
|
-
import { Graph } from '@graphty/algorithms';
|
|
27
|
+
import { Graph, breadthFirstSearch, dijkstra } from '@graphty/algorithms';
|
|
24
28
|
|
|
25
29
|
// Create a new graph
|
|
26
30
|
const graph = new Graph();
|
|
@@ -28,81 +32,845 @@ const graph = new Graph();
|
|
|
28
32
|
// Add nodes and edges
|
|
29
33
|
graph.addNode('A');
|
|
30
34
|
graph.addNode('B');
|
|
35
|
+
graph.addNode('C');
|
|
31
36
|
graph.addEdge('A', 'B', 1); // source, target, weight
|
|
37
|
+
graph.addEdge('B', 'C', 2);
|
|
32
38
|
|
|
33
39
|
// Basic graph operations
|
|
34
|
-
console.log(graph.nodeCount); //
|
|
35
|
-
console.log(graph.totalEdgeCount); //
|
|
40
|
+
console.log(graph.nodeCount); // 3
|
|
41
|
+
console.log(graph.totalEdgeCount); // 2
|
|
36
42
|
console.log(graph.hasEdge('A', 'B')); // true
|
|
43
|
+
|
|
44
|
+
// Run algorithms
|
|
45
|
+
const traversal = breadthFirstSearch(graph, 'A');
|
|
46
|
+
console.log(traversal.order); // ['A', 'B', 'C']
|
|
47
|
+
|
|
48
|
+
const shortestPaths = dijkstra(graph, 'A');
|
|
49
|
+
console.log(shortestPaths.distances); // Map { 'A' => 0, 'B' => 1, 'C' => 3 }
|
|
37
50
|
```
|
|
38
51
|
|
|
39
|
-
##
|
|
52
|
+
## API Reference
|
|
40
53
|
|
|
41
|
-
###
|
|
54
|
+
### Graph Class
|
|
42
55
|
|
|
43
|
-
|
|
44
|
-
- [x] **Graph Data Structure**: Core graph implementation with adjacency lists
|
|
45
|
-
- [ ] **Breadth-First Search (BFS)**: Level-by-level traversal and shortest paths
|
|
46
|
-
- [ ] **Depth-First Search (DFS)**: Deep traversal with cycle detection
|
|
56
|
+
The core data structure for representing graphs.
|
|
47
57
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
58
|
+
```typescript
|
|
59
|
+
class Graph {
|
|
60
|
+
constructor(config?: Partial<GraphConfig>)
|
|
61
|
+
}
|
|
62
|
+
```
|
|
51
63
|
|
|
52
|
-
####
|
|
53
|
-
- [ ] **Degree Centrality**: Node importance based on connections
|
|
54
|
-
- [ ] **Betweenness Centrality**: Node importance based on shortest path frequency
|
|
55
|
-
- [ ] **Closeness Centrality**: Node importance based on average distance
|
|
56
|
-
- [ ] **PageRank**: Google's web page ranking algorithm
|
|
64
|
+
#### Configuration Options
|
|
57
65
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
66
|
+
```typescript
|
|
67
|
+
interface GraphConfig {
|
|
68
|
+
directed: boolean; // Default: false
|
|
69
|
+
allowSelfLoops: boolean; // Default: false
|
|
70
|
+
allowParallelEdges: boolean; // Default: false
|
|
71
|
+
}
|
|
72
|
+
```
|
|
61
73
|
|
|
62
|
-
####
|
|
63
|
-
- [ ] **Connected Components**: Find connected subgraphs
|
|
64
|
-
- [ ] **Strongly Connected Components**: Tarjan's algorithm for directed graphs
|
|
74
|
+
#### Node Operations
|
|
65
75
|
|
|
66
|
-
|
|
76
|
+
```typescript
|
|
77
|
+
// Add a node with optional data
|
|
78
|
+
graph.addNode(id: NodeId, data?: Record<string, unknown>): void
|
|
67
79
|
|
|
68
|
-
|
|
80
|
+
// Remove a node and all its edges
|
|
81
|
+
graph.removeNode(id: NodeId): boolean
|
|
82
|
+
|
|
83
|
+
// Check if a node exists
|
|
84
|
+
graph.hasNode(id: NodeId): boolean
|
|
85
|
+
|
|
86
|
+
// Get node details
|
|
87
|
+
graph.getNode(id: NodeId): Node | undefined
|
|
88
|
+
|
|
89
|
+
// Get all nodes
|
|
90
|
+
graph.nodes(): IterableIterator<Node>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### Edge Operations
|
|
69
94
|
|
|
70
95
|
```typescript
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
96
|
+
// Add an edge with optional weight and data
|
|
97
|
+
graph.addEdge(
|
|
98
|
+
source: NodeId,
|
|
99
|
+
target: NodeId,
|
|
100
|
+
weight?: number,
|
|
101
|
+
data?: Record<string, unknown>
|
|
102
|
+
): void
|
|
103
|
+
|
|
104
|
+
// Remove an edge
|
|
105
|
+
graph.removeEdge(source: NodeId, target: NodeId): boolean
|
|
106
|
+
|
|
107
|
+
// Check if an edge exists
|
|
108
|
+
graph.hasEdge(source: NodeId, target: NodeId): boolean
|
|
109
|
+
|
|
110
|
+
// Get edge details
|
|
111
|
+
graph.getEdge(source: NodeId, target: NodeId): Edge | undefined
|
|
112
|
+
|
|
113
|
+
// Get all edges
|
|
114
|
+
graph.edges(): IterableIterator<Edge>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### Graph Properties
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// Number of nodes
|
|
121
|
+
graph.nodeCount: number
|
|
122
|
+
|
|
123
|
+
// Total number of edges (counts both directions for undirected)
|
|
124
|
+
graph.totalEdgeCount: number
|
|
125
|
+
|
|
126
|
+
// Number of unique edges
|
|
127
|
+
graph.uniqueEdgeCount: number
|
|
128
|
+
|
|
129
|
+
// Check if graph is directed
|
|
130
|
+
graph.isDirected: boolean
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
#### Degree Operations
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
// Total degree (in + out for directed)
|
|
137
|
+
graph.degree(nodeId: NodeId): number
|
|
138
|
+
|
|
139
|
+
// In-degree (directed graphs only)
|
|
140
|
+
graph.inDegree(nodeId: NodeId): number
|
|
141
|
+
|
|
142
|
+
// Out-degree
|
|
143
|
+
graph.outDegree(nodeId: NodeId): number
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### Neighbor Operations
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// Get neighboring nodes
|
|
150
|
+
graph.neighbors(nodeId: NodeId): IterableIterator<NodeId>
|
|
151
|
+
|
|
152
|
+
// Get incoming neighbors (directed graphs)
|
|
153
|
+
graph.inNeighbors(nodeId: NodeId): IterableIterator<NodeId>
|
|
154
|
+
|
|
155
|
+
// Get outgoing neighbors
|
|
156
|
+
graph.outNeighbors(nodeId: NodeId): IterableIterator<NodeId>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### Utility Methods
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
// Create a deep copy
|
|
163
|
+
graph.clone(): Graph
|
|
164
|
+
|
|
165
|
+
// Clear all nodes and edges
|
|
166
|
+
graph.clear(): void
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Traversal Algorithms
|
|
170
|
+
|
|
171
|
+
#### Breadth-First Search (BFS)
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
import { breadthFirstSearch, shortestPathBFS, singleSourceShortestPathBFS } from '@graphty/algorithms';
|
|
175
|
+
|
|
176
|
+
// Basic BFS traversal
|
|
177
|
+
const result = breadthFirstSearch(graph, startNode, {
|
|
178
|
+
maxDepth?: number, // Optional: limit traversal depth
|
|
179
|
+
visitCallback?: (node: NodeId, depth: number) => void
|
|
180
|
+
});
|
|
181
|
+
// Returns: TraversalResult { visited: Set<NodeId>, order: NodeId[], tree?: Map<NodeId, NodeId> }
|
|
182
|
+
|
|
183
|
+
// Find shortest path between two nodes (unweighted)
|
|
184
|
+
const path = shortestPathBFS(graph, source, target);
|
|
185
|
+
// Returns: NodeId[] | null
|
|
186
|
+
|
|
187
|
+
// Find all shortest paths from a source
|
|
188
|
+
const paths = singleSourceShortestPathBFS(graph, source);
|
|
189
|
+
// Returns: Map<NodeId, NodeId[]>
|
|
190
|
+
|
|
191
|
+
// Check if graph is bipartite
|
|
192
|
+
const bipartite = isBipartite(graph);
|
|
193
|
+
// Returns: { isBipartite: boolean, coloring?: Map<NodeId, number> }
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### Depth-First Search (DFS)
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
import { depthFirstSearch, topologicalSort, hasCycleDFS } from '@graphty/algorithms';
|
|
200
|
+
|
|
201
|
+
// Basic DFS traversal
|
|
202
|
+
const result = depthFirstSearch(graph, startNode, {
|
|
203
|
+
previsitCallback?: (node: NodeId) => void,
|
|
204
|
+
postvisitCallback?: (node: NodeId) => void
|
|
205
|
+
});
|
|
206
|
+
// Returns: TraversalResult
|
|
207
|
+
|
|
208
|
+
// Topological sort (for DAGs)
|
|
209
|
+
const sorted = topologicalSort(graph);
|
|
210
|
+
// Returns: NodeId[] | null (null if cycle detected)
|
|
211
|
+
|
|
212
|
+
// Cycle detection
|
|
213
|
+
const hasCycle = hasCycleDFS(graph);
|
|
214
|
+
// Returns: boolean
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Shortest Path Algorithms
|
|
218
|
+
|
|
219
|
+
#### Dijkstra's Algorithm
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { dijkstra, dijkstraPath, singleSourceShortestPath, allPairsShortestPath } from '@graphty/algorithms';
|
|
223
|
+
|
|
224
|
+
// Single-source shortest paths
|
|
225
|
+
const result = dijkstra(graph, source, {
|
|
226
|
+
target?: NodeId // Optional: stop when target is reached
|
|
227
|
+
});
|
|
228
|
+
// Returns: Map<NodeId, { path: NodeId[], distance: number, predecessor: NodeId | null }>
|
|
229
|
+
|
|
230
|
+
// Get specific path
|
|
231
|
+
const path = dijkstraPath(graph, source, target);
|
|
232
|
+
// Returns: { path: NodeId[], distance: number } | null
|
|
233
|
+
|
|
234
|
+
// All shortest paths from source
|
|
235
|
+
const paths = singleSourceShortestPath(graph, source);
|
|
236
|
+
// Returns: Map<NodeId, { path: NodeId[], distance: number }>
|
|
237
|
+
|
|
238
|
+
// All pairs shortest paths
|
|
239
|
+
const allPairs = allPairsShortestPath(graph);
|
|
240
|
+
// Returns: Map<NodeId, Map<NodeId, { path: NodeId[], distance: number }>>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
#### Bellman-Ford Algorithm
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import { bellmanFord, bellmanFordPath, hasNegativeCycle } from '@graphty/algorithms';
|
|
247
|
+
|
|
248
|
+
// Single-source shortest paths (handles negative weights)
|
|
249
|
+
const result = bellmanFord(graph, source);
|
|
250
|
+
// Returns: BellmanFordResult {
|
|
251
|
+
// distances: Map<NodeId, number>,
|
|
252
|
+
// predecessors: Map<NodeId, NodeId | null>,
|
|
253
|
+
// hasNegativeCycle: boolean,
|
|
254
|
+
// negativeCycleNodes?: Set<NodeId>
|
|
255
|
+
// }
|
|
256
|
+
|
|
257
|
+
// Get specific path
|
|
258
|
+
const path = bellmanFordPath(graph, source, target);
|
|
259
|
+
// Returns: { path: NodeId[], distance: number } | null
|
|
260
|
+
|
|
261
|
+
// Check for negative cycles
|
|
262
|
+
const result = hasNegativeCycle(graph);
|
|
263
|
+
// Returns: BellmanFordResult with hasNegativeCycle boolean
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
#### Floyd-Warshall Algorithm
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
import { floydWarshall, floydWarshallPath, transitiveClosure } from '@graphty/algorithms';
|
|
270
|
+
|
|
271
|
+
// All pairs shortest paths
|
|
272
|
+
const result = floydWarshall(graph);
|
|
273
|
+
// Returns: { distances: Map<NodeId, Map<NodeId, number>>, next: Map<NodeId, Map<NodeId, NodeId | null>> }
|
|
274
|
+
|
|
275
|
+
// Get specific path between any pair
|
|
276
|
+
const path = floydWarshallPath(result, source, target);
|
|
277
|
+
// Returns: NodeId[] | null
|
|
278
|
+
|
|
279
|
+
// Compute transitive closure
|
|
280
|
+
const closure = transitiveClosure(graph);
|
|
281
|
+
// Returns: Map<NodeId, Set<NodeId>>
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Centrality Algorithms
|
|
285
|
+
|
|
286
|
+
#### Degree Centrality
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
import { degreeCentrality, nodeDegreeCentrality } from '@graphty/algorithms';
|
|
290
|
+
|
|
291
|
+
// Calculate for all nodes
|
|
292
|
+
const centralities = degreeCentrality(graph, {
|
|
293
|
+
normalized?: boolean, // Default: false
|
|
294
|
+
weight?: string // Optional: edge property for weighted degree
|
|
295
|
+
});
|
|
296
|
+
// Returns: CentralityResult (Map<NodeId, number>)
|
|
297
|
+
|
|
298
|
+
// Calculate for single node
|
|
299
|
+
const centrality = nodeDegreeCentrality(graph, nodeId, { normalized?: boolean });
|
|
300
|
+
// Returns: number
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
#### Betweenness Centrality
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
import { betweennessCentrality, nodeBetweennessCentrality, edgeBetweennessCentrality } from '@graphty/algorithms';
|
|
307
|
+
|
|
308
|
+
// Node betweenness for all nodes
|
|
309
|
+
const centralities = betweennessCentrality(graph, {
|
|
310
|
+
normalized?: boolean, // Default: false
|
|
311
|
+
weight?: string, // Optional: use weighted shortest paths
|
|
312
|
+
endpoints?: boolean // Default: false, include endpoints in paths
|
|
313
|
+
});
|
|
314
|
+
// Returns: CentralityResult
|
|
315
|
+
|
|
316
|
+
// Single node betweenness
|
|
317
|
+
const centrality = nodeBetweennessCentrality(graph, nodeId, options);
|
|
318
|
+
// Returns: number
|
|
319
|
+
|
|
320
|
+
// Edge betweenness
|
|
321
|
+
const edgeCentralities = edgeBetweennessCentrality(graph, options);
|
|
322
|
+
// Returns: Map<string, number> (edge ID to centrality)
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
#### Closeness Centrality
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
import { closenessCentrality, nodeClosenessCentrality, weightedClosenessCentrality } from '@graphty/algorithms';
|
|
329
|
+
|
|
330
|
+
// Closeness for all nodes
|
|
331
|
+
const centralities = closenessCentrality(graph, {
|
|
332
|
+
normalized?: boolean // Default: false
|
|
333
|
+
});
|
|
334
|
+
// Returns: CentralityResult
|
|
335
|
+
|
|
336
|
+
// Single node closeness
|
|
337
|
+
const centrality = nodeClosenessCentrality(graph, nodeId, { normalized?: boolean });
|
|
338
|
+
// Returns: number
|
|
339
|
+
|
|
340
|
+
// Weighted closeness
|
|
341
|
+
const centralities = weightedClosenessCentrality(graph, {
|
|
342
|
+
normalized?: boolean,
|
|
343
|
+
weight?: string // Edge property for weights
|
|
344
|
+
});
|
|
345
|
+
// Returns: CentralityResult
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
#### PageRank
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
import { pageRank, personalizedPageRank, topPageRankNodes } from '@graphty/algorithms';
|
|
352
|
+
|
|
353
|
+
// Standard PageRank
|
|
354
|
+
const result = pageRank(graph, {
|
|
355
|
+
dampingFactor?: number, // Default: 0.85
|
|
356
|
+
maxIterations?: number, // Default: 100
|
|
357
|
+
tolerance?: number, // Default: 1e-6
|
|
358
|
+
initialRanks?: Record<string, number>,
|
|
359
|
+
personalization?: Record<string, number>
|
|
360
|
+
});
|
|
361
|
+
// Returns: { ranks: Record<string, number>, iterations: number, converged: boolean }
|
|
362
|
+
|
|
363
|
+
// Personalized PageRank (with bias)
|
|
364
|
+
const ranks = personalizedPageRank(graph, personalization, options);
|
|
365
|
+
// personalization: Map<NodeId, number> - restart probabilities
|
|
366
|
+
// Returns: CentralityResult
|
|
367
|
+
|
|
368
|
+
// Get top N nodes by PageRank
|
|
369
|
+
const topNodes = topPageRankNodes(graph, n, options);
|
|
370
|
+
// Returns: Array<{ node: NodeId, rank: number }>
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Connected Components
|
|
374
|
+
|
|
375
|
+
#### Basic Component Operations
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
import {
|
|
379
|
+
connectedComponents,
|
|
380
|
+
isConnected,
|
|
381
|
+
numberOfConnectedComponents,
|
|
382
|
+
largestConnectedComponent,
|
|
383
|
+
getConnectedComponent
|
|
384
|
+
} from '@graphty/algorithms';
|
|
385
|
+
|
|
386
|
+
// Find all components
|
|
387
|
+
const components = connectedComponents(graph);
|
|
388
|
+
// Returns: NodeId[][] (array of component arrays)
|
|
389
|
+
|
|
390
|
+
// Check if graph is connected
|
|
391
|
+
const connected = isConnected(graph);
|
|
392
|
+
// Returns: boolean
|
|
393
|
+
|
|
394
|
+
// Count components
|
|
395
|
+
const count = numberOfConnectedComponents(graph);
|
|
396
|
+
// Returns: number
|
|
397
|
+
|
|
398
|
+
// Get largest component
|
|
399
|
+
const largest = largestConnectedComponent(graph);
|
|
400
|
+
// Returns: NodeId[]
|
|
401
|
+
|
|
402
|
+
// Get component containing a specific node
|
|
403
|
+
const component = getConnectedComponent(graph, nodeId);
|
|
404
|
+
// Returns: Set<NodeId>
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
#### Strongly Connected Components
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
import {
|
|
411
|
+
stronglyConnectedComponents,
|
|
412
|
+
findStronglyConnectedComponents,
|
|
413
|
+
isStronglyConnected,
|
|
414
|
+
condensationGraph
|
|
415
|
+
} from '@graphty/algorithms';
|
|
416
|
+
|
|
417
|
+
// Find SCCs using Tarjan's algorithm
|
|
418
|
+
const sccs = stronglyConnectedComponents(graph);
|
|
419
|
+
// Returns: ComponentResult
|
|
420
|
+
|
|
421
|
+
// Alternative: using DFS
|
|
422
|
+
const sccs = findStronglyConnectedComponents(graph);
|
|
423
|
+
// Returns: NodeId[][]
|
|
424
|
+
|
|
425
|
+
// Check if directed graph is strongly connected
|
|
426
|
+
const stronglyConnected = isStronglyConnected(graph);
|
|
427
|
+
// Returns: boolean
|
|
428
|
+
|
|
429
|
+
// Create condensation graph (DAG of SCCs)
|
|
430
|
+
const condensation = condensationGraph(graph);
|
|
431
|
+
// Returns: { graph: Graph, componentMap: Map<NodeId, number> }
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
#### Weakly Connected Components
|
|
435
|
+
|
|
436
|
+
```typescript
|
|
437
|
+
import { weaklyConnectedComponents, isWeaklyConnected } from '@graphty/algorithms';
|
|
438
|
+
|
|
439
|
+
// Find WCCs (ignoring edge direction)
|
|
440
|
+
const wccs = weaklyConnectedComponents(graph);
|
|
441
|
+
// Returns: ComponentResult
|
|
442
|
+
|
|
443
|
+
// Check if directed graph is weakly connected
|
|
444
|
+
const weaklyConnected = isWeaklyConnected(graph);
|
|
445
|
+
// Returns: boolean
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Data Structures
|
|
449
|
+
|
|
450
|
+
#### Priority Queue
|
|
451
|
+
|
|
452
|
+
Min-heap implementation used internally by algorithms.
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
import { PriorityQueue } from '@graphty/algorithms';
|
|
456
|
+
|
|
457
|
+
const pq = new PriorityQueue<T>((a, b) => a.priority - b.priority);
|
|
458
|
+
|
|
459
|
+
pq.enqueue(item);
|
|
460
|
+
pq.dequeue();
|
|
461
|
+
pq.peek();
|
|
462
|
+
pq.isEmpty();
|
|
463
|
+
pq.size;
|
|
464
|
+
pq.clear();
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
#### Union-Find (Disjoint Set)
|
|
468
|
+
|
|
469
|
+
Efficient data structure for tracking connected components.
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
import { UnionFind } from '@graphty/algorithms';
|
|
473
|
+
|
|
474
|
+
const uf = new UnionFind<T>();
|
|
475
|
+
|
|
476
|
+
uf.makeSet(item);
|
|
477
|
+
uf.find(item);
|
|
478
|
+
uf.union(item1, item2);
|
|
479
|
+
uf.connected(item1, item2);
|
|
480
|
+
uf.getSetSize(item);
|
|
481
|
+
uf.numberOfSets;
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### Minimum Spanning Tree Algorithms
|
|
485
|
+
|
|
486
|
+
#### Kruskal's Algorithm
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
import { kruskalMST, minimumSpanningTree } from '@graphty/algorithms';
|
|
490
|
+
|
|
491
|
+
// Find MST using Kruskal's algorithm
|
|
492
|
+
const mst = kruskalMST(graph);
|
|
493
|
+
// Returns: { edges: Edge[], weight: number }
|
|
494
|
+
|
|
495
|
+
// Alternative alias
|
|
496
|
+
const mst = minimumSpanningTree(graph);
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
#### Prim's Algorithm
|
|
500
|
+
|
|
501
|
+
```typescript
|
|
502
|
+
import { primMST } from '@graphty/algorithms';
|
|
503
|
+
|
|
504
|
+
// Find MST using Prim's algorithm
|
|
505
|
+
const mst = primMST(graph, startNode?);
|
|
506
|
+
// Returns: { edges: Edge[], weight: number }
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### Community Detection Algorithms
|
|
510
|
+
|
|
511
|
+
#### Louvain Method
|
|
512
|
+
|
|
513
|
+
```typescript
|
|
514
|
+
import { louvain } from '@graphty/algorithms';
|
|
515
|
+
|
|
516
|
+
// Detect communities using Louvain method
|
|
517
|
+
const communities = louvain(graph, {
|
|
518
|
+
resolution?: number, // Default: 1.0
|
|
519
|
+
randomSeed?: number
|
|
520
|
+
});
|
|
521
|
+
// Returns: { communities: Map<NodeId, number>, modularity: number }
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
#### Leiden Algorithm
|
|
525
|
+
|
|
526
|
+
```typescript
|
|
527
|
+
import { leiden } from '@graphty/algorithms';
|
|
528
|
+
|
|
529
|
+
// Improved community detection
|
|
530
|
+
const communities = leiden(graph, {
|
|
531
|
+
resolution?: number, // Default: 1.0
|
|
532
|
+
iterations?: number, // Default: 10
|
|
533
|
+
randomSeed?: number
|
|
534
|
+
});
|
|
535
|
+
// Returns: { communities: Map<NodeId, number>, modularity: number }
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
#### Label Propagation
|
|
539
|
+
|
|
540
|
+
```typescript
|
|
541
|
+
import { labelPropagation, labelPropagationAsync, labelPropagationSemiSupervised } from '@graphty/algorithms';
|
|
542
|
+
|
|
543
|
+
// Basic label propagation
|
|
544
|
+
const labels = labelPropagation(graph, {
|
|
545
|
+
maxIterations?: number // Default: 100
|
|
546
|
+
});
|
|
547
|
+
// Returns: Map<NodeId, number>
|
|
548
|
+
|
|
549
|
+
// Asynchronous version
|
|
550
|
+
const labels = labelPropagationAsync(graph, options);
|
|
551
|
+
|
|
552
|
+
// Semi-supervised with seed communities
|
|
553
|
+
const labels = labelPropagationSemiSupervised(graph, seedLabels, options);
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
#### Girvan-Newman Algorithm
|
|
557
|
+
|
|
558
|
+
```typescript
|
|
559
|
+
import { girvanNewman } from '@graphty/algorithms';
|
|
560
|
+
|
|
561
|
+
// Edge betweenness based community detection
|
|
562
|
+
const dendrogram = girvanNewman(graph, {
|
|
563
|
+
targetCommunities?: number // Stop at this many communities
|
|
564
|
+
});
|
|
565
|
+
// Returns: { levels: Array<{ modularity: number, communities: NodeId[][] }> }
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
### Pathfinding Algorithms
|
|
569
|
+
|
|
570
|
+
#### A* Algorithm
|
|
571
|
+
|
|
572
|
+
```typescript
|
|
573
|
+
import { astar, astarWithDetails, heuristics } from '@graphty/algorithms';
|
|
574
|
+
|
|
575
|
+
// A* pathfinding with heuristic
|
|
576
|
+
const path = astar(graph, start, goal, {
|
|
577
|
+
heuristic: heuristics.euclidean, // or manhattan, chebyshev, zero
|
|
578
|
+
weight?: (edge: Edge) => number
|
|
579
|
+
});
|
|
580
|
+
// Returns: { path: NodeId[], cost: number } | null
|
|
581
|
+
|
|
582
|
+
// A* with search details
|
|
583
|
+
const result = astarWithDetails(graph, start, goal, options);
|
|
584
|
+
// Returns: { path: NodeId[], cost: number, explored: Set<NodeId>, parent: Map<NodeId, NodeId> } | null
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
### Flow Algorithms
|
|
588
|
+
|
|
589
|
+
#### Maximum Flow
|
|
590
|
+
|
|
591
|
+
```typescript
|
|
592
|
+
import { fordFulkerson, edmondsKarp } from '@graphty/algorithms';
|
|
593
|
+
|
|
594
|
+
// Ford-Fulkerson using DFS
|
|
595
|
+
const flow = fordFulkerson(graph, source, sink, {
|
|
596
|
+
capacityKey?: string // Edge property for capacity
|
|
597
|
+
});
|
|
598
|
+
// Returns: { maxFlow: number, flowGraph: Map<NodeId, Map<NodeId, number>> }
|
|
599
|
+
|
|
600
|
+
// Edmonds-Karp using BFS (better complexity)
|
|
601
|
+
const flow = edmondsKarp(graph, source, sink, options);
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
#### Minimum Cut
|
|
605
|
+
|
|
606
|
+
```typescript
|
|
607
|
+
import { minSTCut, stoerWagner, kargerMinCut } from '@graphty/algorithms';
|
|
608
|
+
|
|
609
|
+
// Min s-t cut using max flow
|
|
610
|
+
const cut = minSTCut(graph, source, sink);
|
|
611
|
+
// Returns: { cutValue: number, sourcePartition: Set<NodeId>, sinkPartition: Set<NodeId> }
|
|
612
|
+
|
|
613
|
+
// Global minimum cut (Stoer-Wagner)
|
|
614
|
+
const cut = stoerWagner(graph);
|
|
615
|
+
// Returns: { cutValue: number, partition1: Set<NodeId>, partition2: Set<NodeId> }
|
|
616
|
+
|
|
617
|
+
// Randomized min cut (Karger)
|
|
618
|
+
const cut = kargerMinCut(graph, iterations?);
|
|
619
|
+
// Returns: { cutValue: number, partition1: Set<NodeId>, partition2: Set<NodeId> }
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
### Clustering Algorithms
|
|
623
|
+
|
|
624
|
+
#### Hierarchical Clustering
|
|
625
|
+
|
|
626
|
+
```typescript
|
|
627
|
+
import { hierarchicalClustering, cutDendrogram, cutDendrogramKClusters } from '@graphty/algorithms';
|
|
628
|
+
|
|
629
|
+
// Agglomerative clustering
|
|
630
|
+
const dendrogram = hierarchicalClustering(graph, {
|
|
631
|
+
linkage: 'single' | 'complete' | 'average', // Default: 'average'
|
|
632
|
+
distanceMetric?: (a: NodeId, b: NodeId) => number
|
|
633
|
+
});
|
|
634
|
+
// Returns: Dendrogram structure
|
|
635
|
+
|
|
636
|
+
// Cut at specific height
|
|
637
|
+
const clusters = cutDendrogram(dendrogram, height);
|
|
638
|
+
// Returns: NodeId[][]
|
|
639
|
+
|
|
640
|
+
// Get exactly k clusters
|
|
641
|
+
const clusters = cutDendrogramKClusters(dendrogram, k);
|
|
642
|
+
// Returns: NodeId[][]
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
#### K-Core Decomposition
|
|
646
|
+
|
|
647
|
+
```typescript
|
|
648
|
+
import { kCoreDecomposition, getKCore, kTruss } from '@graphty/algorithms';
|
|
649
|
+
|
|
650
|
+
// Find all k-cores
|
|
651
|
+
const cores = kCoreDecomposition(graph);
|
|
652
|
+
// Returns: Map<NodeId, number> (node to core number)
|
|
653
|
+
|
|
654
|
+
// Extract specific k-core subgraph
|
|
655
|
+
const kCore = getKCore(graph, k);
|
|
656
|
+
// Returns: Set<NodeId>
|
|
657
|
+
|
|
658
|
+
// Find k-truss (triangular cores)
|
|
659
|
+
const truss = kTruss(graph, k);
|
|
660
|
+
// Returns: Graph
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
## Examples
|
|
664
|
+
|
|
665
|
+
The library includes comprehensive examples demonstrating each algorithm. Find them in the [examples directory](https://github.com/graphty-org/algorithms/tree/main/examples):
|
|
666
|
+
|
|
667
|
+
### Basic Algorithms
|
|
668
|
+
- [BFS Traversal](https://github.com/graphty-org/algorithms/blob/main/examples/bfs-example.js) - Breadth-first search and shortest paths
|
|
669
|
+
- [DFS Traversal](https://github.com/graphty-org/algorithms/blob/main/examples/dfs-example.js) - Depth-first search and applications
|
|
670
|
+
- [Dijkstra's Algorithm](https://github.com/graphty-org/algorithms/blob/main/examples/dijkstra-example.js) - Weighted shortest paths
|
|
671
|
+
- [Bellman-Ford](https://github.com/graphty-org/algorithms/blob/main/examples/bellman-ford-example.js) - Shortest paths with negative weights
|
|
672
|
+
- [Floyd-Warshall](https://github.com/graphty-org/algorithms/blob/main/examples/floyd-warshall-example.js) - All pairs shortest paths
|
|
673
|
+
|
|
674
|
+
### Centrality Measures
|
|
675
|
+
- [Degree Centrality](https://github.com/graphty-org/algorithms/blob/main/examples/degree-centrality-example.js) - Node importance by connections
|
|
676
|
+
- [Betweenness Centrality](https://github.com/graphty-org/algorithms/blob/main/examples/betweenness-centrality-example.js) - Bridge nodes
|
|
677
|
+
- [Closeness Centrality](https://github.com/graphty-org/algorithms/blob/main/examples/closeness-centrality-example.js) - Central nodes
|
|
678
|
+
- [PageRank](https://github.com/graphty-org/algorithms/blob/main/examples/pagerank-example.js) - Node ranking algorithm
|
|
679
|
+
|
|
680
|
+
### Graph Structure
|
|
681
|
+
- [Connected Components](https://github.com/graphty-org/algorithms/blob/main/examples/connected-components-example.js) - Find graph components
|
|
682
|
+
- [Kruskal's MST](https://github.com/graphty-org/algorithms/blob/main/examples/kruskal-example.js) - Minimum spanning tree
|
|
683
|
+
- [Prim's MST](https://github.com/graphty-org/algorithms/blob/main/examples/prim-example.js) - Alternative MST algorithm
|
|
684
|
+
|
|
685
|
+
### Community Detection
|
|
686
|
+
- [Louvain Method](https://github.com/graphty-org/algorithms/blob/main/examples/louvain-example.js) - Modularity-based communities
|
|
687
|
+
- [Leiden Algorithm](https://github.com/graphty-org/algorithms/blob/main/examples/leiden-community.ts) - Improved Louvain
|
|
688
|
+
- [Label Propagation](https://github.com/graphty-org/algorithms/blob/main/examples/label-propagation.ts) - Fast community detection
|
|
689
|
+
- [Girvan-Newman](https://github.com/graphty-org/algorithms/blob/main/examples/girvan-newman-example.js) - Hierarchical communities
|
|
690
|
+
|
|
691
|
+
### Advanced Algorithms
|
|
692
|
+
- [A* Pathfinding](https://github.com/graphty-org/algorithms/blob/main/examples/astar-pathfinding.ts) - Heuristic pathfinding
|
|
693
|
+
- [Flow Algorithms](https://github.com/graphty-org/algorithms/blob/main/examples/flow-algorithms.ts) - Maximum flow and applications
|
|
694
|
+
- [Ford-Fulkerson Flow](https://github.com/graphty-org/algorithms/blob/main/examples/ford-fulkerson-flow.ts) - Maximum flow implementation
|
|
695
|
+
- [Minimum Cut](https://github.com/graphty-org/algorithms/blob/main/examples/min-cut.ts) - Graph partitioning
|
|
696
|
+
- [Hierarchical Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/hierarchical-clustering.ts) - Graph clustering
|
|
697
|
+
- [K-Core Decomposition](https://github.com/graphty-org/algorithms/blob/main/examples/k-core-decomposition.ts) - Core analysis
|
|
698
|
+
|
|
699
|
+
## Advanced Usage Examples
|
|
700
|
+
|
|
701
|
+
### Working with Weighted Graphs
|
|
702
|
+
|
|
703
|
+
```typescript
|
|
704
|
+
const graph = new Graph();
|
|
705
|
+
|
|
706
|
+
// Add weighted edges
|
|
707
|
+
graph.addEdge('A', 'B', 5);
|
|
708
|
+
graph.addEdge('B', 'C', 3);
|
|
709
|
+
graph.addEdge('A', 'C', 10);
|
|
710
|
+
|
|
711
|
+
// Find shortest path considering weights
|
|
712
|
+
const result = dijkstra(graph, 'A');
|
|
713
|
+
const pathToC = dijkstraPath(graph, 'A', 'C');
|
|
714
|
+
console.log(pathToC); // { path: ['A', 'B', 'C'], distance: 8 }
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
### Directed Graphs
|
|
718
|
+
|
|
719
|
+
```typescript
|
|
720
|
+
const directedGraph = new Graph({ directed: true });
|
|
721
|
+
|
|
722
|
+
directedGraph.addEdge('A', 'B');
|
|
723
|
+
directedGraph.addEdge('B', 'C');
|
|
724
|
+
directedGraph.addEdge('C', 'A');
|
|
725
|
+
|
|
726
|
+
// Check for cycles
|
|
727
|
+
console.log(hasCycleDFS(directedGraph)); // true
|
|
728
|
+
|
|
729
|
+
// Find strongly connected components
|
|
730
|
+
const sccs = stronglyConnectedComponents(directedGraph);
|
|
731
|
+
console.log(sccs.components); // [['A', 'B', 'C']]
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
### Network Analysis
|
|
735
|
+
|
|
736
|
+
```typescript
|
|
737
|
+
// Identify important nodes
|
|
738
|
+
const graph = createSocialNetwork(); // Your graph
|
|
739
|
+
|
|
740
|
+
// Find influencers (high PageRank)
|
|
741
|
+
const influencers = topPageRankNodes(graph, 10);
|
|
742
|
+
|
|
743
|
+
// Find bridges (high betweenness)
|
|
744
|
+
const bridgers = Array.from(betweennessCentrality(graph).entries())
|
|
745
|
+
.sort((a, b) => b[1] - a[1])
|
|
746
|
+
.slice(0, 10);
|
|
747
|
+
|
|
748
|
+
// Find communities (connected components)
|
|
749
|
+
const communities = connectedComponents(graph);
|
|
750
|
+
console.log(`Found ${communities.components.length} communities`);
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
### Custom Edge Properties
|
|
754
|
+
|
|
755
|
+
```typescript
|
|
756
|
+
const graph = new Graph();
|
|
757
|
+
|
|
758
|
+
// Add edges with custom data
|
|
759
|
+
graph.addEdge('A', 'B', 1, {
|
|
760
|
+
type: 'road',
|
|
761
|
+
distance: 100,
|
|
762
|
+
traffic: 'heavy'
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
// Use custom weight in algorithms
|
|
766
|
+
const result = dijkstra(graph, 'A', {
|
|
767
|
+
weightKey: 'distance' // Use 'distance' property as weight
|
|
768
|
+
});
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
### Graph Visualization Preparation
|
|
772
|
+
|
|
773
|
+
```typescript
|
|
774
|
+
// Prepare data for visualization
|
|
775
|
+
const graph = loadGraph();
|
|
776
|
+
|
|
777
|
+
// Calculate layout metrics
|
|
778
|
+
const centralities = degreeCentrality(graph, { normalized: true });
|
|
779
|
+
const ranks = pageRank(graph);
|
|
780
|
+
|
|
781
|
+
// Export for visualization
|
|
782
|
+
const nodes = Array.from(graph.nodes()).map(node => ({
|
|
783
|
+
id: node.id,
|
|
784
|
+
data: node.data,
|
|
785
|
+
size: centralities.get(node.id) || 0,
|
|
786
|
+
importance: ranks.get(node.id) || 0
|
|
787
|
+
}));
|
|
788
|
+
|
|
789
|
+
const edges = Array.from(graph.edges()).map(edge => ({
|
|
790
|
+
source: edge.source,
|
|
791
|
+
target: edge.target,
|
|
792
|
+
weight: edge.weight || 1,
|
|
793
|
+
data: edge.data
|
|
794
|
+
}));
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
## Type Definitions
|
|
798
|
+
|
|
799
|
+
### Core Types
|
|
800
|
+
|
|
801
|
+
```typescript
|
|
802
|
+
type NodeId = string | number;
|
|
803
|
+
|
|
804
|
+
interface Node {
|
|
805
|
+
id: NodeId;
|
|
806
|
+
data?: Record<string, unknown>;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
interface Edge {
|
|
810
|
+
source: NodeId;
|
|
811
|
+
target: NodeId;
|
|
812
|
+
weight?: number;
|
|
813
|
+
id?: string;
|
|
814
|
+
data?: Record<string, unknown>;
|
|
103
815
|
}
|
|
104
816
|
```
|
|
105
817
|
|
|
818
|
+
### Algorithm Result Types
|
|
819
|
+
|
|
820
|
+
```typescript
|
|
821
|
+
interface TraversalResult {
|
|
822
|
+
visited: Set<NodeId>;
|
|
823
|
+
order: NodeId[];
|
|
824
|
+
tree?: Map<NodeId, NodeId>;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
interface ShortestPathResult {
|
|
828
|
+
path: NodeId[];
|
|
829
|
+
distance: number;
|
|
830
|
+
predecessor: NodeId | null;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
interface BellmanFordResult {
|
|
834
|
+
distances: Map<NodeId, number>;
|
|
835
|
+
predecessors: Map<NodeId, NodeId | null>;
|
|
836
|
+
hasNegativeCycle: boolean;
|
|
837
|
+
negativeCycleNodes?: Set<NodeId>;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
type CentralityResult = Record<string, number>;
|
|
841
|
+
|
|
842
|
+
interface PageRankResult {
|
|
843
|
+
ranks: Record<string, number>;
|
|
844
|
+
iterations: number;
|
|
845
|
+
converged: boolean;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
interface CommunityResult {
|
|
849
|
+
communities: Map<NodeId, number>;
|
|
850
|
+
modularity: number;
|
|
851
|
+
}
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
## Performance Considerations
|
|
855
|
+
|
|
856
|
+
- **Graph Representation**: Uses adjacency lists for O(1) neighbor access
|
|
857
|
+
- **Algorithm Complexity**:
|
|
858
|
+
- BFS/DFS: O(V + E)
|
|
859
|
+
- Dijkstra: O((V + E) log V) with binary heap
|
|
860
|
+
- Bellman-Ford: O(VE)
|
|
861
|
+
- Floyd-Warshall: O(V³)
|
|
862
|
+
- PageRank: O(k(V + E)) where k is iterations
|
|
863
|
+
- Connected Components: O(V + E)
|
|
864
|
+
- Kruskal's MST: O(E log E)
|
|
865
|
+
- Prim's MST: O((V + E) log V)
|
|
866
|
+
- A*: O((V + E) log V) - depends on heuristic quality
|
|
867
|
+
- Ford-Fulkerson: O(E * f) where f is max flow
|
|
868
|
+
- Edmonds-Karp: O(VE²)
|
|
869
|
+
- Louvain/Leiden: O(n log n) average case
|
|
870
|
+
- Hierarchical Clustering: O(n² log n)
|
|
871
|
+
- **Memory Usage**: O(V + E) for graph storage
|
|
872
|
+
- **Browser Optimization**: Algorithms use iterative approaches where possible to avoid stack overflow
|
|
873
|
+
|
|
106
874
|
## Development
|
|
107
875
|
|
|
108
876
|
### Prerequisites
|
|
@@ -156,7 +924,6 @@ src/
|
|
|
156
924
|
│ ├── traversal/ # BFS, DFS
|
|
157
925
|
│ ├── shortest-path/ # Dijkstra, Bellman-Ford
|
|
158
926
|
│ ├── centrality/ # Degree, Betweenness, PageRank
|
|
159
|
-
│ ├── community/ # Louvain, Girvan-Newman
|
|
160
927
|
│ └── components/ # Connected components
|
|
161
928
|
├── data-structures/ # Supporting data structures
|
|
162
929
|
├── types/ # TypeScript type definitions
|