@graphty/algorithms 1.3.1 → 1.5.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 +368 -422
- package/dist/algorithms.js +567 -264
- package/dist/algorithms.js.map +1 -1
- package/dist/src/algorithms/centrality/betweenness.d.ts +10 -0
- package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/betweenness.js +27 -6
- package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
- package/dist/src/algorithms/centrality/closeness.d.ts +11 -2
- package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/closeness.js +17 -3
- package/dist/src/algorithms/centrality/closeness.js.map +1 -1
- package/dist/src/algorithms/centrality/degree.d.ts +7 -0
- package/dist/src/algorithms/centrality/degree.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/degree.js +9 -6
- package/dist/src/algorithms/centrality/degree.js.map +1 -1
- package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts +21 -3
- package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/delta-pagerank-simple.js +25 -7
- package/dist/src/algorithms/centrality/delta-pagerank-simple.js.map +1 -1
- package/dist/src/algorithms/centrality/delta-pagerank.d.ts +28 -2
- package/dist/src/algorithms/centrality/delta-pagerank.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/delta-pagerank.js +30 -4
- package/dist/src/algorithms/centrality/delta-pagerank.js.map +1 -1
- package/dist/src/algorithms/centrality/eigenvector.d.ts +10 -3
- package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/eigenvector.js +11 -4
- package/dist/src/algorithms/centrality/eigenvector.js.map +1 -1
- package/dist/src/algorithms/centrality/hits.d.ts +10 -3
- package/dist/src/algorithms/centrality/hits.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/hits.js +11 -4
- package/dist/src/algorithms/centrality/hits.js.map +1 -1
- package/dist/src/algorithms/centrality/index.d.ts +1 -1
- package/dist/src/algorithms/centrality/index.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/index.js +1 -1
- package/dist/src/algorithms/centrality/index.js.map +1 -1
- package/dist/src/algorithms/centrality/katz.d.ts +10 -3
- package/dist/src/algorithms/centrality/katz.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/katz.js +13 -8
- package/dist/src/algorithms/centrality/katz.js.map +1 -1
- package/dist/src/algorithms/centrality/pagerank.d.ts +14 -0
- package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -1
- package/dist/src/algorithms/centrality/pagerank.js +16 -1
- package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
- package/dist/src/algorithms/community/girvan-newman.d.ts +2 -3
- package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -1
- package/dist/src/algorithms/community/girvan-newman.js +21 -4
- package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
- package/dist/src/algorithms/community/index.d.ts.map +1 -1
- package/dist/src/algorithms/community/index.js.map +1 -1
- package/dist/src/algorithms/community/label-propagation.d.ts +0 -3
- package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -1
- package/dist/src/algorithms/community/label-propagation.js +13 -6
- package/dist/src/algorithms/community/label-propagation.js.map +1 -1
- package/dist/src/algorithms/community/leiden.d.ts +0 -1
- package/dist/src/algorithms/community/leiden.d.ts.map +1 -1
- package/dist/src/algorithms/community/leiden.js +37 -6
- package/dist/src/algorithms/community/leiden.js.map +1 -1
- package/dist/src/algorithms/community/louvain-optimized.d.ts +37 -0
- package/dist/src/algorithms/community/louvain-optimized.d.ts.map +1 -1
- package/dist/src/algorithms/community/louvain-optimized.js +42 -7
- package/dist/src/algorithms/community/louvain-optimized.js.map +1 -1
- package/dist/src/algorithms/community/louvain.d.ts +2 -3
- package/dist/src/algorithms/community/louvain.d.ts.map +1 -1
- package/dist/src/algorithms/community/louvain.js +19 -6
- package/dist/src/algorithms/community/louvain.js.map +1 -1
- package/dist/src/algorithms/community/modularity-utils.d.ts +0 -4
- package/dist/src/algorithms/community/modularity-utils.d.ts.map +1 -1
- package/dist/src/algorithms/community/modularity-utils.js +1 -5
- package/dist/src/algorithms/community/modularity-utils.js.map +1 -1
- package/dist/src/algorithms/components/connected.d.ts +23 -0
- package/dist/src/algorithms/components/connected.d.ts.map +1 -1
- package/dist/src/algorithms/components/connected.js +29 -3
- package/dist/src/algorithms/components/connected.js.map +1 -1
- package/dist/src/algorithms/matching/bipartite.d.ts +10 -0
- package/dist/src/algorithms/matching/bipartite.d.ts.map +1 -1
- package/dist/src/algorithms/matching/bipartite.js +10 -0
- package/dist/src/algorithms/matching/bipartite.js.map +1 -1
- package/dist/src/algorithms/matching/index.d.ts.map +1 -1
- package/dist/src/algorithms/matching/index.js.map +1 -1
- package/dist/src/algorithms/matching/isomorphism.d.ts +8 -0
- package/dist/src/algorithms/matching/isomorphism.d.ts.map +1 -1
- package/dist/src/algorithms/matching/isomorphism.js +36 -2
- package/dist/src/algorithms/matching/isomorphism.js.map +1 -1
- package/dist/src/algorithms/mst/index.d.ts.map +1 -1
- package/dist/src/algorithms/mst/index.js.map +1 -1
- package/dist/src/algorithms/mst/kruskal.d.ts +14 -0
- package/dist/src/algorithms/mst/kruskal.d.ts.map +1 -1
- package/dist/src/algorithms/mst/kruskal.js +17 -3
- package/dist/src/algorithms/mst/kruskal.js.map +1 -1
- package/dist/src/algorithms/mst/prim.d.ts +9 -0
- package/dist/src/algorithms/mst/prim.d.ts.map +1 -1
- package/dist/src/algorithms/mst/prim.js +9 -0
- package/dist/src/algorithms/mst/prim.js.map +1 -1
- package/dist/src/algorithms/shortest-path/bellman-ford.d.ts +10 -0
- package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/bellman-ford.js +10 -0
- package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts +12 -5
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js +19 -17
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js.map +1 -1
- package/dist/src/algorithms/shortest-path/dijkstra.d.ts +15 -0
- package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/dijkstra.js +15 -0
- package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
- package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts +17 -0
- package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/floyd-warshall.js +17 -0
- package/dist/src/algorithms/shortest-path/floyd-warshall.js.map +1 -1
- package/dist/src/algorithms/shortest-path/index.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/index.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs-unified.d.ts +13 -0
- package/dist/src/algorithms/traversal/bfs-unified.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs-unified.js +37 -0
- package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs-variants.d.ts +23 -0
- package/dist/src/algorithms/traversal/bfs-variants.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs-variants.js +34 -0
- package/dist/src/algorithms/traversal/bfs-variants.js.map +1 -1
- package/dist/src/algorithms/traversal/bfs.d.ts +1 -1
- package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/bfs.js +1 -1
- package/dist/src/algorithms/traversal/bfs.js.map +1 -1
- package/dist/src/algorithms/traversal/dfs.d.ts +10 -0
- package/dist/src/algorithms/traversal/dfs.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/dfs.js +48 -0
- package/dist/src/algorithms/traversal/dfs.js.map +1 -1
- package/dist/src/algorithms/traversal/index.d.ts.map +1 -1
- package/dist/src/algorithms/traversal/index.js.map +1 -1
- package/dist/src/benchmark-all-algorithms.d.ts +2 -0
- package/dist/src/benchmark-all-algorithms.d.ts.map +1 -1
- package/dist/src/benchmark-all-algorithms.js +32 -3
- package/dist/src/benchmark-all-algorithms.js.map +1 -1
- package/dist/src/clustering/hierarchical.d.ts +8 -1
- package/dist/src/clustering/hierarchical.d.ts.map +1 -1
- package/dist/src/clustering/hierarchical.js +22 -6
- package/dist/src/clustering/hierarchical.js.map +1 -1
- package/dist/src/clustering/index.d.ts.map +1 -1
- package/dist/src/clustering/index.js.map +1 -1
- package/dist/src/clustering/k-core.d.ts +2 -5
- package/dist/src/clustering/k-core.d.ts.map +1 -1
- package/dist/src/clustering/k-core.js +14 -12
- package/dist/src/clustering/k-core.js.map +1 -1
- package/dist/src/clustering/mcl.d.ts +6 -0
- package/dist/src/clustering/mcl.d.ts.map +1 -1
- package/dist/src/clustering/mcl.js +34 -3
- package/dist/src/clustering/mcl.js.map +1 -1
- package/dist/src/clustering/spectral.d.ts +4 -1
- package/dist/src/clustering/spectral.d.ts.map +1 -1
- package/dist/src/clustering/spectral.js +61 -28
- package/dist/src/clustering/spectral.js.map +1 -1
- package/dist/src/core/graph.d.ts +45 -0
- package/dist/src/core/graph.d.ts.map +1 -1
- package/dist/src/core/graph.js +45 -1
- package/dist/src/core/graph.js.map +1 -1
- package/dist/src/data-structures/index.d.ts.map +1 -1
- package/dist/src/data-structures/index.js.map +1 -1
- package/dist/src/data-structures/priority-queue.d.ts +18 -1
- package/dist/src/data-structures/priority-queue.d.ts.map +1 -1
- package/dist/src/data-structures/priority-queue.js +26 -5
- package/dist/src/data-structures/priority-queue.js.map +1 -1
- package/dist/src/data-structures/union-find.d.ts +21 -0
- package/dist/src/data-structures/union-find.d.ts.map +1 -1
- package/dist/src/data-structures/union-find.js +21 -0
- package/dist/src/data-structures/union-find.js.map +1 -1
- package/dist/src/flow/ford-fulkerson.d.ts +4 -2
- package/dist/src/flow/ford-fulkerson.d.ts.map +1 -1
- package/dist/src/flow/ford-fulkerson.js +31 -2
- package/dist/src/flow/ford-fulkerson.js.map +1 -1
- package/dist/src/flow/min-cut.d.ts +0 -3
- package/dist/src/flow/min-cut.d.ts.map +1 -1
- package/dist/src/flow/min-cut.js +17 -4
- package/dist/src/flow/min-cut.js.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/link-prediction/adamic-adar.d.ts +26 -0
- package/dist/src/link-prediction/adamic-adar.d.ts.map +1 -1
- package/dist/src/link-prediction/adamic-adar.js +36 -10
- package/dist/src/link-prediction/adamic-adar.js.map +1 -1
- package/dist/src/link-prediction/common-neighbors.d.ts +21 -0
- package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -1
- package/dist/src/link-prediction/common-neighbors.js +27 -6
- package/dist/src/link-prediction/common-neighbors.js.map +1 -1
- package/dist/src/link-prediction/index.d.ts.map +1 -1
- package/dist/src/optimized/bit-packed.d.ts +103 -53
- package/dist/src/optimized/bit-packed.d.ts.map +1 -1
- package/dist/src/optimized/bit-packed.js +104 -54
- package/dist/src/optimized/bit-packed.js.map +1 -1
- package/dist/src/optimized/csr-graph.d.ts +87 -24
- package/dist/src/optimized/csr-graph.d.ts.map +1 -1
- package/dist/src/optimized/csr-graph.js +87 -24
- package/dist/src/optimized/csr-graph.js.map +1 -1
- package/dist/src/optimized/direction-optimized-bfs.d.ts +37 -16
- package/dist/src/optimized/direction-optimized-bfs.d.ts.map +1 -1
- package/dist/src/optimized/direction-optimized-bfs.js +39 -20
- package/dist/src/optimized/direction-optimized-bfs.js.map +1 -1
- package/dist/src/optimized/graph-adapter.d.ts +58 -9
- package/dist/src/optimized/graph-adapter.d.ts.map +1 -1
- package/dist/src/optimized/graph-adapter.js +58 -10
- package/dist/src/optimized/graph-adapter.js.map +1 -1
- package/dist/src/optimized/index.d.ts +1 -1
- package/dist/src/optimized/index.d.ts.map +1 -1
- package/dist/src/optimized/index.js +3 -1
- package/dist/src/optimized/index.js.map +1 -1
- package/dist/src/pathfinding/astar.d.ts +25 -9
- package/dist/src/pathfinding/astar.d.ts.map +1 -1
- package/dist/src/pathfinding/astar.js +25 -10
- package/dist/src/pathfinding/astar.js.map +1 -1
- package/dist/src/pathfinding/utils.d.ts +15 -6
- package/dist/src/pathfinding/utils.d.ts.map +1 -1
- package/dist/src/pathfinding/utils.js +19 -7
- package/dist/src/pathfinding/utils.js.map +1 -1
- package/dist/src/research/grsbm.d.ts +0 -1
- package/dist/src/research/grsbm.d.ts.map +1 -1
- package/dist/src/research/grsbm.js +23 -10
- package/dist/src/research/grsbm.js.map +1 -1
- package/dist/src/research/index.d.ts.map +1 -1
- package/dist/src/research/index.js.map +1 -1
- package/dist/src/research/sync.d.ts +0 -1
- package/dist/src/research/sync.d.ts.map +1 -1
- package/dist/src/research/sync.js +29 -8
- package/dist/src/research/sync.js.map +1 -1
- package/dist/src/research/terahac.d.ts +0 -1
- package/dist/src/research/terahac.d.ts.map +1 -1
- package/dist/src/research/terahac.js +32 -4
- package/dist/src/research/terahac.js.map +1 -1
- package/dist/src/utils/graph-converters.d.ts +31 -0
- package/dist/src/utils/graph-converters.d.ts.map +1 -1
- package/dist/src/utils/graph-converters.js +31 -0
- package/dist/src/utils/graph-converters.js.map +1 -1
- package/dist/src/utils/graph-utilities.d.ts.map +1 -1
- package/dist/src/utils/graph-utilities.js.map +1 -1
- package/dist/src/utils/math-utilities.d.ts +11 -0
- package/dist/src/utils/math-utilities.d.ts.map +1 -1
- package/dist/src/utils/math-utilities.js +14 -5
- package/dist/src/utils/math-utilities.js.map +1 -1
- package/dist/src/utils/optimization-helpers.d.ts +9 -0
- package/dist/src/utils/optimization-helpers.d.ts.map +1 -1
- package/dist/src/utils/optimization-helpers.js +12 -0
- package/dist/src/utils/optimization-helpers.js.map +1 -1
- package/dist/src/utils/priorityQueue.d.ts +24 -0
- package/dist/src/utils/priorityQueue.d.ts.map +1 -1
- package/dist/src/utils/priorityQueue.js +34 -4
- package/dist/src/utils/priorityQueue.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +56 -65
- package/src/algorithms/centrality/betweenness.ts +34 -17
- package/src/algorithms/centrality/closeness.ts +34 -17
- package/src/algorithms/centrality/degree.ts +15 -19
- package/src/algorithms/centrality/delta-pagerank-simple.ts +36 -28
- package/src/algorithms/centrality/delta-pagerank.ts +34 -11
- package/src/algorithms/centrality/eigenvector.ts +14 -15
- package/src/algorithms/centrality/hits.ts +17 -17
- package/src/algorithms/centrality/index.ts +20 -15
- package/src/algorithms/centrality/katz.ts +17 -25
- package/src/algorithms/centrality/pagerank.ts +26 -17
- package/src/algorithms/community/girvan-newman.ts +39 -28
- package/src/algorithms/community/index.ts +6 -7
- package/src/algorithms/community/label-propagation.ts +20 -28
- package/src/algorithms/community/leiden.ts +61 -37
- package/src/algorithms/community/louvain-optimized.ts +49 -20
- package/src/algorithms/community/louvain.ts +35 -25
- package/src/algorithms/community/modularity-utils.ts +5 -17
- package/src/algorithms/components/connected.ts +40 -17
- package/src/algorithms/matching/bipartite.ts +17 -10
- package/src/algorithms/matching/index.ts +4 -4
- package/src/algorithms/matching/isomorphism.ts +53 -23
- package/src/algorithms/mst/index.ts +3 -4
- package/src/algorithms/mst/kruskal.ts +21 -6
- package/src/algorithms/mst/prim.ts +13 -4
- package/src/algorithms/shortest-path/bellman-ford.ts +16 -15
- package/src/algorithms/shortest-path/bidirectional-dijkstra.ts +29 -29
- package/src/algorithms/shortest-path/dijkstra.ts +23 -17
- package/src/algorithms/shortest-path/floyd-warshall.ts +21 -4
- package/src/algorithms/shortest-path/index.ts +5 -5
- package/src/algorithms/traversal/bfs-unified.ts +64 -60
- package/src/algorithms/traversal/bfs-variants.ts +61 -37
- package/src/algorithms/traversal/bfs.ts +1 -7
- package/src/algorithms/traversal/dfs.ts +61 -42
- package/src/algorithms/traversal/index.ts +3 -3
- package/src/benchmark-all-algorithms.ts +57 -25
- package/src/clustering/hierarchical.ts +40 -34
- package/src/clustering/index.ts +8 -8
- package/src/clustering/k-core.ts +26 -42
- package/src/clustering/mcl.ts +53 -23
- package/src/clustering/spectral.ts +91 -57
- package/src/core/graph.ts +54 -14
- package/src/data-structures/index.ts +2 -2
- package/src/data-structures/priority-queue.ts +36 -11
- package/src/data-structures/union-find.ts +22 -1
- package/src/flow/ford-fulkerson.ts +62 -35
- package/src/flow/min-cut.ts +43 -45
- package/src/index.ts +3 -2
- package/src/link-prediction/adamic-adar.ts +65 -51
- package/src/link-prediction/common-neighbors.ts +45 -36
- package/src/link-prediction/index.ts +1 -1
- package/src/optimized/bit-packed.ts +106 -56
- package/src/optimized/csr-graph.ts +93 -30
- package/src/optimized/direction-optimized-bfs.ts +44 -25
- package/src/optimized/graph-adapter.ts +64 -16
- package/src/optimized/index.ts +7 -9
- package/src/pathfinding/astar.ts +40 -25
- package/src/pathfinding/utils.ts +20 -13
- package/src/research/grsbm.ts +31 -25
- package/src/research/index.ts +4 -4
- package/src/research/sync.ts +40 -24
- package/src/research/terahac.ts +54 -20
- package/src/utils/graph-converters.ts +42 -14
- package/src/utils/graph-utilities.ts +11 -37
- package/src/utils/math-utilities.ts +17 -8
- package/src/utils/optimization-helpers.ts +27 -21
- package/src/utils/priorityQueue.ts +40 -6
package/src/core/graph.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {Edge, GraphConfig, Node, NodeId} from "../types/index.js";
|
|
1
|
+
import type { Edge, GraphConfig, Node, NodeId } from "../types/index.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Core Graph data structure for the Graphty Algorithms library
|
|
@@ -13,12 +13,16 @@ export class Graph {
|
|
|
13
13
|
private config: GraphConfig;
|
|
14
14
|
private edgeCount: number;
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Creates a new Graph instance.
|
|
18
|
+
* @param config - Configuration options for the graph
|
|
19
|
+
*/
|
|
16
20
|
constructor(config: Partial<GraphConfig> = {}) {
|
|
17
21
|
this.config = {
|
|
18
22
|
directed: false,
|
|
19
23
|
allowSelfLoops: true,
|
|
20
24
|
allowParallelEdges: false,
|
|
21
|
-
...
|
|
25
|
+
...config,
|
|
22
26
|
};
|
|
23
27
|
this.nodeMap = new Map();
|
|
24
28
|
this.adjacencyList = new Map();
|
|
@@ -28,10 +32,12 @@ export class Graph {
|
|
|
28
32
|
|
|
29
33
|
/**
|
|
30
34
|
* Add a node to the graph
|
|
35
|
+
* @param id - The unique identifier for the node
|
|
36
|
+
* @param data - Optional key-value data to attach to the node
|
|
31
37
|
*/
|
|
32
38
|
addNode(id: NodeId, data?: Record<string, unknown>): void {
|
|
33
39
|
if (!this.nodeMap.has(id)) {
|
|
34
|
-
this.nodeMap.set(id, {id, data});
|
|
40
|
+
this.nodeMap.set(id, { id, data });
|
|
35
41
|
this.adjacencyList.set(id, new Map());
|
|
36
42
|
|
|
37
43
|
if (this.config.directed) {
|
|
@@ -42,6 +48,8 @@ export class Graph {
|
|
|
42
48
|
|
|
43
49
|
/**
|
|
44
50
|
* Remove a node from the graph
|
|
51
|
+
* @param id - The unique identifier of the node to remove
|
|
52
|
+
* @returns True if the node was removed, false if it did not exist
|
|
45
53
|
*/
|
|
46
54
|
removeNode(id: NodeId): boolean {
|
|
47
55
|
if (!this.nodeMap.has(id)) {
|
|
@@ -85,6 +93,10 @@ export class Graph {
|
|
|
85
93
|
|
|
86
94
|
/**
|
|
87
95
|
* Add an edge to the graph
|
|
96
|
+
* @param source - The source node identifier
|
|
97
|
+
* @param target - The target node identifier
|
|
98
|
+
* @param weight - The weight of the edge (defaults to 1)
|
|
99
|
+
* @param data - Optional key-value data to attach to the edge
|
|
88
100
|
*/
|
|
89
101
|
addEdge(source: NodeId, target: NodeId, weight = 1, data?: Record<string, unknown>): void {
|
|
90
102
|
// Ensure both nodes exist
|
|
@@ -101,7 +113,7 @@ export class Graph {
|
|
|
101
113
|
throw new Error("Parallel edges are not allowed in this graph");
|
|
102
114
|
}
|
|
103
115
|
|
|
104
|
-
const edge: Edge = {source, target, weight, data};
|
|
116
|
+
const edge: Edge = { source, target, weight, data };
|
|
105
117
|
|
|
106
118
|
// Add to adjacency list
|
|
107
119
|
const sourceAdjacency = this.adjacencyList.get(source);
|
|
@@ -120,7 +132,7 @@ export class Graph {
|
|
|
120
132
|
} else {
|
|
121
133
|
// For undirected graphs, add the reverse edge
|
|
122
134
|
if (source !== target) {
|
|
123
|
-
const reverseEdge: Edge = {source: target, target: source, weight, data};
|
|
135
|
+
const reverseEdge: Edge = { source: target, target: source, weight, data };
|
|
124
136
|
const targetAdjacency = this.adjacencyList.get(target);
|
|
125
137
|
|
|
126
138
|
if (targetAdjacency) {
|
|
@@ -134,6 +146,9 @@ export class Graph {
|
|
|
134
146
|
|
|
135
147
|
/**
|
|
136
148
|
* Remove an edge from the graph
|
|
149
|
+
* @param source - The source node identifier
|
|
150
|
+
* @param target - The target node identifier
|
|
151
|
+
* @returns True if the edge was removed, false if it did not exist
|
|
137
152
|
*/
|
|
138
153
|
removeEdge(source: NodeId, target: NodeId): boolean {
|
|
139
154
|
const sourceEdges = this.adjacencyList.get(source);
|
|
@@ -162,6 +177,8 @@ export class Graph {
|
|
|
162
177
|
|
|
163
178
|
/**
|
|
164
179
|
* Check if a node exists in the graph
|
|
180
|
+
* @param id - The unique identifier of the node to check
|
|
181
|
+
* @returns True if the node exists, false otherwise
|
|
165
182
|
*/
|
|
166
183
|
hasNode(id: NodeId): boolean {
|
|
167
184
|
return this.nodeMap.has(id);
|
|
@@ -169,6 +186,9 @@ export class Graph {
|
|
|
169
186
|
|
|
170
187
|
/**
|
|
171
188
|
* Check if an edge exists in the graph
|
|
189
|
+
* @param source - The source node identifier
|
|
190
|
+
* @param target - The target node identifier
|
|
191
|
+
* @returns True if the edge exists, false otherwise
|
|
172
192
|
*/
|
|
173
193
|
hasEdge(source: NodeId, target: NodeId): boolean {
|
|
174
194
|
const sourceEdges = this.adjacencyList.get(source);
|
|
@@ -177,6 +197,8 @@ export class Graph {
|
|
|
177
197
|
|
|
178
198
|
/**
|
|
179
199
|
* Get a node by ID
|
|
200
|
+
* @param id - The unique identifier of the node to retrieve
|
|
201
|
+
* @returns The node if found, undefined otherwise
|
|
180
202
|
*/
|
|
181
203
|
getNode(id: NodeId): Node | undefined {
|
|
182
204
|
return this.nodeMap.get(id);
|
|
@@ -184,6 +206,9 @@ export class Graph {
|
|
|
184
206
|
|
|
185
207
|
/**
|
|
186
208
|
* Get an edge by source and target
|
|
209
|
+
* @param source - The source node identifier
|
|
210
|
+
* @param target - The target node identifier
|
|
211
|
+
* @returns The edge if found, undefined otherwise
|
|
187
212
|
*/
|
|
188
213
|
getEdge(source: NodeId, target: NodeId): Edge | undefined {
|
|
189
214
|
const sourceEdges = this.adjacencyList.get(source);
|
|
@@ -192,6 +217,7 @@ export class Graph {
|
|
|
192
217
|
|
|
193
218
|
/**
|
|
194
219
|
* Get the number of nodes in the graph
|
|
220
|
+
* @returns The total count of nodes
|
|
195
221
|
*/
|
|
196
222
|
get nodeCount(): number {
|
|
197
223
|
return this.nodeMap.size;
|
|
@@ -199,6 +225,7 @@ export class Graph {
|
|
|
199
225
|
|
|
200
226
|
/**
|
|
201
227
|
* Get the number of edges in the graph
|
|
228
|
+
* @returns The total count of edges
|
|
202
229
|
*/
|
|
203
230
|
get totalEdgeCount(): number {
|
|
204
231
|
return this.edgeCount;
|
|
@@ -206,6 +233,7 @@ export class Graph {
|
|
|
206
233
|
|
|
207
234
|
/**
|
|
208
235
|
* Check if the graph is directed
|
|
236
|
+
* @returns True if the graph is directed, false otherwise
|
|
209
237
|
*/
|
|
210
238
|
get isDirected(): boolean {
|
|
211
239
|
return this.config.directed;
|
|
@@ -213,6 +241,7 @@ export class Graph {
|
|
|
213
241
|
|
|
214
242
|
/**
|
|
215
243
|
* Get all nodes in the graph
|
|
244
|
+
* @returns An iterator over all nodes
|
|
216
245
|
*/
|
|
217
246
|
nodes(): IterableIterator<Node> {
|
|
218
247
|
return this.nodeMap.values();
|
|
@@ -220,6 +249,7 @@ export class Graph {
|
|
|
220
249
|
|
|
221
250
|
/**
|
|
222
251
|
* Get all edges in the graph
|
|
252
|
+
* @yields Each unique edge in the graph
|
|
223
253
|
*/
|
|
224
254
|
*edges(): IterableIterator<Edge> {
|
|
225
255
|
for (const [source, edges] of this.adjacencyList) {
|
|
@@ -236,6 +266,8 @@ export class Graph {
|
|
|
236
266
|
|
|
237
267
|
/**
|
|
238
268
|
* Get neighbors of a node (outgoing edges)
|
|
269
|
+
* @param nodeId - The node identifier to get neighbors for
|
|
270
|
+
* @returns An iterator over the neighbor node identifiers
|
|
239
271
|
*/
|
|
240
272
|
neighbors(nodeId: NodeId): IterableIterator<NodeId> {
|
|
241
273
|
const edges = this.adjacencyList.get(nodeId);
|
|
@@ -244,6 +276,8 @@ export class Graph {
|
|
|
244
276
|
|
|
245
277
|
/**
|
|
246
278
|
* Get incoming neighbors of a node (directed graphs only)
|
|
279
|
+
* @param nodeId - The node identifier to get incoming neighbors for
|
|
280
|
+
* @returns An iterator over the incoming neighbor node identifiers
|
|
247
281
|
*/
|
|
248
282
|
inNeighbors(nodeId: NodeId): IterableIterator<NodeId> {
|
|
249
283
|
if (!this.config.directed) {
|
|
@@ -256,6 +290,8 @@ export class Graph {
|
|
|
256
290
|
|
|
257
291
|
/**
|
|
258
292
|
* Get outgoing neighbors of a node
|
|
293
|
+
* @param nodeId - The node identifier to get outgoing neighbors for
|
|
294
|
+
* @returns An iterator over the outgoing neighbor node identifiers
|
|
259
295
|
*/
|
|
260
296
|
outNeighbors(nodeId: NodeId): IterableIterator<NodeId> {
|
|
261
297
|
return this.neighbors(nodeId);
|
|
@@ -263,6 +299,8 @@ export class Graph {
|
|
|
263
299
|
|
|
264
300
|
/**
|
|
265
301
|
* Get the degree of a node
|
|
302
|
+
* @param nodeId - The node identifier to get the degree for
|
|
303
|
+
* @returns The total degree of the node
|
|
266
304
|
*/
|
|
267
305
|
degree(nodeId: NodeId): number {
|
|
268
306
|
if (this.config.directed) {
|
|
@@ -275,6 +313,8 @@ export class Graph {
|
|
|
275
313
|
|
|
276
314
|
/**
|
|
277
315
|
* Get the in-degree of a node
|
|
316
|
+
* @param nodeId - The node identifier to get the in-degree for
|
|
317
|
+
* @returns The number of incoming edges to the node
|
|
278
318
|
*/
|
|
279
319
|
inDegree(nodeId: NodeId): number {
|
|
280
320
|
if (!this.config.directed) {
|
|
@@ -287,6 +327,8 @@ export class Graph {
|
|
|
287
327
|
|
|
288
328
|
/**
|
|
289
329
|
* Get the out-degree of a node
|
|
330
|
+
* @param nodeId - The node identifier to get the out-degree for
|
|
331
|
+
* @returns The number of outgoing edges from the node
|
|
290
332
|
*/
|
|
291
333
|
outDegree(nodeId: NodeId): number {
|
|
292
334
|
const edges = this.adjacencyList.get(nodeId);
|
|
@@ -295,23 +337,19 @@ export class Graph {
|
|
|
295
337
|
|
|
296
338
|
/**
|
|
297
339
|
* Create a copy of the graph
|
|
340
|
+
* @returns A new Graph instance with the same nodes and edges
|
|
298
341
|
*/
|
|
299
342
|
clone(): Graph {
|
|
300
343
|
const cloned = new Graph(this.config);
|
|
301
344
|
|
|
302
345
|
// Copy nodes
|
|
303
346
|
for (const node of this.nodeMap.values()) {
|
|
304
|
-
cloned.addNode(node.id, node.data ? {...
|
|
347
|
+
cloned.addNode(node.id, node.data ? { ...node.data } : undefined);
|
|
305
348
|
}
|
|
306
349
|
|
|
307
350
|
// Copy edges
|
|
308
351
|
for (const edge of this.edges()) {
|
|
309
|
-
cloned.addEdge(
|
|
310
|
-
edge.source,
|
|
311
|
-
edge.target,
|
|
312
|
-
edge.weight,
|
|
313
|
-
edge.data ? {... edge.data} : undefined,
|
|
314
|
-
);
|
|
352
|
+
cloned.addEdge(edge.source, edge.target, edge.weight, edge.data ? { ...edge.data } : undefined);
|
|
315
353
|
}
|
|
316
354
|
|
|
317
355
|
return cloned;
|
|
@@ -319,9 +357,10 @@ export class Graph {
|
|
|
319
357
|
|
|
320
358
|
/**
|
|
321
359
|
* Get graph configuration
|
|
360
|
+
* @returns A copy of the graph configuration object
|
|
322
361
|
*/
|
|
323
362
|
getConfig(): GraphConfig {
|
|
324
|
-
return {...
|
|
363
|
+
return { ...this.config };
|
|
325
364
|
}
|
|
326
365
|
|
|
327
366
|
/**
|
|
@@ -337,6 +376,7 @@ export class Graph {
|
|
|
337
376
|
/**
|
|
338
377
|
* Get the number of unique edges in the graph
|
|
339
378
|
* For undirected graphs, each edge is counted once
|
|
379
|
+
* @returns The count of unique edges
|
|
340
380
|
*/
|
|
341
381
|
get uniqueEdgeCount(): number {
|
|
342
382
|
if (this.config.directed) {
|
|
@@ -345,7 +385,7 @@ export class Graph {
|
|
|
345
385
|
|
|
346
386
|
// For undirected graphs, we need to count each edge only once
|
|
347
387
|
let count = 0;
|
|
348
|
-
|
|
388
|
+
|
|
349
389
|
for (const _edge of this.edges()) {
|
|
350
390
|
count++;
|
|
351
391
|
}
|
|
@@ -5,9 +5,13 @@
|
|
|
5
5
|
* Uses a min-heap by default but supports custom comparison functions.
|
|
6
6
|
*/
|
|
7
7
|
export class PriorityQueue<T> {
|
|
8
|
-
private heap: {item: T
|
|
8
|
+
private heap: { item: T; priority: number }[];
|
|
9
9
|
private compareFn: (a: number, b: number) => number;
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new PriorityQueue instance.
|
|
13
|
+
* @param compareFn - Custom comparison function for priorities. Returns negative if a has higher priority than b.
|
|
14
|
+
*/
|
|
11
15
|
constructor(compareFn?: (a: number, b: number) => number) {
|
|
12
16
|
this.heap = [];
|
|
13
17
|
// Default to min-heap (smaller priority values have higher priority)
|
|
@@ -16,15 +20,18 @@ export class PriorityQueue<T> {
|
|
|
16
20
|
|
|
17
21
|
/**
|
|
18
22
|
* Add an item with the given priority to the queue
|
|
23
|
+
* @param item - The item to add to the queue
|
|
24
|
+
* @param priority - The priority value for the item (lower values have higher priority in min-heap)
|
|
19
25
|
*/
|
|
20
26
|
enqueue(item: T, priority: number): void {
|
|
21
|
-
const element = {item, priority};
|
|
27
|
+
const element = { item, priority };
|
|
22
28
|
this.heap.push(element);
|
|
23
29
|
this.heapifyUp(this.heap.length - 1);
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
/**
|
|
27
33
|
* Remove and return the item with the highest priority
|
|
34
|
+
* @returns The item with the highest priority, or undefined if the queue is empty
|
|
28
35
|
*/
|
|
29
36
|
dequeue(): T | undefined {
|
|
30
37
|
if (this.heap.length === 0) {
|
|
@@ -52,6 +59,7 @@ export class PriorityQueue<T> {
|
|
|
52
59
|
|
|
53
60
|
/**
|
|
54
61
|
* View the item with the highest priority without removing it
|
|
62
|
+
* @returns The item with the highest priority, or undefined if the queue is empty
|
|
55
63
|
*/
|
|
56
64
|
peek(): T | undefined {
|
|
57
65
|
const first = this.heap[0];
|
|
@@ -60,6 +68,7 @@ export class PriorityQueue<T> {
|
|
|
60
68
|
|
|
61
69
|
/**
|
|
62
70
|
* Check if the queue is empty
|
|
71
|
+
* @returns True if the queue has no items, false otherwise
|
|
63
72
|
*/
|
|
64
73
|
isEmpty(): boolean {
|
|
65
74
|
return this.heap.length === 0;
|
|
@@ -67,6 +76,7 @@ export class PriorityQueue<T> {
|
|
|
67
76
|
|
|
68
77
|
/**
|
|
69
78
|
* Get the number of items in the queue
|
|
79
|
+
* @returns The number of items currently in the queue
|
|
70
80
|
*/
|
|
71
81
|
size(): number {
|
|
72
82
|
return this.heap.length;
|
|
@@ -74,7 +84,9 @@ export class PriorityQueue<T> {
|
|
|
74
84
|
|
|
75
85
|
/**
|
|
76
86
|
* Update the priority of an item if it exists in the queue
|
|
77
|
-
*
|
|
87
|
+
* @param item - The item whose priority should be updated
|
|
88
|
+
* @param newPriority - The new priority value for the item
|
|
89
|
+
* @returns True if the item was found and updated, false otherwise
|
|
78
90
|
*/
|
|
79
91
|
updatePriority(item: T, newPriority: number): boolean {
|
|
80
92
|
const index = this.heap.findIndex((element) => element.item === item);
|
|
@@ -110,13 +122,15 @@ export class PriorityQueue<T> {
|
|
|
110
122
|
|
|
111
123
|
/**
|
|
112
124
|
* Convert queue to array (for testing/debugging)
|
|
125
|
+
* @returns An array of all items with their priorities
|
|
113
126
|
*/
|
|
114
|
-
toArray(): {item: T
|
|
115
|
-
return [...
|
|
127
|
+
toArray(): { item: T; priority: number }[] {
|
|
128
|
+
return [...this.heap];
|
|
116
129
|
}
|
|
117
130
|
|
|
118
131
|
/**
|
|
119
132
|
* Move element up the heap until heap property is satisfied
|
|
133
|
+
* @param index - The index of the element to heapify up
|
|
120
134
|
*/
|
|
121
135
|
private heapifyUp(index: number): void {
|
|
122
136
|
if (index === 0) {
|
|
@@ -136,26 +150,35 @@ export class PriorityQueue<T> {
|
|
|
136
150
|
|
|
137
151
|
/**
|
|
138
152
|
* Move element down the heap until heap property is satisfied
|
|
153
|
+
* @param index - The index of the element to heapify down
|
|
139
154
|
*/
|
|
140
155
|
private heapifyDown(index: number): void {
|
|
141
|
-
const leftChildIndex =
|
|
142
|
-
const rightChildIndex =
|
|
156
|
+
const leftChildIndex = 2 * index + 1;
|
|
157
|
+
const rightChildIndex = 2 * index + 2;
|
|
143
158
|
let targetIndex = index;
|
|
144
159
|
|
|
145
160
|
// Find the child with highest priority (lowest value for min-heap)
|
|
146
161
|
const leftChild = this.heap[leftChildIndex];
|
|
147
162
|
const target = this.heap[targetIndex];
|
|
148
163
|
|
|
149
|
-
if (
|
|
150
|
-
this.
|
|
164
|
+
if (
|
|
165
|
+
leftChildIndex < this.heap.length &&
|
|
166
|
+
leftChild &&
|
|
167
|
+
target &&
|
|
168
|
+
this.compareFn(leftChild.priority, target.priority) < 0
|
|
169
|
+
) {
|
|
151
170
|
targetIndex = leftChildIndex;
|
|
152
171
|
}
|
|
153
172
|
|
|
154
173
|
const rightChild = this.heap[rightChildIndex];
|
|
155
174
|
const newTarget = this.heap[targetIndex];
|
|
156
175
|
|
|
157
|
-
if (
|
|
158
|
-
this.
|
|
176
|
+
if (
|
|
177
|
+
rightChildIndex < this.heap.length &&
|
|
178
|
+
rightChild &&
|
|
179
|
+
newTarget &&
|
|
180
|
+
this.compareFn(rightChild.priority, newTarget.priority) < 0
|
|
181
|
+
) {
|
|
159
182
|
targetIndex = rightChildIndex;
|
|
160
183
|
}
|
|
161
184
|
|
|
@@ -168,6 +191,8 @@ export class PriorityQueue<T> {
|
|
|
168
191
|
|
|
169
192
|
/**
|
|
170
193
|
* Swap two elements in the heap
|
|
194
|
+
* @param i - Index of the first element
|
|
195
|
+
* @param j - Index of the second element
|
|
171
196
|
*/
|
|
172
197
|
private swap(i: number, j: number): void {
|
|
173
198
|
const temp = this.heap[i];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {NodeId} from "../types/index.js";
|
|
1
|
+
import type { NodeId } from "../types/index.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Union-Find (Disjoint Set) data structure with path compression and union by rank
|
|
@@ -11,6 +11,10 @@ export class UnionFind {
|
|
|
11
11
|
private rank: Map<NodeId, number>;
|
|
12
12
|
private componentCount: number;
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new UnionFind data structure with the given elements.
|
|
16
|
+
* @param elements - Array of elements to initialize the data structure with
|
|
17
|
+
*/
|
|
14
18
|
constructor(elements: NodeId[]) {
|
|
15
19
|
this.parent = new Map();
|
|
16
20
|
this.rank = new Map();
|
|
@@ -25,6 +29,8 @@ export class UnionFind {
|
|
|
25
29
|
|
|
26
30
|
/**
|
|
27
31
|
* Find the root of the set containing the element with path compression
|
|
32
|
+
* @param element - The element to find the root for
|
|
33
|
+
* @returns The root element of the set containing the given element
|
|
28
34
|
*/
|
|
29
35
|
find(element: NodeId): NodeId {
|
|
30
36
|
const parent = this.parent.get(element);
|
|
@@ -48,6 +54,8 @@ export class UnionFind {
|
|
|
48
54
|
|
|
49
55
|
/**
|
|
50
56
|
* Union two sets using union by rank
|
|
57
|
+
* @param elementA - The first element whose set should be merged
|
|
58
|
+
* @param elementB - The second element whose set should be merged
|
|
51
59
|
*/
|
|
52
60
|
union(elementA: NodeId, elementB: NodeId): void {
|
|
53
61
|
const rootA = this.find(elementA);
|
|
@@ -80,6 +88,9 @@ export class UnionFind {
|
|
|
80
88
|
|
|
81
89
|
/**
|
|
82
90
|
* Check if two elements are in the same connected component
|
|
91
|
+
* @param elementA - The first element to check
|
|
92
|
+
* @param elementB - The second element to check
|
|
93
|
+
* @returns True if both elements are in the same component, false otherwise
|
|
83
94
|
*/
|
|
84
95
|
connected(elementA: NodeId, elementB: NodeId): boolean {
|
|
85
96
|
try {
|
|
@@ -91,6 +102,7 @@ export class UnionFind {
|
|
|
91
102
|
|
|
92
103
|
/**
|
|
93
104
|
* Get the number of connected components
|
|
105
|
+
* @returns The current count of disjoint components
|
|
94
106
|
*/
|
|
95
107
|
getComponentCount(): number {
|
|
96
108
|
return this.componentCount;
|
|
@@ -98,6 +110,8 @@ export class UnionFind {
|
|
|
98
110
|
|
|
99
111
|
/**
|
|
100
112
|
* Get all elements that belong to the same component as the given element
|
|
113
|
+
* @param element - The element whose component should be retrieved
|
|
114
|
+
* @returns Array of all elements in the same component
|
|
101
115
|
*/
|
|
102
116
|
getComponent(element: NodeId): NodeId[] {
|
|
103
117
|
const root = this.find(element);
|
|
@@ -114,6 +128,7 @@ export class UnionFind {
|
|
|
114
128
|
|
|
115
129
|
/**
|
|
116
130
|
* Get all connected components as separate arrays
|
|
131
|
+
* @returns Array of arrays, where each inner array contains elements of one component
|
|
117
132
|
*/
|
|
118
133
|
getAllComponents(): NodeId[][] {
|
|
119
134
|
const componentMap = new Map<NodeId, NodeId[]>();
|
|
@@ -136,6 +151,8 @@ export class UnionFind {
|
|
|
136
151
|
|
|
137
152
|
/**
|
|
138
153
|
* Get the size of the component containing the given element
|
|
154
|
+
* @param element - The element whose component size should be retrieved
|
|
155
|
+
* @returns The number of elements in the component containing the given element
|
|
139
156
|
*/
|
|
140
157
|
getComponentSize(element: NodeId): number {
|
|
141
158
|
return this.getComponent(element).length;
|
|
@@ -143,6 +160,7 @@ export class UnionFind {
|
|
|
143
160
|
|
|
144
161
|
/**
|
|
145
162
|
* Add a new element to the data structure
|
|
163
|
+
* @param element - The element to add as a new singleton set
|
|
146
164
|
*/
|
|
147
165
|
addElement(element: NodeId): void {
|
|
148
166
|
if (this.parent.has(element)) {
|
|
@@ -156,6 +174,8 @@ export class UnionFind {
|
|
|
156
174
|
|
|
157
175
|
/**
|
|
158
176
|
* Check if an element exists in the data structure
|
|
177
|
+
* @param element - The element to check for
|
|
178
|
+
* @returns True if the element exists, false otherwise
|
|
159
179
|
*/
|
|
160
180
|
hasElement(element: NodeId): boolean {
|
|
161
181
|
return this.parent.has(element);
|
|
@@ -163,6 +183,7 @@ export class UnionFind {
|
|
|
163
183
|
|
|
164
184
|
/**
|
|
165
185
|
* Get the total number of elements
|
|
186
|
+
* @returns The total count of all elements in the data structure
|
|
166
187
|
*/
|
|
167
188
|
size(): number {
|
|
168
189
|
return this.parent.size;
|