@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.
Files changed (273) hide show
  1. package/README.md +827 -60
  2. package/dist/algorithms.d.ts +2 -0
  3. package/dist/algorithms.d.ts.map +1 -0
  4. package/dist/algorithms.js +2 -0
  5. package/dist/algorithms.js.map +1 -0
  6. package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
  7. package/dist/src/algorithms/centrality/betweenness.js +22 -7
  8. package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
  9. package/dist/src/algorithms/centrality/closeness.js +7 -7
  10. package/dist/src/algorithms/centrality/closeness.js.map +1 -1
  11. package/dist/src/algorithms/centrality/degree.js +1 -1
  12. package/dist/src/algorithms/centrality/degree.js.map +1 -1
  13. package/dist/src/algorithms/centrality/eigenvector.d.ts +27 -0
  14. package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -0
  15. package/dist/src/algorithms/centrality/eigenvector.js +113 -0
  16. package/dist/src/algorithms/centrality/eigenvector.js.map +1 -0
  17. package/dist/src/algorithms/centrality/hits.d.ts +35 -0
  18. package/dist/src/algorithms/centrality/hits.d.ts.map +1 -0
  19. package/dist/src/algorithms/centrality/hits.js +146 -0
  20. package/dist/src/algorithms/centrality/hits.js.map +1 -0
  21. package/dist/src/algorithms/centrality/index.d.ts +6 -0
  22. package/dist/src/algorithms/centrality/index.d.ts.map +1 -1
  23. package/dist/src/algorithms/centrality/index.js +3 -0
  24. package/dist/src/algorithms/centrality/index.js.map +1 -1
  25. package/dist/src/algorithms/centrality/katz.d.ts +30 -0
  26. package/dist/src/algorithms/centrality/katz.d.ts.map +1 -0
  27. package/dist/src/algorithms/centrality/katz.js +85 -0
  28. package/dist/src/algorithms/centrality/katz.js.map +1 -0
  29. package/dist/src/algorithms/centrality/pagerank.js +3 -3
  30. package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
  31. package/dist/src/algorithms/community/girvan-newman.d.ts +23 -0
  32. package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -0
  33. package/dist/src/algorithms/community/girvan-newman.js +297 -0
  34. package/dist/src/algorithms/community/girvan-newman.js.map +1 -0
  35. package/dist/src/algorithms/community/index.d.ts +12 -0
  36. package/dist/src/algorithms/community/index.d.ts.map +1 -0
  37. package/dist/src/algorithms/community/index.js +12 -0
  38. package/dist/src/algorithms/community/index.js.map +1 -0
  39. package/dist/src/algorithms/community/label-propagation.d.ts +42 -0
  40. package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -0
  41. package/dist/src/algorithms/community/label-propagation.js +307 -0
  42. package/dist/src/algorithms/community/label-propagation.js.map +1 -0
  43. package/dist/src/algorithms/community/leiden.d.ts +33 -0
  44. package/dist/src/algorithms/community/leiden.d.ts.map +1 -0
  45. package/dist/src/algorithms/community/leiden.js +434 -0
  46. package/dist/src/algorithms/community/leiden.js.map +1 -0
  47. package/dist/src/algorithms/community/louvain.d.ts +19 -0
  48. package/dist/src/algorithms/community/louvain.d.ts.map +1 -0
  49. package/dist/src/algorithms/community/louvain.js +219 -0
  50. package/dist/src/algorithms/community/louvain.js.map +1 -0
  51. package/dist/src/algorithms/components/connected.js +7 -7
  52. package/dist/src/algorithms/components/connected.js.map +1 -1
  53. package/dist/src/algorithms/index.d.ts +7 -0
  54. package/dist/src/algorithms/index.d.ts.map +1 -1
  55. package/dist/src/algorithms/index.js +14 -0
  56. package/dist/src/algorithms/index.js.map +1 -1
  57. package/dist/src/algorithms/matching/bipartite.d.ts +37 -0
  58. package/dist/src/algorithms/matching/bipartite.d.ts.map +1 -0
  59. package/dist/src/algorithms/matching/bipartite.js +127 -0
  60. package/dist/src/algorithms/matching/bipartite.js.map +1 -0
  61. package/dist/src/algorithms/matching/index.d.ts +8 -0
  62. package/dist/src/algorithms/matching/index.d.ts.map +1 -0
  63. package/dist/src/algorithms/matching/index.js +6 -0
  64. package/dist/src/algorithms/matching/index.js.map +1 -0
  65. package/dist/src/algorithms/matching/isomorphism.d.ts +32 -0
  66. package/dist/src/algorithms/matching/isomorphism.d.ts.map +1 -0
  67. package/dist/src/algorithms/matching/isomorphism.js +291 -0
  68. package/dist/src/algorithms/matching/isomorphism.js.map +1 -0
  69. package/dist/src/algorithms/mst/index.d.ts +4 -0
  70. package/dist/src/algorithms/mst/index.d.ts.map +1 -0
  71. package/dist/src/algorithms/mst/index.js +3 -0
  72. package/dist/src/algorithms/mst/index.js.map +1 -0
  73. package/dist/src/algorithms/mst/kruskal.d.ts +9 -0
  74. package/dist/src/algorithms/mst/kruskal.d.ts.map +1 -0
  75. package/dist/src/algorithms/mst/kruskal.js +43 -0
  76. package/dist/src/algorithms/mst/kruskal.js.map +1 -0
  77. package/dist/src/algorithms/mst/prim.d.ts +5 -0
  78. package/dist/src/algorithms/mst/prim.d.ts.map +1 -0
  79. package/dist/src/algorithms/mst/prim.js +63 -0
  80. package/dist/src/algorithms/mst/prim.js.map +1 -0
  81. package/dist/src/algorithms/shortest-path/bellman-ford.js +2 -2
  82. package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
  83. package/dist/src/algorithms/shortest-path/dijkstra.js +5 -5
  84. package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
  85. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts +14 -0
  86. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts.map +1 -0
  87. package/dist/src/algorithms/shortest-path/floyd-warshall.js +129 -0
  88. package/dist/src/algorithms/shortest-path/floyd-warshall.js.map +1 -0
  89. package/dist/src/algorithms/shortest-path/index.d.ts +2 -0
  90. package/dist/src/algorithms/shortest-path/index.d.ts.map +1 -1
  91. package/dist/src/algorithms/shortest-path/index.js +1 -0
  92. package/dist/src/algorithms/shortest-path/index.js.map +1 -1
  93. package/dist/src/algorithms/traversal/bfs.js +2 -2
  94. package/dist/src/algorithms/traversal/bfs.js.map +1 -1
  95. package/dist/src/algorithms/traversal/dfs.js +11 -11
  96. package/dist/src/algorithms/traversal/dfs.js.map +1 -1
  97. package/dist/src/clustering/hierarchical.d.ts +48 -0
  98. package/dist/src/clustering/hierarchical.d.ts.map +1 -0
  99. package/dist/src/clustering/hierarchical.js +439 -0
  100. package/dist/src/clustering/hierarchical.js.map +1 -0
  101. package/dist/src/clustering/index.d.ts +7 -0
  102. package/dist/src/clustering/index.d.ts.map +1 -0
  103. package/dist/src/clustering/index.js +5 -0
  104. package/dist/src/clustering/index.js.map +1 -0
  105. package/dist/src/clustering/k-core.d.ts +63 -0
  106. package/dist/src/clustering/k-core.d.ts.map +1 -0
  107. package/dist/src/clustering/k-core.js +377 -0
  108. package/dist/src/clustering/k-core.js.map +1 -0
  109. package/dist/src/clustering/mcl.d.ts +36 -0
  110. package/dist/src/clustering/mcl.d.ts.map +1 -0
  111. package/dist/src/clustering/mcl.js +343 -0
  112. package/dist/src/clustering/mcl.js.map +1 -0
  113. package/dist/src/clustering/spectral.d.ts +28 -0
  114. package/dist/src/clustering/spectral.d.ts.map +1 -0
  115. package/dist/src/clustering/spectral.js +447 -0
  116. package/dist/src/clustering/spectral.js.map +1 -0
  117. package/dist/src/core/graph.d.ts +9 -0
  118. package/dist/src/core/graph.d.ts.map +1 -1
  119. package/dist/src/core/graph.js +31 -11
  120. package/dist/src/core/graph.js.map +1 -1
  121. package/dist/src/data-structures/priority-queue.js +0 -2
  122. package/dist/src/data-structures/priority-queue.js.map +1 -1
  123. package/dist/src/data-structures/union-find.js +2 -5
  124. package/dist/src/data-structures/union-find.js.map +1 -1
  125. package/dist/src/flow/ford-fulkerson.d.ts +53 -0
  126. package/dist/src/flow/ford-fulkerson.d.ts.map +1 -0
  127. package/dist/src/flow/ford-fulkerson.js +355 -0
  128. package/dist/src/flow/ford-fulkerson.js.map +1 -0
  129. package/dist/src/flow/index.d.ts +3 -0
  130. package/dist/src/flow/index.d.ts.map +1 -0
  131. package/dist/src/flow/index.js +3 -0
  132. package/dist/src/flow/index.js.map +1 -0
  133. package/dist/src/flow/min-cut.d.ts +49 -0
  134. package/dist/src/flow/min-cut.d.ts.map +1 -0
  135. package/dist/src/flow/min-cut.js +383 -0
  136. package/dist/src/flow/min-cut.js.map +1 -0
  137. package/dist/src/index.d.ts +1 -1
  138. package/dist/src/index.d.ts.map +1 -1
  139. package/dist/src/index.js.map +1 -1
  140. package/dist/src/link-prediction/adamic-adar.d.ts +56 -0
  141. package/dist/src/link-prediction/adamic-adar.d.ts.map +1 -0
  142. package/dist/src/link-prediction/adamic-adar.js +256 -0
  143. package/dist/src/link-prediction/adamic-adar.js.map +1 -0
  144. package/dist/src/link-prediction/common-neighbors.d.ts +50 -0
  145. package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -0
  146. package/dist/src/link-prediction/common-neighbors.js +155 -0
  147. package/dist/src/link-prediction/common-neighbors.js.map +1 -0
  148. package/dist/src/link-prediction/index.d.ts +7 -0
  149. package/dist/src/link-prediction/index.d.ts.map +1 -0
  150. package/dist/src/link-prediction/index.js +6 -0
  151. package/dist/src/link-prediction/index.js.map +1 -0
  152. package/dist/src/pathfinding/astar.d.ts +50 -0
  153. package/dist/src/pathfinding/astar.d.ts.map +1 -0
  154. package/dist/src/pathfinding/astar.js +180 -0
  155. package/dist/src/pathfinding/astar.js.map +1 -0
  156. package/dist/src/pathfinding/index.d.ts +3 -0
  157. package/dist/src/pathfinding/index.d.ts.map +1 -0
  158. package/dist/src/pathfinding/index.js +3 -0
  159. package/dist/src/pathfinding/index.js.map +1 -0
  160. package/dist/src/pathfinding/utils.d.ts +18 -0
  161. package/dist/src/pathfinding/utils.d.ts.map +1 -0
  162. package/dist/src/pathfinding/utils.js +68 -0
  163. package/dist/src/pathfinding/utils.js.map +1 -0
  164. package/dist/src/types/index.d.ts +9 -0
  165. package/dist/src/types/index.d.ts.map +1 -1
  166. package/dist/src/utils/graphNode.d.ts +8 -0
  167. package/dist/src/utils/graphNode.d.ts.map +1 -0
  168. package/dist/src/utils/graphNode.js +2 -0
  169. package/dist/src/utils/graphNode.js.map +1 -0
  170. package/dist/src/utils/priorityQueue.d.ts +21 -0
  171. package/dist/src/utils/priorityQueue.d.ts.map +1 -0
  172. package/dist/src/utils/priorityQueue.js +101 -0
  173. package/dist/src/utils/priorityQueue.js.map +1 -0
  174. package/package.json +3 -1
  175. package/src/algorithms/centrality/betweenness.ts +25 -7
  176. package/src/algorithms/centrality/closeness.ts +7 -7
  177. package/src/algorithms/centrality/degree.ts +1 -1
  178. package/src/algorithms/centrality/eigenvector.ts +162 -0
  179. package/src/algorithms/centrality/hits.ts +210 -0
  180. package/src/algorithms/centrality/index.ts +6 -0
  181. package/src/algorithms/centrality/katz.ts +139 -0
  182. package/src/algorithms/centrality/pagerank.ts +3 -3
  183. package/src/algorithms/community/girvan-newman.ts +372 -0
  184. package/src/algorithms/community/index.ts +13 -0
  185. package/src/algorithms/community/label-propagation.ts +392 -0
  186. package/src/algorithms/community/leiden.ts +572 -0
  187. package/src/algorithms/community/louvain.ts +298 -0
  188. package/src/algorithms/components/connected.ts +7 -7
  189. package/src/algorithms/index.ts +21 -0
  190. package/src/algorithms/matching/bipartite.ts +179 -0
  191. package/src/algorithms/matching/index.ts +8 -0
  192. package/src/algorithms/matching/isomorphism.ts +392 -0
  193. package/src/algorithms/mst/index.ts +4 -0
  194. package/src/algorithms/mst/kruskal.ts +61 -0
  195. package/src/algorithms/mst/prim.ts +80 -0
  196. package/src/algorithms/shortest-path/bellman-ford.ts +2 -2
  197. package/src/algorithms/shortest-path/dijkstra.ts +5 -5
  198. package/src/algorithms/shortest-path/floyd-warshall.ts +170 -0
  199. package/src/algorithms/shortest-path/index.ts +2 -0
  200. package/src/algorithms/traversal/bfs.ts +2 -2
  201. package/src/algorithms/traversal/dfs.ts +11 -11
  202. package/src/clustering/hierarchical.ts +555 -0
  203. package/src/clustering/index.ts +6 -0
  204. package/src/clustering/k-core.ts +460 -0
  205. package/src/clustering/mcl.ts +454 -0
  206. package/src/clustering/spectral.ts +545 -0
  207. package/src/core/graph.ts +34 -6
  208. package/src/data-structures/union-find.ts +2 -2
  209. package/src/flow/ford-fulkerson.ts +459 -0
  210. package/src/flow/index.ts +2 -0
  211. package/src/flow/min-cut.ts +482 -0
  212. package/src/index.ts +2 -0
  213. package/src/link-prediction/adamic-adar.ts +353 -0
  214. package/src/link-prediction/common-neighbors.ts +252 -0
  215. package/src/link-prediction/index.ts +20 -0
  216. package/src/pathfinding/astar.ts +229 -0
  217. package/src/pathfinding/index.ts +2 -0
  218. package/src/pathfinding/utils.ts +87 -0
  219. package/src/types/index.ts +11 -0
  220. package/src/utils/graphNode.ts +7 -0
  221. package/src/utils/priorityQueue.ts +120 -0
  222. package/dist/test/browser/basic.test.d.ts +0 -2
  223. package/dist/test/browser/basic.test.d.ts.map +0 -1
  224. package/dist/test/browser/basic.test.js +0 -70
  225. package/dist/test/browser/basic.test.js.map +0 -1
  226. package/dist/test/unit/bellman-ford.test.d.ts +0 -2
  227. package/dist/test/unit/bellman-ford.test.d.ts.map +0 -1
  228. package/dist/test/unit/bellman-ford.test.js +0 -231
  229. package/dist/test/unit/bellman-ford.test.js.map +0 -1
  230. package/dist/test/unit/betweenness-centrality.test.d.ts +0 -2
  231. package/dist/test/unit/betweenness-centrality.test.d.ts.map +0 -1
  232. package/dist/test/unit/betweenness-centrality.test.js +0 -311
  233. package/dist/test/unit/betweenness-centrality.test.js.map +0 -1
  234. package/dist/test/unit/bfs.test.d.ts +0 -2
  235. package/dist/test/unit/bfs.test.d.ts.map +0 -1
  236. package/dist/test/unit/bfs.test.js +0 -277
  237. package/dist/test/unit/bfs.test.js.map +0 -1
  238. package/dist/test/unit/closeness.test.d.ts +0 -2
  239. package/dist/test/unit/closeness.test.d.ts.map +0 -1
  240. package/dist/test/unit/closeness.test.js +0 -266
  241. package/dist/test/unit/closeness.test.js.map +0 -1
  242. package/dist/test/unit/connected-components.test.d.ts +0 -2
  243. package/dist/test/unit/connected-components.test.d.ts.map +0 -1
  244. package/dist/test/unit/connected-components.test.js +0 -355
  245. package/dist/test/unit/connected-components.test.js.map +0 -1
  246. package/dist/test/unit/degree-centrality.test.d.ts +0 -2
  247. package/dist/test/unit/degree-centrality.test.d.ts.map +0 -1
  248. package/dist/test/unit/degree-centrality.test.js +0 -260
  249. package/dist/test/unit/degree-centrality.test.js.map +0 -1
  250. package/dist/test/unit/dfs.test.d.ts +0 -2
  251. package/dist/test/unit/dfs.test.d.ts.map +0 -1
  252. package/dist/test/unit/dfs.test.js +0 -350
  253. package/dist/test/unit/dfs.test.js.map +0 -1
  254. package/dist/test/unit/dijkstra.test.d.ts +0 -2
  255. package/dist/test/unit/dijkstra.test.d.ts.map +0 -1
  256. package/dist/test/unit/dijkstra.test.js +0 -311
  257. package/dist/test/unit/dijkstra.test.js.map +0 -1
  258. package/dist/test/unit/graph.test.d.ts +0 -2
  259. package/dist/test/unit/graph.test.d.ts.map +0 -1
  260. package/dist/test/unit/graph.test.js +0 -175
  261. package/dist/test/unit/graph.test.js.map +0 -1
  262. package/dist/test/unit/pagerank.test.d.ts +0 -2
  263. package/dist/test/unit/pagerank.test.d.ts.map +0 -1
  264. package/dist/test/unit/pagerank.test.js +0 -281
  265. package/dist/test/unit/pagerank.test.js.map +0 -1
  266. package/dist/test/unit/priority-queue.test.d.ts +0 -2
  267. package/dist/test/unit/priority-queue.test.d.ts.map +0 -1
  268. package/dist/test/unit/priority-queue.test.js +0 -189
  269. package/dist/test/unit/priority-queue.test.js.map +0 -1
  270. package/dist/test/unit/union-find.test.d.ts +0 -2
  271. package/dist/test/unit/union-find.test.d.ts.map +0 -1
  272. package/dist/test/unit/union-find.test.js +0 -245
  273. package/dist/test/unit/union-find.test.js.map +0 -1
@@ -0,0 +1,229 @@
1
+ import {graphNode} from "../utils/graphNode.js";
2
+ import {MinPriorityQueue} from "../utils/priorityQueue.js";
3
+ import {pathfindingUtils} from "./utils.js";
4
+
5
+ /**
6
+ * A* pathfinding algorithm
7
+ * Finds the shortest path from start to goal using a heuristic function
8
+ *
9
+ * @param graph - The graph represented as an adjacency list
10
+ * @param start - The starting node
11
+ * @param goal - The goal node
12
+ * @param heuristic - Heuristic function that estimates distance from node to goal
13
+ * @returns Object containing the shortest path and its cost, or null if no path exists
14
+ *
15
+ * Time Complexity: O(E) with good heuristic, O(b^d) worst case
16
+ * Space Complexity: O(V)
17
+ */
18
+ export function astar<T>(
19
+ graph: Map<T, Map<T, number>>,
20
+ start: T,
21
+ goal: T,
22
+ heuristic: (node: T, goal: T) => number,
23
+ ): {path: T[], cost: number} | null {
24
+ if (!graph.has(start) || !graph.has(goal)) {
25
+ return null;
26
+ }
27
+
28
+ // Priority queue ordered by f(n) = g(n) + h(n)
29
+ const openSet = new MinPriorityQueue<graphNode<T>>();
30
+ const gScore = new Map<T, number>(); // Cost from start to node
31
+ const fScore = new Map<T, number>(); // Estimated total cost
32
+ const cameFrom = new Map<T, T>();
33
+ const closedSet = new Set<T>();
34
+
35
+ // Initialize start node
36
+ gScore.set(start, 0);
37
+ fScore.set(start, heuristic(start, goal));
38
+ const startFScore = fScore.get(start);
39
+ if (startFScore === undefined) {
40
+ return null;
41
+ }
42
+
43
+ openSet.insert({node: start, distance: startFScore});
44
+
45
+ while (!openSet.isEmpty()) {
46
+ const current = openSet.extractMin();
47
+ if (!current) {
48
+ break;
49
+ }
50
+
51
+ const currentNode = current.node;
52
+
53
+ if (currentNode === goal) {
54
+ // Reconstruct path
55
+ const path = pathfindingUtils.reconstructPath(cameFrom, goal);
56
+ const goalCost = gScore.get(goal);
57
+ if (goalCost === undefined) {
58
+ return null;
59
+ }
60
+
61
+ return {path, cost: goalCost};
62
+ }
63
+
64
+ closedSet.add(currentNode);
65
+
66
+ const neighbors = graph.get(currentNode);
67
+ if (!neighbors) {
68
+ continue;
69
+ }
70
+
71
+ for (const [neighbor, weight] of neighbors) {
72
+ if (closedSet.has(neighbor)) {
73
+ continue;
74
+ }
75
+
76
+ const currentNodeGScore = gScore.get(currentNode);
77
+ if (currentNodeGScore === undefined) {
78
+ continue;
79
+ }
80
+
81
+ const tentativeGScore = currentNodeGScore + weight;
82
+ const currentGScore = gScore.get(neighbor) ?? Infinity;
83
+
84
+ if (tentativeGScore < currentGScore) {
85
+ // This path to neighbor is better
86
+ cameFrom.set(neighbor, currentNode);
87
+ gScore.set(neighbor, tentativeGScore);
88
+ fScore.set(neighbor, tentativeGScore + heuristic(neighbor, goal));
89
+
90
+ // Add to open set if not already there
91
+ const neighborFScore = fScore.get(neighbor);
92
+ if (neighborFScore !== undefined) {
93
+ openSet.insert({node: neighbor, distance: neighborFScore});
94
+ }
95
+ }
96
+ }
97
+ }
98
+
99
+ return null; // No path found
100
+ }
101
+
102
+ /**
103
+ * A* pathfinding with path reconstruction details
104
+ * Returns detailed information about the search process
105
+ */
106
+ export function astarWithDetails<T>(
107
+ graph: Map<T, Map<T, number>>,
108
+ start: T,
109
+ goal: T,
110
+ heuristic: (node: T, goal: T) => number,
111
+ ): {
112
+ path: T[] | null;
113
+ cost: number;
114
+ visited: Set<T>;
115
+ gScores: Map<T, number>;
116
+ fScores: Map<T, number>;
117
+ } {
118
+ const openSet = new MinPriorityQueue<graphNode<T>>();
119
+ const gScore = new Map<T, number>();
120
+ const fScore = new Map<T, number>();
121
+ const cameFrom = new Map<T, T>();
122
+ const closedSet = new Set<T>();
123
+
124
+ gScore.set(start, 0);
125
+ fScore.set(start, heuristic(start, goal));
126
+ const startFScore = fScore.get(start);
127
+ if (startFScore === undefined) {
128
+ return {
129
+ path: null,
130
+ cost: Infinity,
131
+ visited: new Set(),
132
+ gScores: new Map(),
133
+ fScores: new Map(),
134
+ };
135
+ }
136
+
137
+ openSet.insert({node: start, distance: startFScore});
138
+
139
+ while (!openSet.isEmpty()) {
140
+ const current = openSet.extractMin();
141
+ if (!current) {
142
+ break;
143
+ }
144
+
145
+ const currentNode = current.node;
146
+
147
+ if (currentNode === goal) {
148
+ const path = pathfindingUtils.reconstructPath(cameFrom, goal);
149
+ return {
150
+ path,
151
+ cost: gScore.get(goal) ?? Infinity,
152
+ visited: closedSet,
153
+ gScores: gScore,
154
+ fScores: fScore,
155
+ };
156
+ }
157
+
158
+ closedSet.add(currentNode);
159
+
160
+ const neighbors = graph.get(currentNode);
161
+ if (!neighbors) {
162
+ continue;
163
+ }
164
+
165
+ for (const [neighbor, weight] of neighbors) {
166
+ if (closedSet.has(neighbor)) {
167
+ continue;
168
+ }
169
+
170
+ const currentNodeGScore = gScore.get(currentNode);
171
+ if (currentNodeGScore === undefined) {
172
+ continue;
173
+ }
174
+
175
+ const tentativeGScore = currentNodeGScore + weight;
176
+ const currentGScore = gScore.get(neighbor) ?? Infinity;
177
+
178
+ if (tentativeGScore < currentGScore) {
179
+ cameFrom.set(neighbor, currentNode);
180
+ gScore.set(neighbor, tentativeGScore);
181
+ fScore.set(neighbor, tentativeGScore + heuristic(neighbor, goal));
182
+ const neighborFScore = fScore.get(neighbor);
183
+ if (neighborFScore !== undefined) {
184
+ openSet.insert({node: neighbor, distance: neighborFScore});
185
+ }
186
+ }
187
+ }
188
+ }
189
+
190
+ return {
191
+ path: null,
192
+ cost: Infinity,
193
+ visited: closedSet,
194
+ gScores: gScore,
195
+ fScores: fScore,
196
+ };
197
+ }
198
+
199
+ /**
200
+ * Common heuristic functions for A*
201
+ */
202
+ export const heuristics = {
203
+ /**
204
+ * Manhattan distance heuristic for grid-based graphs
205
+ */
206
+ manhattan: (a: [number, number], b: [number, number]): number => {
207
+ return Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]);
208
+ },
209
+
210
+ /**
211
+ * Euclidean distance heuristic
212
+ */
213
+ euclidean: (a: [number, number], b: [number, number]): number => {
214
+ return Math.sqrt(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2));
215
+ },
216
+
217
+ /**
218
+ * Chebyshev distance heuristic (diagonal movement allowed)
219
+ */
220
+ chebyshev: (a: [number, number], b: [number, number]): number => {
221
+ return Math.max(Math.abs(a[0] - b[0]), Math.abs(a[1] - b[1]));
222
+ },
223
+
224
+ /**
225
+ * Zero heuristic (makes A* behave like Dijkstra)
226
+ */
227
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
228
+ zero: <T>(_a: T, _b: T): number => 0,
229
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./astar.js";
2
+ export * from "./utils.js";
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Utility functions for pathfinding algorithms
3
+ */
4
+
5
+ export const pathfindingUtils = {
6
+ /**
7
+ * Reconstructs a path from start to goal using the cameFrom map
8
+ */
9
+ reconstructPath<T>(cameFrom: Map<T, T>, goal: T): T[] {
10
+ const path: T[] = [goal];
11
+ let current = goal;
12
+
13
+ while (cameFrom.has(current)) {
14
+ const next = cameFrom.get(current);
15
+ if (next === undefined) {
16
+ break;
17
+ }
18
+
19
+ current = next;
20
+ path.unshift(current);
21
+ }
22
+
23
+ return path;
24
+ },
25
+
26
+ /**
27
+ * Creates a grid graph for testing pathfinding algorithms
28
+ */
29
+ createGridGraph(
30
+ width: number,
31
+ height: number,
32
+ obstacles = new Set<string>(),
33
+ ): Map<string, Map<string, number>> {
34
+ const graph = new Map<string, Map<string, number>>();
35
+
36
+ for (let x = 0; x < width; x++) {
37
+ for (let y = 0; y < height; y++) {
38
+ const node = `${String(x)},${String(y)}`;
39
+ if (obstacles.has(node)) {
40
+ continue;
41
+ }
42
+
43
+ const neighbors = new Map<string, number>();
44
+
45
+ // Add 4-directional neighbors
46
+ const directions = [
47
+ [0, 1], [1, 0], [0, -1], [-1, 0],
48
+ ];
49
+
50
+ for (const dir of directions) {
51
+ const dx = dir[0];
52
+ const dy = dir[1];
53
+ if (dx === undefined || dy === undefined) {
54
+ continue;
55
+ }
56
+
57
+ const nx = x + dx;
58
+ const ny = y + dy;
59
+ const neighbor = `${String(nx)},${String(ny)}`;
60
+
61
+ if (nx >= 0 && nx < width && ny >= 0 && ny < height && !obstacles.has(neighbor)) {
62
+ neighbors.set(neighbor, 1); // Unit cost for grid movement
63
+ }
64
+ }
65
+
66
+ graph.set(node, neighbors);
67
+ }
68
+ }
69
+
70
+ return graph;
71
+ },
72
+
73
+ /**
74
+ * Parses a grid coordinate string
75
+ */
76
+ parseGridCoordinate(coord: string): [number, number] {
77
+ const parts = coord.split(",").map(Number);
78
+ const x = parts[0];
79
+ const y = parts[1];
80
+ if (x === undefined || y === undefined) {
81
+ throw new Error(`Invalid coordinate: ${coord}`);
82
+ }
83
+
84
+ return [x, y];
85
+ },
86
+ };
87
+
@@ -53,6 +53,17 @@ export interface ComponentResult {
53
53
  componentMap: Map<NodeId, number>;
54
54
  }
55
55
 
56
+ export interface MSTResult {
57
+ edges: Edge[];
58
+ totalWeight: number;
59
+ }
60
+
61
+ export interface FloydWarshallResult {
62
+ distances: Map<NodeId, Map<NodeId, number>>;
63
+ predecessors: Map<NodeId, Map<NodeId, NodeId | null>>;
64
+ hasNegativeCycle: boolean;
65
+ }
66
+
56
67
  // Algorithm options interfaces
57
68
  export interface TraversalOptions {
58
69
  targetNode?: NodeId;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Graph node interface for priority queue operations
3
+ */
4
+ export interface graphNode<T> {
5
+ node: T;
6
+ distance: number;
7
+ }
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Min Priority Queue implementation for graph algorithms
3
+ */
4
+ export class MinPriorityQueue<T> {
5
+ private heap: T[] = [];
6
+ private compare: (a: T, b: T) => number;
7
+
8
+ constructor(compareFunction?: (a: T, b: T) => number) {
9
+ this.compare = compareFunction ?? ((a: T, b: T) => this.defaultCompare(a, b));
10
+ }
11
+
12
+ private defaultCompare(a: T, b: T): number {
13
+ const aWithDistance = a as T & {distance?: number};
14
+ const bWithDistance = b as T & {distance?: number};
15
+
16
+ if (aWithDistance.distance !== undefined && bWithDistance.distance !== undefined) {
17
+ return aWithDistance.distance - bWithDistance.distance;
18
+ }
19
+
20
+ return 0;
21
+ }
22
+
23
+ private parent(i: number): number {
24
+ return Math.floor((i - 1) / 2);
25
+ }
26
+
27
+ private leftChild(i: number): number {
28
+ return (2 * i) + 1;
29
+ }
30
+
31
+ private rightChild(i: number): number {
32
+ return (2 * i) + 2;
33
+ }
34
+
35
+ private swap(i: number, j: number): void {
36
+ const temp = this.heap[i];
37
+ const temp2 = this.heap[j];
38
+ if (temp !== undefined && temp2 !== undefined) {
39
+ this.heap[i] = temp2;
40
+ this.heap[j] = temp;
41
+ }
42
+ }
43
+
44
+ private heapifyUp(index: number): void {
45
+ while (index > 0) {
46
+ const parentIndex = this.parent(index);
47
+ const current = this.heap[index];
48
+ const parent = this.heap[parentIndex];
49
+ if (current !== undefined && parent !== undefined && this.compare(current, parent) < 0) {
50
+ this.swap(index, parentIndex);
51
+ index = parentIndex;
52
+ } else {
53
+ break;
54
+ }
55
+ }
56
+ }
57
+
58
+ private heapifyDown(index: number): void {
59
+ while (index < this.heap.length) {
60
+ let minIndex = index;
61
+ const left = this.leftChild(index);
62
+ const right = this.rightChild(index);
63
+
64
+ const leftItem = this.heap[left];
65
+ const minItem = this.heap[minIndex];
66
+ if (left < this.heap.length && leftItem !== undefined && minItem !== undefined && this.compare(leftItem, minItem) < 0) {
67
+ minIndex = left;
68
+ }
69
+
70
+ const rightItem = this.heap[right];
71
+ const newMinItem = this.heap[minIndex];
72
+ if (right < this.heap.length && rightItem !== undefined && newMinItem !== undefined && this.compare(rightItem, newMinItem) < 0) {
73
+ minIndex = right;
74
+ }
75
+
76
+ if (minIndex !== index) {
77
+ this.swap(index, minIndex);
78
+ index = minIndex;
79
+ } else {
80
+ break;
81
+ }
82
+ }
83
+ }
84
+
85
+ insert(value: T): void {
86
+ this.heap.push(value);
87
+ this.heapifyUp(this.heap.length - 1);
88
+ }
89
+
90
+ extractMin(): T | undefined {
91
+ if (this.heap.length === 0) {
92
+ return undefined;
93
+ }
94
+
95
+ if (this.heap.length === 1) {
96
+ return this.heap.pop();
97
+ }
98
+
99
+ const min = this.heap[0];
100
+ const last = this.heap.pop();
101
+ if (last !== undefined) {
102
+ this.heap[0] = last;
103
+ this.heapifyDown(0);
104
+ }
105
+
106
+ return min;
107
+ }
108
+
109
+ peek(): T | undefined {
110
+ return this.heap[0];
111
+ }
112
+
113
+ isEmpty(): boolean {
114
+ return this.heap.length === 0;
115
+ }
116
+
117
+ size(): number {
118
+ return this.heap.length;
119
+ }
120
+ }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=basic.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"basic.test.d.ts","sourceRoot":"","sources":["../../../test/browser/basic.test.ts"],"names":[],"mappings":""}
@@ -1,70 +0,0 @@
1
- /* eslint-disable dot-notation */
2
- import { describe, expect, it } from "vitest";
3
- import { degreeCentrality } from "../../src/algorithms/centrality/degree.js";
4
- import { dijkstra } from "../../src/algorithms/shortest-path/dijkstra.js";
5
- import { breadthFirstSearch, depthFirstSearch } from "../../src/algorithms/traversal/index.js";
6
- import { Graph } from "../../src/core/graph.js";
7
- describe("Browser Environment Tests", () => {
8
- it("should create and manipulate graphs in browser", () => {
9
- const graph = new Graph();
10
- graph.addEdge("a", "b");
11
- graph.addEdge("b", "c");
12
- graph.addEdge("c", "d");
13
- expect(graph.nodeCount).toBe(4);
14
- expect(graph.totalEdgeCount).toBe(3);
15
- });
16
- it("should run BFS traversal in browser", () => {
17
- const graph = new Graph();
18
- graph.addEdge("a", "b");
19
- graph.addEdge("a", "c");
20
- graph.addEdge("b", "d");
21
- const result = breadthFirstSearch(graph, "a");
22
- expect(result.visited.size).toBe(4);
23
- expect(result.order).toHaveLength(4);
24
- expect(result.order[0]).toBe("a");
25
- });
26
- it("should run DFS traversal in browser", () => {
27
- const graph = new Graph();
28
- graph.addEdge("a", "b");
29
- graph.addEdge("a", "c");
30
- graph.addEdge("b", "d");
31
- const result = depthFirstSearch(graph, "a");
32
- expect(result.visited.size).toBe(4);
33
- expect(result.order).toHaveLength(4);
34
- expect(result.order[0]).toBe("a");
35
- });
36
- it("should calculate degree centrality in browser", () => {
37
- const graph = new Graph();
38
- graph.addEdge("center", "a");
39
- graph.addEdge("center", "b");
40
- graph.addEdge("center", "c");
41
- const centrality = degreeCentrality(graph);
42
- expect(centrality["center"]).toBe(3);
43
- expect(centrality["a"]).toBe(1);
44
- });
45
- it("should run Dijkstra algorithm in browser", () => {
46
- const graph = new Graph();
47
- graph.addEdge("a", "b", 1);
48
- graph.addEdge("b", "c", 2);
49
- graph.addEdge("a", "c", 4);
50
- const results = dijkstra(graph, "a");
51
- const resultC = results.get("c");
52
- expect(resultC).toBeDefined();
53
- expect(resultC?.distance).toBe(3); // a -> b -> c
54
- expect(resultC?.path).toEqual(["a", "b", "c"]);
55
- });
56
- it("should handle large graphs in browser", () => {
57
- const graph = new Graph();
58
- const nodeCount = 100;
59
- // Create a chain
60
- for (let i = 0; i < nodeCount - 1; i++) {
61
- graph.addEdge(i, i + 1);
62
- }
63
- expect(graph.nodeCount).toBe(nodeCount);
64
- // Run BFS to ensure traversal works
65
- const result = breadthFirstSearch(graph, 0);
66
- expect(result.visited.size).toBe(nodeCount);
67
- expect(result.order).toHaveLength(nodeCount);
68
- });
69
- });
70
- //# sourceMappingURL=basic.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"basic.test.js","sourceRoot":"","sources":["../../../test/browser/basic.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=bellman-ford.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bellman-ford.test.d.ts","sourceRoot":"","sources":["../../../test/unit/bellman-ford.test.ts"],"names":[],"mappings":""}