@graphty/algorithms 1.3.1 → 1.4.2
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 +358 -413
- package/dist/algorithms.js +564 -261
- 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 +11 -4
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts.map +1 -1
- package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js +18 -16
- 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 +22 -9
- 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 +28 -7
- 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/package.json +49 -45
- 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 +28 -28
- 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 +30 -24
- package/src/research/index.ts +4 -4
- package/src/research/sync.ts +39 -23
- 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
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {NodeId} from "../types/index.js";
|
|
2
|
-
import {CompactDistanceArray, GraphBitSet} from "./bit-packed.js";
|
|
3
|
-
import {CSRGraph} from "./csr-graph.js";
|
|
1
|
+
import type { NodeId } from "../types/index.js";
|
|
2
|
+
import { CompactDistanceArray, GraphBitSet } from "./bit-packed.js";
|
|
3
|
+
import { CSRGraph } from "./csr-graph.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Options for Direction-Optimized BFS
|
|
@@ -40,6 +40,11 @@ export class DirectionOptimizedBFS<TNodeId = NodeId> {
|
|
|
40
40
|
private nextFrontier: GraphBitSet; // Next level frontier
|
|
41
41
|
private distances: CompactDistanceArray;
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Creates a new DirectionOptimizedBFS instance.
|
|
45
|
+
* @param graph - The CSR graph to perform BFS on
|
|
46
|
+
* @param options - Optional configuration for switching thresholds
|
|
47
|
+
*/
|
|
43
48
|
constructor(graph: CSRGraph<TNodeId>, options?: DirectionOptimizedBFSOptions) {
|
|
44
49
|
this.graph = graph;
|
|
45
50
|
this.alpha = options?.alpha ?? 15;
|
|
@@ -53,8 +58,10 @@ export class DirectionOptimizedBFS<TNodeId = NodeId> {
|
|
|
53
58
|
}
|
|
54
59
|
|
|
55
60
|
/**
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
* Perform BFS from a single source node.
|
|
62
|
+
* @param source - The source node ID to start the BFS from
|
|
63
|
+
* @returns The BFS result containing distances and parent pointers
|
|
64
|
+
*/
|
|
58
65
|
search(source: TNodeId): BFSResult<TNodeId> {
|
|
59
66
|
const sourceIndex = this.graph.nodeToIndex(source);
|
|
60
67
|
this.parent[sourceIndex] = -2; // Mark as source
|
|
@@ -76,8 +83,7 @@ export class DirectionOptimizedBFS<TNodeId = NodeId> {
|
|
|
76
83
|
|
|
77
84
|
if (useBottomUp) {
|
|
78
85
|
// Check if we should switch back to top-down
|
|
79
|
-
if (awakeCount >= oldAwakeCount ||
|
|
80
|
-
awakeCount > this.graph.nodeCount() / this.beta) {
|
|
86
|
+
if (awakeCount >= oldAwakeCount || awakeCount > this.graph.nodeCount() / this.beta) {
|
|
81
87
|
useBottomUp = false;
|
|
82
88
|
}
|
|
83
89
|
} else {
|
|
@@ -106,8 +112,9 @@ export class DirectionOptimizedBFS<TNodeId = NodeId> {
|
|
|
106
112
|
}
|
|
107
113
|
|
|
108
114
|
/**
|
|
109
|
-
|
|
110
|
-
|
|
115
|
+
* Top-down BFS step - explore from frontier.
|
|
116
|
+
* @returns The scout count (total degree of newly discovered nodes)
|
|
117
|
+
*/
|
|
111
118
|
private topDownStep(): number {
|
|
112
119
|
let scoutCount = 0;
|
|
113
120
|
|
|
@@ -129,8 +136,9 @@ export class DirectionOptimizedBFS<TNodeId = NodeId> {
|
|
|
129
136
|
}
|
|
130
137
|
|
|
131
138
|
/**
|
|
132
|
-
|
|
133
|
-
|
|
139
|
+
* Bottom-up BFS step - check unvisited nodes for frontier neighbors.
|
|
140
|
+
* @returns The number of newly discovered nodes
|
|
141
|
+
*/
|
|
134
142
|
private bottomUpStep(): number {
|
|
135
143
|
const nodeCount = this.graph.nodeCount();
|
|
136
144
|
let awakeCount = 0;
|
|
@@ -156,8 +164,9 @@ export class DirectionOptimizedBFS<TNodeId = NodeId> {
|
|
|
156
164
|
}
|
|
157
165
|
|
|
158
166
|
/**
|
|
159
|
-
|
|
160
|
-
|
|
167
|
+
* Calculate edges to check for switching heuristic.
|
|
168
|
+
* @returns The total number of outgoing edges from frontier nodes
|
|
169
|
+
*/
|
|
161
170
|
private calculateEdgesToCheck(): number {
|
|
162
171
|
let count = 0;
|
|
163
172
|
for (const node of this.frontier) {
|
|
@@ -167,8 +176,9 @@ export class DirectionOptimizedBFS<TNodeId = NodeId> {
|
|
|
167
176
|
}
|
|
168
177
|
|
|
169
178
|
/**
|
|
170
|
-
|
|
171
|
-
|
|
179
|
+
* Build result map from internal data structures.
|
|
180
|
+
* @returns The BFS result containing distances and parent pointers
|
|
181
|
+
*/
|
|
172
182
|
private buildResult(): BFSResult<TNodeId> {
|
|
173
183
|
const distances = new Map<TNodeId, number>();
|
|
174
184
|
const parents = new Map<TNodeId, TNodeId | null>();
|
|
@@ -194,14 +204,16 @@ export class DirectionOptimizedBFS<TNodeId = NodeId> {
|
|
|
194
204
|
}
|
|
195
205
|
}
|
|
196
206
|
|
|
197
|
-
return {distances, parents, visitedCount};
|
|
207
|
+
return { distances, parents, visitedCount };
|
|
198
208
|
}
|
|
199
209
|
|
|
200
210
|
/**
|
|
201
|
-
|
|
202
|
-
|
|
211
|
+
* Perform multi-source BFS from multiple source nodes.
|
|
212
|
+
* @param sources - Array of source node IDs to start the BFS from
|
|
213
|
+
* @returns The BFS result containing distances and parent pointers
|
|
214
|
+
*/
|
|
203
215
|
searchMultiple(sources: TNodeId[]): BFSResult<TNodeId> {
|
|
204
|
-
|
|
216
|
+
// Initialize multiple sources
|
|
205
217
|
for (const source of sources) {
|
|
206
218
|
const sourceIndex = this.graph.nodeToIndex(source);
|
|
207
219
|
this.parent[sourceIndex] = -2; // Mark as source
|
|
@@ -228,8 +240,7 @@ export class DirectionOptimizedBFS<TNodeId = NodeId> {
|
|
|
228
240
|
oldAwakeCount = awakeCount;
|
|
229
241
|
|
|
230
242
|
if (useBottomUp) {
|
|
231
|
-
if (awakeCount >= oldAwakeCount ||
|
|
232
|
-
awakeCount > this.graph.nodeCount() / this.beta) {
|
|
243
|
+
if (awakeCount >= oldAwakeCount || awakeCount > this.graph.nodeCount() / this.beta) {
|
|
233
244
|
useBottomUp = false;
|
|
234
245
|
}
|
|
235
246
|
} else {
|
|
@@ -256,8 +267,8 @@ export class DirectionOptimizedBFS<TNodeId = NodeId> {
|
|
|
256
267
|
}
|
|
257
268
|
|
|
258
269
|
/**
|
|
259
|
-
|
|
260
|
-
|
|
270
|
+
* Reset internal state for reuse
|
|
271
|
+
*/
|
|
261
272
|
reset(): void {
|
|
262
273
|
this.parent.fill(-1);
|
|
263
274
|
this.frontier.clear();
|
|
@@ -267,7 +278,11 @@ export class DirectionOptimizedBFS<TNodeId = NodeId> {
|
|
|
267
278
|
}
|
|
268
279
|
|
|
269
280
|
/**
|
|
270
|
-
* Convenience function for single-source BFS
|
|
281
|
+
* Convenience function for single-source BFS.
|
|
282
|
+
* @param graph - The CSR graph to perform BFS on
|
|
283
|
+
* @param source - The source node ID to start the BFS from
|
|
284
|
+
* @param options - Optional configuration for switching thresholds
|
|
285
|
+
* @returns The BFS result containing distances and parent pointers
|
|
271
286
|
*/
|
|
272
287
|
export function directionOptimizedBFS<TNodeId = NodeId>(
|
|
273
288
|
graph: CSRGraph<TNodeId>,
|
|
@@ -279,7 +294,11 @@ export function directionOptimizedBFS<TNodeId = NodeId>(
|
|
|
279
294
|
}
|
|
280
295
|
|
|
281
296
|
/**
|
|
282
|
-
* Convenience function for multi-source BFS
|
|
297
|
+
* Convenience function for multi-source BFS.
|
|
298
|
+
* @param graph - The CSR graph to perform BFS on
|
|
299
|
+
* @param sources - Array of source node IDs to start the BFS from
|
|
300
|
+
* @param options - Optional configuration for switching thresholds
|
|
301
|
+
* @returns The BFS result containing distances and parent pointers
|
|
283
302
|
*/
|
|
284
303
|
export function directionOptimizedBFSMultiple<TNodeId = NodeId>(
|
|
285
304
|
graph: CSRGraph<TNodeId>,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {Graph} from "../core/graph.js";
|
|
2
|
-
import type {NodeId} from "../types/index.js";
|
|
3
|
-
import {CSRGraph, type ReadonlyGraph} from "./csr-graph.js";
|
|
1
|
+
import type { Graph } from "../core/graph.js";
|
|
2
|
+
import type { NodeId } from "../types/index.js";
|
|
3
|
+
import { CSRGraph, type ReadonlyGraph } from "./csr-graph.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Adapter to convert standard Graph to CSR format
|
|
@@ -10,8 +10,12 @@ import {CSRGraph, type ReadonlyGraph} from "./csr-graph.js";
|
|
|
10
10
|
export class GraphAdapter<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
|
|
11
11
|
private csrGraph: CSRGraph<TNodeId>;
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new GraphAdapter that wraps or converts a graph to CSR format.
|
|
15
|
+
* @param graph - The graph to adapt (either standard Graph or ReadonlyGraph)
|
|
16
|
+
*/
|
|
13
17
|
constructor(graph: Graph | ReadonlyGraph<TNodeId>) {
|
|
14
|
-
|
|
18
|
+
// Check if already a CSRGraph
|
|
15
19
|
if (graph instanceof CSRGraph) {
|
|
16
20
|
this.csrGraph = graph as CSRGraph<TNodeId>;
|
|
17
21
|
} else {
|
|
@@ -21,8 +25,10 @@ export class GraphAdapter<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
|
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
/**
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
* Convert standard graph to CSR format.
|
|
29
|
+
* @param graph - The graph to convert
|
|
30
|
+
* @returns A new CSRGraph instance
|
|
31
|
+
*/
|
|
26
32
|
private convertToCSR(graph: Graph | ReadonlyGraph<TNodeId>): CSRGraph<TNodeId> {
|
|
27
33
|
const adjacencyList = new Map<TNodeId, TNodeId[]>();
|
|
28
34
|
const weights = new Map<string, number>();
|
|
@@ -31,7 +37,7 @@ export class GraphAdapter<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
|
|
|
31
37
|
if ("nodes" in graph && typeof graph.nodes === "function") {
|
|
32
38
|
// Build adjacency list from Graph
|
|
33
39
|
for (const node of graph.nodes()) {
|
|
34
|
-
const nodeId = (node as {id: TNodeId}).id;
|
|
40
|
+
const nodeId = (node as { id: TNodeId }).id;
|
|
35
41
|
const neighbors: TNodeId[] = [];
|
|
36
42
|
|
|
37
43
|
const graphTyped = graph as Graph;
|
|
@@ -53,7 +59,7 @@ export class GraphAdapter<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
|
|
|
53
59
|
// Handle ReadonlyGraph with nodeIds method
|
|
54
60
|
interface ReadonlyGraphWithNodeIds {
|
|
55
61
|
nodeIds(): Iterable<TNodeId>;
|
|
56
|
-
edges?(): Iterable<{source: TNodeId
|
|
62
|
+
edges?(): Iterable<{ source: TNodeId; target: TNodeId; weight?: number }>;
|
|
57
63
|
}
|
|
58
64
|
const readonlyGraph = graph as ReadonlyGraphWithNodeIds;
|
|
59
65
|
for (const nodeId of readonlyGraph.nodeIds()) {
|
|
@@ -78,37 +84,71 @@ export class GraphAdapter<TNodeId = NodeId> implements ReadonlyGraph<TNodeId> {
|
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
// Delegate all methods to CSR implementation
|
|
87
|
+
/**
|
|
88
|
+
* Get the total number of nodes in the graph.
|
|
89
|
+
* @returns The number of nodes
|
|
90
|
+
*/
|
|
81
91
|
nodeCount(): number {
|
|
82
92
|
return this.csrGraph.nodeCount();
|
|
83
93
|
}
|
|
84
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Get the total number of edges in the graph.
|
|
97
|
+
* @returns The number of edges
|
|
98
|
+
*/
|
|
85
99
|
edgeCount(): number {
|
|
86
100
|
return this.csrGraph.edgeCount();
|
|
87
101
|
}
|
|
88
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Check if a node exists in the graph.
|
|
105
|
+
* @param nodeId - The node ID to check
|
|
106
|
+
* @returns True if the node exists, false otherwise
|
|
107
|
+
*/
|
|
89
108
|
hasNode(nodeId: TNodeId): boolean {
|
|
90
109
|
return this.csrGraph.hasNode(nodeId);
|
|
91
110
|
}
|
|
92
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Check if an edge exists between two nodes.
|
|
114
|
+
* @param source - The source node ID
|
|
115
|
+
* @param target - The target node ID
|
|
116
|
+
* @returns True if the edge exists, false otherwise
|
|
117
|
+
*/
|
|
93
118
|
hasEdge(source: TNodeId, target: TNodeId): boolean {
|
|
94
119
|
return this.csrGraph.hasEdge(source, target);
|
|
95
120
|
}
|
|
96
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Get neighbors of a node as node IDs.
|
|
124
|
+
* @param nodeId - The node ID to get neighbors for
|
|
125
|
+
* @returns An iterator over neighbor node IDs
|
|
126
|
+
*/
|
|
97
127
|
neighbors(nodeId: TNodeId): IterableIterator<TNodeId> {
|
|
98
128
|
return this.csrGraph.neighbors(nodeId);
|
|
99
129
|
}
|
|
100
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Get the out-degree (number of outgoing edges) of a node.
|
|
133
|
+
* @param nodeId - The node ID to get the out-degree for
|
|
134
|
+
* @returns The number of outgoing edges from the node
|
|
135
|
+
*/
|
|
101
136
|
outDegree(nodeId: TNodeId): number {
|
|
102
137
|
return this.csrGraph.outDegree(nodeId);
|
|
103
138
|
}
|
|
104
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Get all nodes in the graph.
|
|
142
|
+
* @returns An iterator over all node IDs
|
|
143
|
+
*/
|
|
105
144
|
nodes(): IterableIterator<TNodeId> {
|
|
106
145
|
return this.csrGraph.nodes();
|
|
107
146
|
}
|
|
108
147
|
|
|
109
148
|
/**
|
|
110
|
-
|
|
111
|
-
|
|
149
|
+
* Get the underlying CSR graph.
|
|
150
|
+
* @returns The CSRGraph instance used internally
|
|
151
|
+
*/
|
|
112
152
|
getCSRGraph(): CSRGraph<TNodeId> {
|
|
113
153
|
return this.csrGraph;
|
|
114
154
|
}
|
|
@@ -133,31 +173,36 @@ export interface GraphAlgorithmConfig {
|
|
|
133
173
|
}
|
|
134
174
|
|
|
135
175
|
/**
|
|
136
|
-
* Configure optimizations globally
|
|
176
|
+
* Configure optimizations globally.
|
|
137
177
|
* @deprecated This function is a no-op and will be removed in a future version
|
|
178
|
+
* @param _config - The configuration object (ignored)
|
|
138
179
|
*/
|
|
139
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
140
180
|
export function configureOptimizations(_config: GraphAlgorithmConfig): void {
|
|
141
181
|
// No-op for backward compatibility
|
|
142
182
|
}
|
|
143
183
|
|
|
144
184
|
/**
|
|
145
|
-
* Get current configuration
|
|
185
|
+
* Get current configuration.
|
|
146
186
|
* @deprecated This function returns empty config and will be removed in a future version
|
|
187
|
+
* @returns An empty configuration object
|
|
147
188
|
*/
|
|
148
189
|
export function getOptimizationConfig(): GraphAlgorithmConfig {
|
|
149
190
|
return {};
|
|
150
191
|
}
|
|
151
192
|
|
|
152
193
|
/**
|
|
153
|
-
* Check if a graph is already in CSR format
|
|
194
|
+
* Check if a graph is already in CSR format.
|
|
195
|
+
* @param graph - The graph to check
|
|
196
|
+
* @returns True if the graph is a CSRGraph instance
|
|
154
197
|
*/
|
|
155
198
|
export function isCSRGraph<TNodeId = NodeId>(graph: unknown): graph is CSRGraph<TNodeId> {
|
|
156
199
|
return graph instanceof CSRGraph;
|
|
157
200
|
}
|
|
158
201
|
|
|
159
202
|
/**
|
|
160
|
-
* Convert any graph to CSR format
|
|
203
|
+
* Convert any graph to CSR format.
|
|
204
|
+
* @param graph - The graph to convert
|
|
205
|
+
* @returns A CSRGraph instance (either the original if already CSR, or a new converted one)
|
|
161
206
|
*/
|
|
162
207
|
export function toCSRGraph<TNodeId = NodeId>(
|
|
163
208
|
graph: Graph | ReadonlyGraph<TNodeId> | CSRGraph<TNodeId>,
|
|
@@ -171,7 +216,10 @@ export function toCSRGraph<TNodeId = NodeId>(
|
|
|
171
216
|
}
|
|
172
217
|
|
|
173
218
|
/**
|
|
174
|
-
* Create an optimized graph from nodes and edges
|
|
219
|
+
* Create an optimized graph from nodes and edges.
|
|
220
|
+
* @param nodes - Array of node IDs
|
|
221
|
+
* @param edges - Array of edge tuples [source, target, weight?]
|
|
222
|
+
* @returns A new CSRGraph instance
|
|
175
223
|
*/
|
|
176
224
|
export function createOptimizedGraph<TNodeId = NodeId>(
|
|
177
225
|
nodes: TNodeId[],
|
package/src/optimized/index.ts
CHANGED
|
@@ -8,11 +8,9 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
// Configuration and optimization control
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
type GraphAlgorithmConfig,
|
|
15
|
-
} from "./graph-adapter.js";
|
|
11
|
+
// These deprecated functions are intentionally re-exported for backward compatibility
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
13
|
+
export { configureOptimizations, getOptimizationConfig, type GraphAlgorithmConfig } from "./graph-adapter.js";
|
|
16
14
|
|
|
17
15
|
// Note: The main BFS functions in algorithms/traversal/bfs.ts automatically
|
|
18
16
|
// use these optimizations for large graphs (>10k nodes) when optimizations are enabled.
|
|
@@ -28,9 +26,9 @@ export {
|
|
|
28
26
|
// for large graphs without requiring manual configuration.
|
|
29
27
|
|
|
30
28
|
// Export data structures for advanced users
|
|
31
|
-
export {CompactDistanceArray, GraphBitSet, VisitedBitArray} from "./bit-packed.js";
|
|
32
|
-
export {CSRGraph} from "./csr-graph.js";
|
|
33
|
-
export {DirectionOptimizedBFS} from "./direction-optimized-bfs.js";
|
|
29
|
+
export { CompactDistanceArray, GraphBitSet, VisitedBitArray } from "./bit-packed.js";
|
|
30
|
+
export { CSRGraph } from "./csr-graph.js";
|
|
31
|
+
export { DirectionOptimizedBFS } from "./direction-optimized-bfs.js";
|
|
34
32
|
|
|
35
33
|
// Export utilities
|
|
36
|
-
export {createOptimizedGraph, isCSRGraph, toCSRGraph} from "./graph-adapter.js";
|
|
34
|
+
export { createOptimizedGraph, isCSRGraph, toCSRGraph } from "./graph-adapter.js";
|
package/src/pathfinding/astar.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {graphNode} from "../utils/graphNode.js";
|
|
2
|
-
import {MinPriorityQueue} from "../utils/priorityQueue.js";
|
|
3
|
-
import {pathfindingUtils} from "./utils.js";
|
|
1
|
+
import { graphNode } from "../utils/graphNode.js";
|
|
2
|
+
import { MinPriorityQueue } from "../utils/priorityQueue.js";
|
|
3
|
+
import { pathfindingUtils } from "./utils.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* A* pathfinding algorithm
|
|
7
7
|
* Finds the shortest path from start to goal using a heuristic function
|
|
8
|
-
*
|
|
9
8
|
* @param graph - The graph represented as an adjacency list
|
|
10
9
|
* @param start - The starting node
|
|
11
10
|
* @param goal - The goal node
|
|
@@ -20,7 +19,7 @@ export function astar<T>(
|
|
|
20
19
|
start: T,
|
|
21
20
|
goal: T,
|
|
22
21
|
heuristic: (node: T, goal: T) => number,
|
|
23
|
-
): {path: T[]
|
|
22
|
+
): { path: T[]; cost: number } | null {
|
|
24
23
|
if (!graph.has(start) || !graph.has(goal)) {
|
|
25
24
|
return null;
|
|
26
25
|
}
|
|
@@ -40,7 +39,7 @@ export function astar<T>(
|
|
|
40
39
|
return null;
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
openSet.insert({node: start, distance: startFScore});
|
|
42
|
+
openSet.insert({ node: start, distance: startFScore });
|
|
44
43
|
|
|
45
44
|
while (!openSet.isEmpty()) {
|
|
46
45
|
const current = openSet.extractMin();
|
|
@@ -58,7 +57,7 @@ export function astar<T>(
|
|
|
58
57
|
return null;
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
return {path, cost: goalCost};
|
|
60
|
+
return { path, cost: goalCost };
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
closedSet.add(currentNode);
|
|
@@ -90,7 +89,7 @@ export function astar<T>(
|
|
|
90
89
|
// Add to open set if not already there
|
|
91
90
|
const neighborFScore = fScore.get(neighbor);
|
|
92
91
|
if (neighborFScore !== undefined) {
|
|
93
|
-
openSet.insert({node: neighbor, distance: neighborFScore});
|
|
92
|
+
openSet.insert({ node: neighbor, distance: neighborFScore });
|
|
94
93
|
}
|
|
95
94
|
}
|
|
96
95
|
}
|
|
@@ -102,6 +101,11 @@ export function astar<T>(
|
|
|
102
101
|
/**
|
|
103
102
|
* A* pathfinding with path reconstruction details
|
|
104
103
|
* Returns detailed information about the search process
|
|
104
|
+
* @param graph - The graph represented as an adjacency list
|
|
105
|
+
* @param start - The starting node
|
|
106
|
+
* @param goal - The goal node
|
|
107
|
+
* @param heuristic - Heuristic function that estimates distance from node to goal
|
|
108
|
+
* @returns Detailed result including path, cost, visited nodes, and score maps
|
|
105
109
|
*/
|
|
106
110
|
export function astarWithDetails<T>(
|
|
107
111
|
graph: Map<T, Map<T, number>>,
|
|
@@ -109,12 +113,12 @@ export function astarWithDetails<T>(
|
|
|
109
113
|
goal: T,
|
|
110
114
|
heuristic: (node: T, goal: T) => number,
|
|
111
115
|
): {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
path: T[] | null;
|
|
117
|
+
cost: number;
|
|
118
|
+
visited: Set<T>;
|
|
119
|
+
gScores: Map<T, number>;
|
|
120
|
+
fScores: Map<T, number>;
|
|
121
|
+
} {
|
|
118
122
|
const openSet = new MinPriorityQueue<graphNode<T>>();
|
|
119
123
|
const gScore = new Map<T, number>();
|
|
120
124
|
const fScore = new Map<T, number>();
|
|
@@ -134,7 +138,7 @@ export function astarWithDetails<T>(
|
|
|
134
138
|
};
|
|
135
139
|
}
|
|
136
140
|
|
|
137
|
-
openSet.insert({node: start, distance: startFScore});
|
|
141
|
+
openSet.insert({ node: start, distance: startFScore });
|
|
138
142
|
|
|
139
143
|
while (!openSet.isEmpty()) {
|
|
140
144
|
const current = openSet.extractMin();
|
|
@@ -181,7 +185,7 @@ export function astarWithDetails<T>(
|
|
|
181
185
|
fScore.set(neighbor, tentativeGScore + heuristic(neighbor, goal));
|
|
182
186
|
const neighborFScore = fScore.get(neighbor);
|
|
183
187
|
if (neighborFScore !== undefined) {
|
|
184
|
-
openSet.insert({node: neighbor, distance: neighborFScore});
|
|
188
|
+
openSet.insert({ node: neighbor, distance: neighborFScore });
|
|
185
189
|
}
|
|
186
190
|
}
|
|
187
191
|
}
|
|
@@ -201,29 +205,40 @@ export function astarWithDetails<T>(
|
|
|
201
205
|
*/
|
|
202
206
|
export const heuristics = {
|
|
203
207
|
/**
|
|
204
|
-
|
|
205
|
-
|
|
208
|
+
* Manhattan distance heuristic for grid-based graphs
|
|
209
|
+
* @param a - First coordinate as [x, y] tuple
|
|
210
|
+
* @param b - Second coordinate as [x, y] tuple
|
|
211
|
+
* @returns The Manhattan distance between the two points
|
|
212
|
+
*/
|
|
206
213
|
manhattan: (a: [number, number], b: [number, number]): number => {
|
|
207
214
|
return Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]);
|
|
208
215
|
},
|
|
209
216
|
|
|
210
217
|
/**
|
|
211
|
-
|
|
212
|
-
|
|
218
|
+
* Euclidean distance heuristic
|
|
219
|
+
* @param a - First coordinate as [x, y] tuple
|
|
220
|
+
* @param b - Second coordinate as [x, y] tuple
|
|
221
|
+
* @returns The Euclidean distance between the two points
|
|
222
|
+
*/
|
|
213
223
|
euclidean: (a: [number, number], b: [number, number]): number => {
|
|
214
224
|
return Math.sqrt(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2));
|
|
215
225
|
},
|
|
216
226
|
|
|
217
227
|
/**
|
|
218
|
-
|
|
219
|
-
|
|
228
|
+
* Chebyshev distance heuristic (diagonal movement allowed)
|
|
229
|
+
* @param a - First coordinate as [x, y] tuple
|
|
230
|
+
* @param b - Second coordinate as [x, y] tuple
|
|
231
|
+
* @returns The Chebyshev distance between the two points
|
|
232
|
+
*/
|
|
220
233
|
chebyshev: (a: [number, number], b: [number, number]): number => {
|
|
221
234
|
return Math.max(Math.abs(a[0] - b[0]), Math.abs(a[1] - b[1]));
|
|
222
235
|
},
|
|
223
236
|
|
|
224
237
|
/**
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
238
|
+
* Zero heuristic (makes A* behave like Dijkstra)
|
|
239
|
+
* @param _a - First node (unused)
|
|
240
|
+
* @param _b - Second node (unused)
|
|
241
|
+
* @returns Always returns 0
|
|
242
|
+
*/
|
|
228
243
|
zero: <T>(_a: T, _b: T): number => 0,
|
|
229
244
|
};
|
package/src/pathfinding/utils.ts
CHANGED
|
@@ -4,8 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
export const pathfindingUtils = {
|
|
6
6
|
/**
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
* Reconstructs a path from start to goal using the cameFrom map
|
|
8
|
+
* @param cameFrom - Map of each node to its predecessor on the path
|
|
9
|
+
* @param goal - The goal node to reconstruct the path to
|
|
10
|
+
* @returns An array of nodes representing the path from start to goal
|
|
11
|
+
*/
|
|
9
12
|
reconstructPath<T>(cameFrom: Map<T, T>, goal: T): T[] {
|
|
10
13
|
const path: T[] = [goal];
|
|
11
14
|
let current = goal;
|
|
@@ -24,13 +27,13 @@ export const pathfindingUtils = {
|
|
|
24
27
|
},
|
|
25
28
|
|
|
26
29
|
/**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
): Map<string, Map<string, number>> {
|
|
30
|
+
* Creates a grid graph for testing pathfinding algorithms
|
|
31
|
+
* @param width - The width of the grid
|
|
32
|
+
* @param height - The height of the grid
|
|
33
|
+
* @param obstacles - Set of obstacle coordinates as "x,y" strings
|
|
34
|
+
* @returns A grid graph with 4-directional movement
|
|
35
|
+
*/
|
|
36
|
+
createGridGraph(width: number, height: number, obstacles = new Set<string>()): Map<string, Map<string, number>> {
|
|
34
37
|
const graph = new Map<string, Map<string, number>>();
|
|
35
38
|
|
|
36
39
|
for (let x = 0; x < width; x++) {
|
|
@@ -44,7 +47,10 @@ export const pathfindingUtils = {
|
|
|
44
47
|
|
|
45
48
|
// Add 4-directional neighbors
|
|
46
49
|
const directions = [
|
|
47
|
-
[0, 1],
|
|
50
|
+
[0, 1],
|
|
51
|
+
[1, 0],
|
|
52
|
+
[0, -1],
|
|
53
|
+
[-1, 0],
|
|
48
54
|
];
|
|
49
55
|
|
|
50
56
|
for (const dir of directions) {
|
|
@@ -71,8 +77,10 @@ export const pathfindingUtils = {
|
|
|
71
77
|
},
|
|
72
78
|
|
|
73
79
|
/**
|
|
74
|
-
|
|
75
|
-
|
|
80
|
+
* Parses a grid coordinate string
|
|
81
|
+
* @param coord - The coordinate string in "x,y" format
|
|
82
|
+
* @returns A tuple of [x, y] coordinates
|
|
83
|
+
*/
|
|
76
84
|
parseGridCoordinate(coord: string): [number, number] {
|
|
77
85
|
const parts = coord.split(",").map(Number);
|
|
78
86
|
const x = parts[0];
|
|
@@ -84,4 +92,3 @@ export const pathfindingUtils = {
|
|
|
84
92
|
return [x, y];
|
|
85
93
|
},
|
|
86
94
|
};
|
|
87
|
-
|