@graphty/algorithms 1.2.0 → 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.
Files changed (337) hide show
  1. package/README.md +375 -276
  2. package/dist/algorithms.d.ts +42 -2
  3. package/dist/algorithms.js +11402 -2
  4. package/dist/algorithms.js.map +1 -1
  5. package/dist/src/algorithms/centrality/betweenness.d.ts +14 -0
  6. package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
  7. package/dist/src/algorithms/centrality/betweenness.js +144 -169
  8. package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
  9. package/dist/src/algorithms/centrality/closeness.d.ts +35 -1
  10. package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -1
  11. package/dist/src/algorithms/centrality/closeness.js +70 -149
  12. package/dist/src/algorithms/centrality/closeness.js.map +1 -1
  13. package/dist/src/algorithms/centrality/degree.d.ts +7 -0
  14. package/dist/src/algorithms/centrality/degree.d.ts.map +1 -1
  15. package/dist/src/algorithms/centrality/degree.js +12 -9
  16. package/dist/src/algorithms/centrality/degree.js.map +1 -1
  17. package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts +57 -0
  18. package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts.map +1 -0
  19. package/dist/src/algorithms/centrality/delta-pagerank-simple.js +304 -0
  20. package/dist/src/algorithms/centrality/delta-pagerank-simple.js.map +1 -0
  21. package/dist/src/algorithms/centrality/delta-pagerank.d.ts +106 -0
  22. package/dist/src/algorithms/centrality/delta-pagerank.d.ts.map +1 -0
  23. package/dist/src/algorithms/centrality/delta-pagerank.js +320 -0
  24. package/dist/src/algorithms/centrality/delta-pagerank.js.map +1 -0
  25. package/dist/src/algorithms/centrality/eigenvector.d.ts +10 -3
  26. package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -1
  27. package/dist/src/algorithms/centrality/eigenvector.js +11 -4
  28. package/dist/src/algorithms/centrality/eigenvector.js.map +1 -1
  29. package/dist/src/algorithms/centrality/hits.d.ts +10 -3
  30. package/dist/src/algorithms/centrality/hits.d.ts.map +1 -1
  31. package/dist/src/algorithms/centrality/hits.js +11 -4
  32. package/dist/src/algorithms/centrality/hits.js.map +1 -1
  33. package/dist/src/algorithms/centrality/index.d.ts +3 -1
  34. package/dist/src/algorithms/centrality/index.d.ts.map +1 -1
  35. package/dist/src/algorithms/centrality/index.js +2 -1
  36. package/dist/src/algorithms/centrality/index.js.map +1 -1
  37. package/dist/src/algorithms/centrality/katz.d.ts +10 -3
  38. package/dist/src/algorithms/centrality/katz.d.ts.map +1 -1
  39. package/dist/src/algorithms/centrality/katz.js +13 -8
  40. package/dist/src/algorithms/centrality/katz.js.map +1 -1
  41. package/dist/src/algorithms/centrality/pagerank.d.ts +31 -0
  42. package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -1
  43. package/dist/src/algorithms/centrality/pagerank.js +61 -1
  44. package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
  45. package/dist/src/algorithms/community/girvan-newman.d.ts +2 -3
  46. package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -1
  47. package/dist/src/algorithms/community/girvan-newman.js +67 -57
  48. package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
  49. package/dist/src/algorithms/community/index.d.ts +2 -0
  50. package/dist/src/algorithms/community/index.d.ts.map +1 -1
  51. package/dist/src/algorithms/community/index.js.map +1 -1
  52. package/dist/src/algorithms/community/label-propagation.d.ts +11 -4
  53. package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -1
  54. package/dist/src/algorithms/community/label-propagation.js +60 -38
  55. package/dist/src/algorithms/community/label-propagation.js.map +1 -1
  56. package/dist/src/algorithms/community/leiden.d.ts +3 -3
  57. package/dist/src/algorithms/community/leiden.d.ts.map +1 -1
  58. package/dist/src/algorithms/community/leiden.js +70 -44
  59. package/dist/src/algorithms/community/leiden.js.map +1 -1
  60. package/dist/src/algorithms/community/louvain-optimized.d.ts +149 -0
  61. package/dist/src/algorithms/community/louvain-optimized.d.ts.map +1 -0
  62. package/dist/src/algorithms/community/louvain-optimized.js +338 -0
  63. package/dist/src/algorithms/community/louvain-optimized.js.map +1 -0
  64. package/dist/src/algorithms/community/louvain.d.ts +2 -3
  65. package/dist/src/algorithms/community/louvain.d.ts.map +1 -1
  66. package/dist/src/algorithms/community/louvain.js +35 -81
  67. package/dist/src/algorithms/community/louvain.js.map +1 -1
  68. package/dist/src/algorithms/community/modularity-utils.d.ts +55 -0
  69. package/dist/src/algorithms/community/modularity-utils.d.ts.map +1 -0
  70. package/dist/src/algorithms/community/modularity-utils.js +108 -0
  71. package/dist/src/algorithms/community/modularity-utils.js.map +1 -0
  72. package/dist/src/algorithms/components/connected.d.ts +23 -0
  73. package/dist/src/algorithms/components/connected.d.ts.map +1 -1
  74. package/dist/src/algorithms/components/connected.js +29 -3
  75. package/dist/src/algorithms/components/connected.js.map +1 -1
  76. package/dist/src/algorithms/matching/bipartite.d.ts +10 -0
  77. package/dist/src/algorithms/matching/bipartite.d.ts.map +1 -1
  78. package/dist/src/algorithms/matching/bipartite.js +18 -40
  79. package/dist/src/algorithms/matching/bipartite.js.map +1 -1
  80. package/dist/src/algorithms/matching/index.d.ts.map +1 -1
  81. package/dist/src/algorithms/matching/index.js.map +1 -1
  82. package/dist/src/algorithms/matching/isomorphism.d.ts +8 -0
  83. package/dist/src/algorithms/matching/isomorphism.d.ts.map +1 -1
  84. package/dist/src/algorithms/matching/isomorphism.js +36 -2
  85. package/dist/src/algorithms/matching/isomorphism.js.map +1 -1
  86. package/dist/src/algorithms/mst/index.d.ts.map +1 -1
  87. package/dist/src/algorithms/mst/index.js.map +1 -1
  88. package/dist/src/algorithms/mst/kruskal.d.ts +14 -0
  89. package/dist/src/algorithms/mst/kruskal.d.ts.map +1 -1
  90. package/dist/src/algorithms/mst/kruskal.js +17 -3
  91. package/dist/src/algorithms/mst/kruskal.js.map +1 -1
  92. package/dist/src/algorithms/mst/prim.d.ts +9 -0
  93. package/dist/src/algorithms/mst/prim.d.ts.map +1 -1
  94. package/dist/src/algorithms/mst/prim.js +9 -0
  95. package/dist/src/algorithms/mst/prim.js.map +1 -1
  96. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts +10 -0
  97. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -1
  98. package/dist/src/algorithms/shortest-path/bellman-ford.js +11 -12
  99. package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
  100. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts +44 -0
  101. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts.map +1 -0
  102. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js +195 -0
  103. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js.map +1 -0
  104. package/dist/src/algorithms/shortest-path/dijkstra.d.ts +20 -2
  105. package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -1
  106. package/dist/src/algorithms/shortest-path/dijkstra.js +30 -14
  107. package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
  108. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts +17 -0
  109. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts.map +1 -1
  110. package/dist/src/algorithms/shortest-path/floyd-warshall.js +17 -0
  111. package/dist/src/algorithms/shortest-path/floyd-warshall.js.map +1 -1
  112. package/dist/src/algorithms/shortest-path/index.d.ts.map +1 -1
  113. package/dist/src/algorithms/shortest-path/index.js.map +1 -1
  114. package/dist/src/algorithms/traversal/bfs-unified.d.ts +42 -0
  115. package/dist/src/algorithms/traversal/bfs-unified.d.ts.map +1 -0
  116. package/dist/src/algorithms/traversal/bfs-unified.js +370 -0
  117. package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -0
  118. package/dist/src/algorithms/traversal/bfs-variants.d.ts +77 -0
  119. package/dist/src/algorithms/traversal/bfs-variants.d.ts.map +1 -0
  120. package/dist/src/algorithms/traversal/bfs-variants.js +402 -0
  121. package/dist/src/algorithms/traversal/bfs-variants.js.map +1 -0
  122. package/dist/src/algorithms/traversal/bfs.d.ts +4 -18
  123. package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -1
  124. package/dist/src/algorithms/traversal/bfs.js +5 -182
  125. package/dist/src/algorithms/traversal/bfs.js.map +1 -1
  126. package/dist/src/algorithms/traversal/dfs.d.ts +10 -0
  127. package/dist/src/algorithms/traversal/dfs.d.ts.map +1 -1
  128. package/dist/src/algorithms/traversal/dfs.js +48 -0
  129. package/dist/src/algorithms/traversal/dfs.js.map +1 -1
  130. package/dist/src/algorithms/traversal/index.d.ts.map +1 -1
  131. package/dist/src/algorithms/traversal/index.js.map +1 -1
  132. package/dist/src/benchmark-all-algorithms.d.ts +25 -0
  133. package/dist/src/benchmark-all-algorithms.d.ts.map +1 -0
  134. package/dist/src/benchmark-all-algorithms.js +491 -0
  135. package/dist/src/benchmark-all-algorithms.js.map +1 -0
  136. package/dist/src/clustering/hierarchical.d.ts +23 -15
  137. package/dist/src/clustering/hierarchical.d.ts.map +1 -1
  138. package/dist/src/clustering/hierarchical.js +226 -224
  139. package/dist/src/clustering/hierarchical.js.map +1 -1
  140. package/dist/src/clustering/index.d.ts +4 -2
  141. package/dist/src/clustering/index.d.ts.map +1 -1
  142. package/dist/src/clustering/index.js +2 -2
  143. package/dist/src/clustering/index.js.map +1 -1
  144. package/dist/src/clustering/k-core.d.ts +17 -19
  145. package/dist/src/clustering/k-core.d.ts.map +1 -1
  146. package/dist/src/clustering/k-core.js +68 -30
  147. package/dist/src/clustering/k-core.js.map +1 -1
  148. package/dist/src/clustering/mcl.d.ts +6 -0
  149. package/dist/src/clustering/mcl.d.ts.map +1 -1
  150. package/dist/src/clustering/mcl.js +34 -3
  151. package/dist/src/clustering/mcl.js.map +1 -1
  152. package/dist/src/clustering/spectral.d.ts +11 -0
  153. package/dist/src/clustering/spectral.d.ts.map +1 -1
  154. package/dist/src/clustering/spectral.js +99 -47
  155. package/dist/src/clustering/spectral.js.map +1 -1
  156. package/dist/src/core/graph.d.ts +45 -0
  157. package/dist/src/core/graph.d.ts.map +1 -1
  158. package/dist/src/core/graph.js +49 -5
  159. package/dist/src/core/graph.js.map +1 -1
  160. package/dist/src/data-structures/index.d.ts.map +1 -1
  161. package/dist/src/data-structures/index.js.map +1 -1
  162. package/dist/src/data-structures/priority-queue.d.ts +18 -1
  163. package/dist/src/data-structures/priority-queue.d.ts.map +1 -1
  164. package/dist/src/data-structures/priority-queue.js +26 -5
  165. package/dist/src/data-structures/priority-queue.js.map +1 -1
  166. package/dist/src/data-structures/union-find.d.ts +21 -0
  167. package/dist/src/data-structures/union-find.d.ts.map +1 -1
  168. package/dist/src/data-structures/union-find.js +21 -0
  169. package/dist/src/data-structures/union-find.js.map +1 -1
  170. package/dist/src/flow/ford-fulkerson.d.ts +20 -12
  171. package/dist/src/flow/ford-fulkerson.d.ts.map +1 -1
  172. package/dist/src/flow/ford-fulkerson.js +170 -217
  173. package/dist/src/flow/ford-fulkerson.js.map +1 -1
  174. package/dist/src/flow/min-cut.d.ts +6 -8
  175. package/dist/src/flow/min-cut.d.ts.map +1 -1
  176. package/dist/src/flow/min-cut.js +34 -12
  177. package/dist/src/flow/min-cut.js.map +1 -1
  178. package/dist/src/index.d.ts +3 -1
  179. package/dist/src/index.d.ts.map +1 -1
  180. package/dist/src/index.js +6 -1
  181. package/dist/src/index.js.map +1 -1
  182. package/dist/src/link-prediction/adamic-adar.d.ts +26 -0
  183. package/dist/src/link-prediction/adamic-adar.d.ts.map +1 -1
  184. package/dist/src/link-prediction/adamic-adar.js +47 -30
  185. package/dist/src/link-prediction/adamic-adar.js.map +1 -1
  186. package/dist/src/link-prediction/common-neighbors.d.ts +21 -0
  187. package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -1
  188. package/dist/src/link-prediction/common-neighbors.js +31 -14
  189. package/dist/src/link-prediction/common-neighbors.js.map +1 -1
  190. package/dist/src/link-prediction/index.d.ts.map +1 -1
  191. package/dist/src/optimized/bit-packed.d.ts +193 -0
  192. package/dist/src/optimized/bit-packed.d.ts.map +1 -0
  193. package/dist/src/optimized/bit-packed.js +342 -0
  194. package/dist/src/optimized/bit-packed.js.map +1 -0
  195. package/dist/src/optimized/csr-graph.d.ts +149 -0
  196. package/dist/src/optimized/csr-graph.d.ts.map +1 -0
  197. package/dist/src/optimized/csr-graph.js +404 -0
  198. package/dist/src/optimized/csr-graph.js.map +1 -0
  199. package/dist/src/optimized/direction-optimized-bfs.d.ts +95 -0
  200. package/dist/src/optimized/direction-optimized-bfs.d.ts.map +1 -0
  201. package/dist/src/optimized/direction-optimized-bfs.js +242 -0
  202. package/dist/src/optimized/direction-optimized-bfs.js.map +1 -0
  203. package/dist/src/optimized/graph-adapter.d.ts +111 -0
  204. package/dist/src/optimized/graph-adapter.d.ts.map +1 -0
  205. package/dist/src/optimized/graph-adapter.js +194 -0
  206. package/dist/src/optimized/graph-adapter.js.map +1 -0
  207. package/dist/src/optimized/index.d.ts +14 -0
  208. package/dist/src/optimized/index.d.ts.map +1 -0
  209. package/dist/src/optimized/index.js +30 -0
  210. package/dist/src/optimized/index.js.map +1 -0
  211. package/dist/src/pathfinding/astar.d.ts +25 -9
  212. package/dist/src/pathfinding/astar.d.ts.map +1 -1
  213. package/dist/src/pathfinding/astar.js +25 -10
  214. package/dist/src/pathfinding/astar.js.map +1 -1
  215. package/dist/src/pathfinding/utils.d.ts +15 -6
  216. package/dist/src/pathfinding/utils.d.ts.map +1 -1
  217. package/dist/src/pathfinding/utils.js +19 -7
  218. package/dist/src/pathfinding/utils.js.map +1 -1
  219. package/dist/src/research/grsbm.d.ts +0 -1
  220. package/dist/src/research/grsbm.d.ts.map +1 -1
  221. package/dist/src/research/grsbm.js +28 -23
  222. package/dist/src/research/grsbm.js.map +1 -1
  223. package/dist/src/research/index.d.ts.map +1 -1
  224. package/dist/src/research/index.js.map +1 -1
  225. package/dist/src/research/sync.d.ts +0 -1
  226. package/dist/src/research/sync.d.ts.map +1 -1
  227. package/dist/src/research/sync.js +31 -36
  228. package/dist/src/research/sync.js.map +1 -1
  229. package/dist/src/research/terahac.d.ts +2 -1
  230. package/dist/src/research/terahac.d.ts.map +1 -1
  231. package/dist/src/research/terahac.js +39 -7
  232. package/dist/src/research/terahac.js.map +1 -1
  233. package/dist/src/types/index.d.ts +8 -0
  234. package/dist/src/types/index.d.ts.map +1 -1
  235. package/dist/src/utils/algorithm-utilities.d.ts +2 -0
  236. package/dist/src/utils/algorithm-utilities.d.ts.map +1 -0
  237. package/dist/src/utils/algorithm-utilities.js +2 -0
  238. package/dist/src/utils/algorithm-utilities.js.map +1 -0
  239. package/dist/src/utils/graph-converters.d.ts +110 -0
  240. package/dist/src/utils/graph-converters.d.ts.map +1 -0
  241. package/dist/src/utils/graph-converters.js +227 -0
  242. package/dist/src/utils/graph-converters.js.map +1 -0
  243. package/dist/src/utils/graph-utilities.d.ts +62 -0
  244. package/dist/src/utils/graph-utilities.d.ts.map +1 -0
  245. package/dist/src/utils/graph-utilities.js +148 -0
  246. package/dist/src/utils/graph-utilities.js.map +1 -0
  247. package/dist/src/utils/index.d.ts +5 -0
  248. package/dist/src/utils/index.d.ts.map +1 -0
  249. package/dist/src/utils/index.js +5 -0
  250. package/dist/src/utils/index.js.map +1 -0
  251. package/dist/src/utils/math-utilities.d.ts +63 -0
  252. package/dist/src/utils/math-utilities.d.ts.map +1 -0
  253. package/dist/src/utils/math-utilities.js +132 -0
  254. package/dist/src/utils/math-utilities.js.map +1 -0
  255. package/dist/src/utils/matrix-utilities.d.ts +2 -0
  256. package/dist/src/utils/matrix-utilities.d.ts.map +1 -0
  257. package/dist/src/utils/matrix-utilities.js +2 -0
  258. package/dist/src/utils/matrix-utilities.js.map +1 -0
  259. package/dist/src/utils/optimization-helpers.d.ts +42 -0
  260. package/dist/src/utils/optimization-helpers.d.ts.map +1 -0
  261. package/dist/src/utils/optimization-helpers.js +59 -0
  262. package/dist/src/utils/optimization-helpers.js.map +1 -0
  263. package/dist/src/utils/priorityQueue.d.ts +24 -0
  264. package/dist/src/utils/priorityQueue.d.ts.map +1 -1
  265. package/dist/src/utils/priorityQueue.js +34 -4
  266. package/dist/src/utils/priorityQueue.js.map +1 -1
  267. package/package.json +58 -39
  268. package/src/algorithms/centrality/betweenness.ts +185 -200
  269. package/src/algorithms/centrality/closeness.ts +93 -194
  270. package/src/algorithms/centrality/degree.ts +18 -22
  271. package/src/algorithms/centrality/delta-pagerank-simple.ts +374 -0
  272. package/src/algorithms/centrality/delta-pagerank.ts +458 -0
  273. package/src/algorithms/centrality/eigenvector.ts +14 -15
  274. package/src/algorithms/centrality/hits.ts +17 -17
  275. package/src/algorithms/centrality/index.ts +20 -13
  276. package/src/algorithms/centrality/katz.ts +17 -25
  277. package/src/algorithms/centrality/pagerank.ts +91 -16
  278. package/src/algorithms/community/girvan-newman.ts +90 -86
  279. package/src/algorithms/community/index.ts +6 -5
  280. package/src/algorithms/community/label-propagation.ts +69 -48
  281. package/src/algorithms/community/leiden.ts +88 -65
  282. package/src/algorithms/community/louvain-optimized.ts +474 -0
  283. package/src/algorithms/community/louvain.ts +52 -122
  284. package/src/algorithms/community/modularity-utils.ts +134 -0
  285. package/src/algorithms/components/connected.ts +40 -17
  286. package/src/algorithms/matching/bipartite.ts +24 -53
  287. package/src/algorithms/matching/index.ts +4 -4
  288. package/src/algorithms/matching/isomorphism.ts +53 -23
  289. package/src/algorithms/mst/index.ts +3 -4
  290. package/src/algorithms/mst/kruskal.ts +21 -6
  291. package/src/algorithms/mst/prim.ts +13 -4
  292. package/src/algorithms/shortest-path/bellman-ford.ts +16 -28
  293. package/src/algorithms/shortest-path/bidirectional-dijkstra.ts +248 -0
  294. package/src/algorithms/shortest-path/dijkstra.ts +38 -30
  295. package/src/algorithms/shortest-path/floyd-warshall.ts +21 -4
  296. package/src/algorithms/shortest-path/index.ts +5 -5
  297. package/src/algorithms/traversal/bfs-unified.ts +437 -0
  298. package/src/algorithms/traversal/bfs-variants.ts +520 -0
  299. package/src/algorithms/traversal/bfs.ts +5 -229
  300. package/src/algorithms/traversal/dfs.ts +61 -42
  301. package/src/algorithms/traversal/index.ts +3 -3
  302. package/src/benchmark-all-algorithms.ts +580 -0
  303. package/src/clustering/hierarchical.ts +268 -272
  304. package/src/clustering/index.ts +8 -6
  305. package/src/clustering/k-core.ts +93 -61
  306. package/src/clustering/mcl.ts +53 -23
  307. package/src/clustering/spectral.ts +130 -72
  308. package/src/core/graph.ts +58 -18
  309. package/src/data-structures/index.ts +2 -2
  310. package/src/data-structures/priority-queue.ts +36 -11
  311. package/src/data-structures/union-find.ts +22 -1
  312. package/src/flow/ford-fulkerson.ts +221 -262
  313. package/src/flow/min-cut.ts +59 -51
  314. package/src/index.ts +9 -2
  315. package/src/link-prediction/adamic-adar.ts +75 -74
  316. package/src/link-prediction/common-neighbors.ts +49 -49
  317. package/src/link-prediction/index.ts +1 -1
  318. package/src/optimized/bit-packed.ts +390 -0
  319. package/src/optimized/csr-graph.ts +518 -0
  320. package/src/optimized/direction-optimized-bfs.ts +310 -0
  321. package/src/optimized/graph-adapter.ts +248 -0
  322. package/src/optimized/index.ts +34 -0
  323. package/src/pathfinding/astar.ts +40 -25
  324. package/src/pathfinding/utils.ts +20 -13
  325. package/src/research/grsbm.ts +36 -39
  326. package/src/research/index.ts +4 -4
  327. package/src/research/sync.ts +41 -54
  328. package/src/research/terahac.ts +63 -21
  329. package/src/types/index.ts +8 -0
  330. package/src/utils/algorithm-utilities.ts +2 -0
  331. package/src/utils/graph-converters.ts +269 -0
  332. package/src/utils/graph-utilities.ts +173 -0
  333. package/src/utils/index.ts +4 -0
  334. package/src/utils/math-utilities.ts +149 -0
  335. package/src/utils/matrix-utilities.ts +2 -0
  336. package/src/utils/optimization-helpers.ts +87 -0
  337. package/src/utils/priorityQueue.ts +40 -6
@@ -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[], cost: number} | null {
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
- path: T[] | null;
113
- cost: number;
114
- visited: Set<T>;
115
- gScores: Map<T, number>;
116
- fScores: Map<T, number>;
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
- * Manhattan distance heuristic for grid-based graphs
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
- * Euclidean distance heuristic
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
- * Chebyshev distance heuristic (diagonal movement allowed)
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
- * Zero heuristic (makes A* behave like Dijkstra)
226
- */
227
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
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
  };
@@ -4,8 +4,11 @@
4
4
 
5
5
  export const pathfindingUtils = {
6
6
  /**
7
- * Reconstructs a path from start to goal using the cameFrom map
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
- * 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>> {
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], [1, 0], [0, -1], [-1, 0],
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
- * Parses a grid coordinate string
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
-
@@ -1,5 +1,6 @@
1
- import type {Graph} from "../core/graph.js";
2
- import type {NodeId} from "../types/index.js";
1
+ import type { Graph } from "../core/graph.js";
2
+ import type { NodeId } from "../types/index.js";
3
+ import { SeededRandom } from "../utils/math-utilities.js";
3
4
 
4
5
  /**
5
6
  * Configuration options for the GRSBM (Greedy Recursive Spectral Bisection) algorithm
@@ -79,7 +80,6 @@ export interface ClusterExplanation {
79
80
  * community structure by tracking the reasoning behind each split.
80
81
  *
81
82
  * Based on: "Explainable Community Detection via Hierarchical Spectral Clustering" (2024)
82
- *
83
83
  * @param graph - Input graph to cluster
84
84
  * @param config - Configuration options
85
85
  * @returns Hierarchical clustering result with explanations
@@ -95,7 +95,9 @@ export function grsbm(graph: Graph, config: GRSBMConfig = {}): GRSBMResult {
95
95
  } = config;
96
96
 
97
97
  // Set random seed for reproducibility
98
- Math.random = seedRandom(seed);
98
+ const rng = SeededRandom.createGenerator(seed);
99
+ const originalRandom = Math.random;
100
+ Math.random = rng;
99
101
 
100
102
  const nodes = Array.from(graph.nodes());
101
103
  const nodeCount = nodes.length;
@@ -106,7 +108,7 @@ export function grsbm(graph: Graph, config: GRSBMConfig = {}): GRSBMResult {
106
108
 
107
109
  // Initialize root cluster with all nodes
108
110
  const rootMembers = new Set(nodes.map((node) => node.id));
109
- const initialModularity = calculateModularity(graph, new Map([... rootMembers].map((id) => [id, 0])));
111
+ const initialModularity = calculateModularity(graph, new Map([...rootMembers].map((id) => [id, 0])));
110
112
 
111
113
  const root: GRSBMCluster = {
112
114
  id: "root",
@@ -130,25 +132,18 @@ export function grsbm(graph: Graph, config: GRSBMConfig = {}): GRSBMResult {
130
132
  }
131
133
 
132
134
  // Check stopping criteria
133
- if (currentCluster.depth >= maxDepth ||
134
- currentCluster.members.size < minClusterSize * 2) {
135
+ if (currentCluster.depth >= maxDepth || currentCluster.members.size < minClusterSize * 2) {
135
136
  continue;
136
137
  }
137
138
 
138
139
  // Attempt spectral bisection
139
- const bisectionResult = spectralBisection(
140
- graph,
141
- currentCluster,
142
- numEigenvectors,
143
- tolerance,
144
- maxIterations,
145
- );
140
+ const bisectionResult = spectralBisection(graph, currentCluster, numEigenvectors, tolerance, maxIterations);
146
141
 
147
142
  if (!bisectionResult) {
148
143
  continue; // Could not split this cluster
149
144
  }
150
145
 
151
- const {leftMembers, rightMembers, spectralScore, keyNodes, spectralValues, reason} = bisectionResult;
146
+ const { leftMembers, rightMembers, spectralScore, keyNodes, spectralValues, reason } = bisectionResult;
152
147
 
153
148
  // Create child clusters
154
149
  const leftCluster: GRSBMCluster = {
@@ -180,7 +175,8 @@ export function grsbm(graph: Graph, config: GRSBMConfig = {}): GRSBMResult {
180
175
  const modularityImprovement = newModularity - currentCluster.modularity;
181
176
 
182
177
  // Only split if modularity improves or is neutral (allow small splits)
183
- if (modularityImprovement >= -0.01) { // Small tolerance for neutral splits
178
+ if (modularityImprovement >= -0.01) {
179
+ // Small tolerance for neutral splits
184
180
  leftCluster.modularity = newModularity;
185
181
  rightCluster.modularity = newModularity;
186
182
 
@@ -228,6 +224,9 @@ export function grsbm(graph: Graph, config: GRSBMConfig = {}): GRSBMResult {
228
224
 
229
225
  assignClusterIds(root);
230
226
 
227
+ // Restore original random function
228
+ Math.random = originalRandom;
229
+
231
230
  return {
232
231
  root,
233
232
  clusters,
@@ -239,6 +238,12 @@ export function grsbm(graph: Graph, config: GRSBMConfig = {}): GRSBMResult {
239
238
 
240
239
  /**
241
240
  * Perform spectral bisection on a cluster
241
+ * @param graph - The input graph
242
+ * @param cluster - The cluster to bisect
243
+ * @param numEigenvectors - Number of eigenvectors to compute
244
+ * @param tolerance - Convergence tolerance
245
+ * @param maxIterations - Maximum number of iterations
246
+ * @returns Bisection result with left/right members, scores, and explanation, or null if bisection failed
242
247
  */
243
248
  function spectralBisection(
244
249
  graph: Graph,
@@ -272,9 +277,7 @@ function spectralBisection(
272
277
  }
273
278
 
274
279
  // Find optimal split point
275
- const sortedIndices = eigenvector
276
- .map((value, index) => ({value, index}))
277
- .sort((a, b) => a.value - b.value);
280
+ const sortedIndices = eigenvector.map((value, index) => ({ value, index })).sort((a, b) => a.value - b.value);
278
281
 
279
282
  let bestSplitIndex = Math.floor(n / 2);
280
283
  let bestModularity = -Infinity;
@@ -329,7 +332,7 @@ function spectralBisection(
329
332
 
330
333
  // Identify key nodes (those with extreme spectral values)
331
334
  const extremeThreshold = 0.1;
332
- const sortedValues = [... eigenvector].sort((a, b) => Math.abs(b) - Math.abs(a));
335
+ const sortedValues = [...eigenvector].sort((a, b) => Math.abs(b) - Math.abs(a));
333
336
  const threshold = sortedValues[Math.floor(sortedValues.length * extremeThreshold)] ?? 0;
334
337
 
335
338
  const keyNodes: NodeId[] = [];
@@ -363,6 +366,9 @@ function spectralBisection(
363
366
 
364
367
  /**
365
368
  * Create Laplacian matrix for a subgraph
369
+ * @param graph - The input graph
370
+ * @param nodes - The nodes to include in the subgraph
371
+ * @returns The Laplacian matrix as a 2D array
366
372
  */
367
373
  function createLaplacianMatrix(graph: Graph, nodes: NodeId[]): number[][] {
368
374
  const n = nodes.length;
@@ -377,7 +383,7 @@ function createLaplacianMatrix(graph: Graph, nodes: NodeId[]): number[][] {
377
383
  }
378
384
 
379
385
  // Initialize Laplacian matrix
380
- const laplacian = Array.from({length: n}, () => new Array<number>(n).fill(0));
386
+ const laplacian = Array.from({ length: n }, () => new Array<number>(n).fill(0));
381
387
 
382
388
  // Fill adjacency part and calculate degrees
383
389
  const degrees = new Array<number>(n).fill(0);
@@ -414,6 +420,10 @@ function createLaplacianMatrix(graph: Graph, nodes: NodeId[]): number[][] {
414
420
 
415
421
  /**
416
422
  * Compute the Fiedler vector (second smallest eigenvector) using power iteration
423
+ * @param laplacian - The Laplacian matrix
424
+ * @param tolerance - Convergence tolerance
425
+ * @param maxIterations - Maximum number of iterations
426
+ * @returns The Fiedler vector, or null if computation failed
417
427
  */
418
428
  function computeFiedlerVector(laplacian: number[][], tolerance: number, maxIterations: number): number[] | null {
419
429
  const n = laplacian.length;
@@ -437,7 +447,7 @@ function computeFiedlerVector(laplacian: number[][], tolerance: number, maxItera
437
447
  }
438
448
 
439
449
  // Normalize
440
- const norm = Math.sqrt(vector.reduce((sum: number, val: number) => sum + (val * val), 0));
450
+ const norm = Math.sqrt(vector.reduce((sum: number, val: number) => sum + val * val, 0));
441
451
  if (norm > 0) {
442
452
  for (let i = 0; i < n; i++) {
443
453
  const val = vector[i];
@@ -488,7 +498,7 @@ function computeFiedlerVector(laplacian: number[][], tolerance: number, maxItera
488
498
  }
489
499
 
490
500
  // Normalize
491
- const newNorm = Math.sqrt(newVector.reduce((sum, val) => sum + (val * val), 0));
501
+ const newNorm = Math.sqrt(newVector.reduce((sum, val) => sum + val * val, 0));
492
502
  if (newNorm < tolerance) {
493
503
  break; // Converged to zero vector
494
504
  }
@@ -522,6 +532,9 @@ function computeFiedlerVector(laplacian: number[][], tolerance: number, maxItera
522
532
 
523
533
  /**
524
534
  * Calculate modularity of a graph partitioning
535
+ * @param graph - The input graph
536
+ * @param assignment - Map from node ID to community ID
537
+ * @returns The modularity score
525
538
  */
526
539
  function calculateModularity(graph: Graph, assignment: Map<NodeId, number>): number {
527
540
  const totalEdges = graph.uniqueEdgeCount;
@@ -571,19 +584,3 @@ function calculateModularity(graph: Graph, assignment: Map<NodeId, number>): num
571
584
 
572
585
  return modularity;
573
586
  }
574
-
575
- /**
576
- * Simple seeded random number generator for reproducibility
577
- */
578
- function seedRandom(seed: number): () => number {
579
- const m = 0x80000000; // 2**31
580
- const a = 1103515245;
581
- const c = 12345;
582
-
583
- seed = seed % m;
584
-
585
- return function() {
586
- seed = ((a * seed) + c) % m;
587
- return seed / (m - 1);
588
- };
589
- }
@@ -7,11 +7,11 @@
7
7
  */
8
8
 
9
9
  // Synergistic Deep Graph Clustering
10
- export {syncClustering, type SynCConfig, type SynCResult} from "./sync.js";
10
+ export { syncClustering, type SynCConfig, type SynCResult } from "./sync.js";
11
11
 
12
12
  // TeraHAC - Hierarchical Agglomerative Clustering
13
- export {teraHAC, type TeraHACConfig, type TeraHACResult} from "./terahac.js";
14
- export {type ClusterNode as TeraHACClusterNode} from "./terahac.js";
13
+ export { teraHAC, type TeraHACConfig, type TeraHACResult } from "./terahac.js";
14
+ export { type ClusterNode as TeraHACClusterNode } from "./terahac.js";
15
15
 
16
16
  // GRSBM - Greedy Recursive Spectral Bisection with Modularity
17
- export {type ClusterExplanation, grsbm, type GRSBMCluster, type GRSBMConfig, type GRSBMResult} from "./grsbm.js";
17
+ export { type ClusterExplanation, grsbm, type GRSBMCluster, type GRSBMConfig, type GRSBMResult } from "./grsbm.js";
@@ -1,5 +1,6 @@
1
- import type {Graph} from "../core/graph.js";
2
- import type {NodeId} from "../types/index.js";
1
+ import type { Graph } from "../core/graph.js";
2
+ import type { NodeId } from "../types/index.js";
3
+ import { euclideanDistance, SeededRandom } from "../utils/math-utilities.js";
3
4
 
4
5
  /**
5
6
  * Configuration options for the SynC (Synergistic Deep Graph Clustering) algorithm
@@ -43,24 +44,17 @@ export interface SynCResult {
43
44
  * embeddings and cluster assignments while preserving graph structure.
44
45
  *
45
46
  * Based on: "Synergistic Deep Graph Clustering" (arXiv:2406.15797, June 2024)
46
- *
47
47
  * @param graph - Input graph to cluster
48
48
  * @param config - Configuration options
49
49
  * @returns Clustering result with assignments and embeddings
50
50
  */
51
51
  export function syncClustering(graph: Graph, config: SynCConfig): SynCResult {
52
- const {
53
- numClusters,
54
- maxIterations = 100,
55
- tolerance = 1e-6,
56
- seed = 42,
57
- learningRate = 0.01,
58
- lambda = 0.1,
59
- } = config;
52
+ const { numClusters, maxIterations = 100, tolerance = 1e-6, seed = 42, learningRate = 0.01, lambda = 0.1 } = config;
60
53
 
61
54
  // Set random seed for reproducibility (save original)
62
55
  const originalRandom = Math.random;
63
- Math.random = seedRandom(seed);
56
+ const rng = SeededRandom.createGenerator(seed);
57
+ Math.random = rng;
64
58
 
65
59
  const nodes = Array.from(graph.nodes());
66
60
  const nodeCount = nodes.length;
@@ -76,7 +70,9 @@ export function syncClustering(graph: Graph, config: SynCConfig): SynCResult {
76
70
  }
77
71
 
78
72
  if (numClusters <= 0 || numClusters > nodeCount) {
79
- throw new Error(`Invalid number of clusters: ${String(numClusters)}. Must be between 1 and ${String(nodeCount)}`);
73
+ throw new Error(
74
+ `Invalid number of clusters: ${String(numClusters)}. Must be between 1 and ${String(nodeCount)}`,
75
+ );
80
76
  }
81
77
 
82
78
  // Initialize node embeddings (simplified version using graph features)
@@ -182,6 +178,10 @@ export function syncClustering(graph: Graph, config: SynCConfig): SynCResult {
182
178
 
183
179
  /**
184
180
  * Initialize node embedding based on graph structure and features
181
+ * @param graph - The input graph
182
+ * @param nodeId - The node ID to initialize embedding for
183
+ * @param dim - The embedding dimension
184
+ * @returns The initialized embedding vector
185
185
  */
186
186
  function initializeNodeEmbedding(graph: Graph, nodeId: NodeId, dim: number): number[] {
187
187
  const embedding = new Array<number>(dim).fill(0);
@@ -192,7 +192,7 @@ function initializeNodeEmbedding(graph: Graph, nodeId: NodeId, dim: number): num
192
192
 
193
193
  // Initialize with small random values influenced by graph structure
194
194
  for (let i = 0; i < dim; i++) {
195
- embedding[i] = ((Math.random() - 0.5) * 0.1) + (normalizedDegree * 0.1);
195
+ embedding[i] = (Math.random() - 0.5) * 0.1 + normalizedDegree * 0.1;
196
196
  }
197
197
 
198
198
  return embedding;
@@ -200,6 +200,9 @@ function initializeNodeEmbedding(graph: Graph, nodeId: NodeId, dim: number): num
200
200
 
201
201
  /**
202
202
  * Initialize cluster centers using k-means++ style initialization
203
+ * @param embeddings - Map of node IDs to embedding vectors
204
+ * @param numClusters - Number of cluster centers to initialize
205
+ * @returns Array of initialized cluster center vectors
203
206
  */
204
207
  function initializeClusterCenters(embeddings: Map<NodeId, number[]>, numClusters: number): number[][] {
205
208
  const embeddingArray = Array.from(embeddings.values());
@@ -208,7 +211,7 @@ function initializeClusterCenters(embeddings: Map<NodeId, number[]>, numClusters
208
211
  // Choose first center randomly
209
212
  const firstCenter = embeddingArray[Math.floor(Math.random() * embeddingArray.length)];
210
213
  if (firstCenter) {
211
- centers.push([... firstCenter] as number[]);
214
+ centers.push([...firstCenter] as number[]);
212
215
  }
213
216
 
214
217
  // Choose remaining centers using k-means++ initialization
@@ -237,7 +240,7 @@ function initializeClusterCenters(embeddings: Map<NodeId, number[]>, numClusters
237
240
  if (randomValue <= 0) {
238
241
  const newCenter = embeddingArray[i];
239
242
  if (newCenter) {
240
- centers.push([... newCenter] as number[]);
243
+ centers.push([...newCenter] as number[]);
241
244
  }
242
245
 
243
246
  break;
@@ -250,6 +253,11 @@ function initializeClusterCenters(embeddings: Map<NodeId, number[]>, numClusters
250
253
 
251
254
  /**
252
255
  * Update node embeddings using gradient descent
256
+ * @param graph - The input graph
257
+ * @param embeddings - Map of node IDs to embedding vectors
258
+ * @param clusters - Map of node IDs to cluster assignments
259
+ * @param learningRate - Learning rate for gradient descent
260
+ * @param lambda - Regularization parameter
253
261
  */
254
262
  function updateEmbeddings(
255
263
  graph: Graph,
@@ -291,7 +299,7 @@ function updateEmbeddings(
291
299
  const gradVal = gradient[i];
292
300
  const diffVal = diff[i];
293
301
  if (gradVal !== undefined && diffVal !== undefined) {
294
- gradient[i] = gradVal + (lambda * diffVal);
302
+ gradient[i] = gradVal + lambda * diffVal;
295
303
  }
296
304
  }
297
305
  }
@@ -301,7 +309,7 @@ function updateEmbeddings(
301
309
  const gradVal = gradient[i];
302
310
  const nodeVal = nodeEmbedding[i];
303
311
  if (gradVal !== undefined && nodeVal !== undefined) {
304
- gradient[i] = gradVal + (lambda * nodeVal);
312
+ gradient[i] = gradVal + lambda * nodeVal;
305
313
  }
306
314
  }
307
315
  }
@@ -317,7 +325,7 @@ function updateEmbeddings(
317
325
  const embVal = embedding[i];
318
326
  const gradVal = gradient[i];
319
327
  if (embVal !== undefined && gradVal !== undefined) {
320
- embedding[i] = embVal - (learningRate * gradVal);
328
+ embedding[i] = embVal - learningRate * gradVal;
321
329
  }
322
330
  }
323
331
  }
@@ -325,6 +333,10 @@ function updateEmbeddings(
325
333
 
326
334
  /**
327
335
  * Update cluster centers based on current assignments
336
+ * @param embeddings - Map of node IDs to embedding vectors
337
+ * @param clusters - Map of node IDs to cluster assignments
338
+ * @param clusterCenters - Array of cluster center vectors to update
339
+ * @param numClusters - Number of clusters
328
340
  */
329
341
  function updateClusterCenters(
330
342
  embeddings: Map<NodeId, number[]>,
@@ -333,8 +345,9 @@ function updateClusterCenters(
333
345
  numClusters: number,
334
346
  ): void {
335
347
  const dimensions = clusterCenters[0]?.length ?? 0;
336
- const clusterSums: number[][] = Array.from({length: numClusters}, () =>
337
- new Array(dimensions).fill(0) as number[],
348
+ const clusterSums: number[][] = Array.from(
349
+ { length: numClusters },
350
+ () => new Array(dimensions).fill(0) as number[],
338
351
  );
339
352
  const clusterCounts = new Array<number>(numClusters).fill(0);
340
353
 
@@ -380,6 +393,12 @@ function updateClusterCenters(
380
393
 
381
394
  /**
382
395
  * Calculate the total loss function
396
+ * @param graph - The input graph
397
+ * @param embeddings - Map of node IDs to embedding vectors
398
+ * @param clusters - Map of node IDs to cluster assignments
399
+ * @param clusterCenters - Array of cluster center vectors
400
+ * @param lambda - Regularization parameter
401
+ * @returns The total loss value
383
402
  */
384
403
  function calculateLoss(
385
404
  graph: Graph,
@@ -433,37 +452,5 @@ function calculateLoss(
433
452
  }
434
453
  }
435
454
 
436
- return clusteringLoss + (lambda * reconstructionLoss) + (lambda * regularizationLoss);
437
- }
438
-
439
- /**
440
- * Calculate Euclidean distance between two vectors
441
- */
442
- function euclideanDistance(a: number[], b: number[]): number {
443
- let sum = 0;
444
- for (let i = 0; i < a.length; i++) {
445
- const aVal = a[i];
446
- const bVal = b[i];
447
- if (aVal !== undefined && bVal !== undefined) {
448
- const diff = aVal - bVal;
449
- sum += diff * diff;
450
- }
451
- }
452
- return Math.sqrt(sum);
453
- }
454
-
455
- /**
456
- * Simple seeded random number generator for reproducibility
457
- */
458
- function seedRandom(seed: number): () => number {
459
- const m = 0x80000000; // 2**31
460
- const a = 1103515245;
461
- const c = 12345;
462
-
463
- seed = seed % m;
464
-
465
- return function() {
466
- seed = ((a * seed) + c) % m;
467
- return seed / (m - 1);
468
- };
455
+ return clusteringLoss + lambda * reconstructionLoss + lambda * regularizationLoss;
469
456
  }