@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
@@ -9,6 +9,10 @@
9
9
  * detect community structures in large-scale networks"
10
10
  */
11
11
 
12
+ import type { Graph } from "../../core/graph.js";
13
+ import { graphToMap } from "../../utils/graph-converters.js";
14
+ import { SeededRandom, shuffle } from "../../utils/math-utilities.js";
15
+
12
16
  export interface LabelPropagationOptions {
13
17
  maxIterations?: number;
14
18
  randomSeed?: number;
@@ -21,24 +25,16 @@ export interface LabelPropagationResult {
21
25
  }
22
26
 
23
27
  /**
24
- * Label Propagation Algorithm
25
- * Each node adopts the most frequent label among its neighbors
26
- *
27
- * @param graph - Undirected graph (can be weighted)
28
- * @param options - Algorithm options
29
- * @returns Community assignments
30
- *
31
- * Time Complexity: O(m) per iteration, typically O(km) for k iterations
32
- * Space Complexity: O(n)
28
+ * Internal implementation of Label Propagation Algorithm
29
+ * @param graph - Map representation of the graph (node to neighbors with weights)
30
+ * @param options - Algorithm configuration options
31
+ * @returns Community assignments, iteration count, and convergence status
33
32
  */
34
- export function labelPropagation(
33
+ function labelPropagationImpl(
35
34
  graph: Map<string, Map<string, number>>,
36
35
  options: LabelPropagationOptions = {},
37
36
  ): LabelPropagationResult {
38
- const {
39
- maxIterations = 100,
40
- randomSeed = 42,
41
- } = options;
37
+ const { maxIterations = 100, randomSeed = 42 } = options;
42
38
 
43
39
  if (graph.size === 0) {
44
40
  return {
@@ -49,11 +45,7 @@ export function labelPropagation(
49
45
  }
50
46
 
51
47
  // Initialize random number generator
52
- let seed = randomSeed;
53
- const random = (): number => {
54
- seed = ((seed * 1664525) + 1013904223) % 2147483647;
55
- return seed / 2147483647;
56
- };
48
+ const random = SeededRandom.createGenerator(randomSeed);
57
49
 
58
50
  // Initialize labels - each node gets its own label
59
51
  const labels = new Map<string, number>();
@@ -69,7 +61,7 @@ export function labelPropagation(
69
61
  converged = true;
70
62
 
71
63
  // Create random order for node updates
72
- const nodeOrder = [... nodes];
64
+ const nodeOrder = [...nodes];
73
65
  shuffle(nodeOrder, random);
74
66
 
75
67
  // Update each node's label
@@ -157,16 +149,17 @@ export function labelPropagation(
157
149
  }
158
150
 
159
151
  /**
160
- * Asynchronous Label Propagation
152
+ * Internal implementation of Asynchronous Label Propagation
161
153
  * Updates all nodes simultaneously (can lead to oscillations)
154
+ * @param graph - Map representation of the graph (node to neighbors with weights)
155
+ * @param options - Algorithm configuration options
156
+ * @returns Community assignments, iteration count, and convergence status
162
157
  */
163
- export function labelPropagationAsync(
158
+ function labelPropagationAsyncImpl(
164
159
  graph: Map<string, Map<string, number>>,
165
160
  options: LabelPropagationOptions = {},
166
161
  ): LabelPropagationResult {
167
- const {
168
- maxIterations = 100,
169
- } = options;
162
+ const { maxIterations = 100 } = options;
170
163
 
171
164
  if (graph.size === 0) {
172
165
  return {
@@ -267,30 +260,27 @@ export function labelPropagationAsync(
267
260
  }
268
261
 
269
262
  /**
270
- * Semi-supervised Label Propagation
263
+ * Internal implementation of Semi-supervised Label Propagation
271
264
  * Some nodes have fixed labels that don't change
265
+ * @param graph - Map representation of the graph (node to neighbors with weights)
266
+ * @param seedLabels - Map of node IDs to their fixed community labels
267
+ * @param options - Algorithm configuration options
268
+ * @returns Community assignments, iteration count, and convergence status
272
269
  */
273
- export function labelPropagationSemiSupervised(
270
+ function labelPropagationSemiSupervisedImpl(
274
271
  graph: Map<string, Map<string, number>>,
275
272
  seedLabels: Map<string, number>,
276
273
  options: LabelPropagationOptions = {},
277
274
  ): LabelPropagationResult {
278
- const {
279
- maxIterations = 100,
280
- randomSeed = 42,
281
- } = options;
275
+ const { maxIterations = 100, randomSeed = 42 } = options;
282
276
 
283
277
  // Initialize random number generator
284
- let seed = randomSeed;
285
- const random = (): number => {
286
- seed = ((seed * 1664525) + 1013904223) % 2147483647;
287
- return seed / 2147483647;
288
- };
278
+ const random = SeededRandom.createGenerator(randomSeed);
289
279
 
290
280
  // Initialize labels
291
281
  const labels = new Map<string, number>();
292
282
  const nodes = Array.from(graph.keys());
293
- let labelCounter = Math.max(... Array.from(seedLabels.values())) + 1;
283
+ let labelCounter = Math.max(...Array.from(seedLabels.values())) + 1;
294
284
 
295
285
  for (const node of nodes) {
296
286
  if (seedLabels.has(node)) {
@@ -376,17 +366,48 @@ export function labelPropagationSemiSupervised(
376
366
  }
377
367
 
378
368
  /**
379
- * Fisher-Yates shuffle
369
+ * Label Propagation Algorithm
370
+ * Each node adopts the most frequent label among its neighbors
371
+ * @param graph - Undirected graph (can be weighted)
372
+ * @param options - Algorithm options
373
+ * @returns Community assignments
374
+ *
375
+ * Time Complexity: O(m) per iteration, typically O(km) for k iterations
376
+ * Space Complexity: O(n)
377
+ */
378
+ export function labelPropagation(graph: Graph, options: LabelPropagationOptions = {}): LabelPropagationResult {
379
+ // Convert Graph to Map representation
380
+ const graphMap = graphToMap(graph);
381
+ return labelPropagationImpl(graphMap, options);
382
+ }
383
+
384
+ /**
385
+ * Asynchronous Label Propagation
386
+ * Updates all nodes simultaneously (can lead to oscillations)
387
+ * @param graph - Undirected graph (can be weighted)
388
+ * @param options - Algorithm options
389
+ * @returns Community assignments
380
390
  */
381
- function shuffle(array: unknown[], random: () => number): void {
382
- for (let i = array.length - 1; i > 0; i--) {
383
- const j = Math.floor(random() * (i + 1));
384
- const temp = array[i];
385
- const swapItem = array[j];
386
- if (temp !== undefined && swapItem !== undefined) {
387
- array[i] = swapItem;
388
- array[j] = temp;
389
- }
390
- }
391
+ export function labelPropagationAsync(graph: Graph, options: LabelPropagationOptions = {}): LabelPropagationResult {
392
+ // Convert Graph to Map representation
393
+ const graphMap = graphToMap(graph);
394
+ return labelPropagationAsyncImpl(graphMap, options);
391
395
  }
392
396
 
397
+ /**
398
+ * Semi-supervised Label Propagation
399
+ * Some nodes have fixed labels that don't change
400
+ * @param graph - Undirected graph (can be weighted)
401
+ * @param seedLabels - Initial fixed labels for some nodes
402
+ * @param options - Algorithm options
403
+ * @returns Community assignments
404
+ */
405
+ export function labelPropagationSemiSupervised(
406
+ graph: Graph,
407
+ seedLabels: Map<string, number>,
408
+ options: LabelPropagationOptions = {},
409
+ ): LabelPropagationResult {
410
+ // Convert Graph to Map representation
411
+ const graphMap = graphToMap(graph);
412
+ return labelPropagationSemiSupervisedImpl(graphMap, seedLabels, options);
413
+ }
@@ -8,7 +8,9 @@
8
8
  * "From Louvain to Leiden: guaranteeing well-connected communities"
9
9
  */
10
10
 
11
- // Louvain import removed - not used in this implementation
11
+ import type { Graph } from "../../core/graph.js";
12
+ import { graphToMap } from "../../utils/graph-converters.js";
13
+ import { SeededRandom, shuffle } from "../../utils/math-utilities.js";
12
14
 
13
15
  export interface LeidenOptions {
14
16
  resolution?: number;
@@ -24,29 +26,17 @@ export interface LeidenResult {
24
26
  }
25
27
 
26
28
  /**
27
- * Leiden algorithm for community detection
29
+ * Internal implementation of Leiden algorithm for community detection
28
30
  * Improves upon Louvain by ensuring well-connected communities
29
- *
30
- * @param graph - Undirected weighted graph
31
- * @param options - Algorithm options
32
- * @returns Community assignments and modularity
33
- *
34
- * Time Complexity: O(m) per iteration, typically O(m log m) total
35
- * Space Complexity: O(n + m)
31
+ * @param inputGraph - Map representation of the graph (node to neighbors with weights)
32
+ * @param options - Algorithm configuration options
33
+ * @returns Community assignments, modularity score, and iteration count
36
34
  */
37
- export function leiden(
38
- graph: Map<string, Map<string, number>>,
39
- options: LeidenOptions = {},
40
- ): LeidenResult {
41
- const {
42
- resolution = 1.0,
43
- randomSeed = 42,
44
- maxIterations = 100,
45
- threshold = 1e-7,
46
- } = options;
35
+ function leidenImpl(inputGraph: Map<string, Map<string, number>>, options: LeidenOptions = {}): LeidenResult {
36
+ const { resolution = 1.0, randomSeed = 42, maxIterations = 100, threshold = 1e-7 } = options;
47
37
 
48
38
  // Handle empty graph
49
- if (graph.size === 0) {
39
+ if (inputGraph.size === 0) {
50
40
  return {
51
41
  communities: new Map(),
52
42
  modularity: 0,
@@ -54,18 +44,17 @@ export function leiden(
54
44
  };
55
45
  }
56
46
 
47
+ // Use a mutable variable for the current graph state
48
+ let currentGraph = inputGraph;
49
+
57
50
  // Initialize random number generator
58
- let seed = randomSeed;
59
- const random = (): number => {
60
- seed = ((seed * 1664525) + 1013904223) % 2147483647;
61
- return seed / 2147483647;
62
- };
51
+ const random = SeededRandom.createGenerator(randomSeed);
63
52
 
64
53
  // Calculate total weight
65
54
  let totalWeight = 0;
66
55
  const degrees = new Map<string, number>();
67
56
 
68
- for (const [node, neighbors] of graph) {
57
+ for (const [node, neighbors] of currentGraph) {
69
58
  let degree = 0;
70
59
  for (const weight of neighbors.values()) {
71
60
  degree += weight;
@@ -77,10 +66,10 @@ export function leiden(
77
66
 
78
67
  // Initialize communities - each node in its own community
79
68
  const communities = new Map<string, number>();
80
- const nodes = Array.from(graph.keys());
69
+ const nodes = Array.from(currentGraph.keys());
81
70
  nodes.forEach((node, i) => communities.set(node, i));
82
71
 
83
- let modularity = calculateModularity(graph, communities, degrees, totalWeight, resolution);
72
+ let modularity = calculateModularity(currentGraph, communities, degrees, totalWeight, resolution);
84
73
  let bestModularity = modularity;
85
74
  let bestCommunities = new Map(communities);
86
75
  let iterations = 0;
@@ -91,7 +80,7 @@ export function leiden(
91
80
  let improved = false;
92
81
 
93
82
  // Phase 1: Local moving of nodes (fast)
94
- const nodeOrder = [... nodes];
83
+ const nodeOrder = [...nodes];
95
84
  shuffle(nodeOrder, random);
96
85
 
97
86
  for (const node of nodeOrder) {
@@ -100,7 +89,7 @@ export function leiden(
100
89
  continue;
101
90
  }
102
91
 
103
- const neighborCommunities = getNeighborCommunities(node, graph, communities);
92
+ const neighborCommunities = getNeighborCommunities(node, currentGraph, communities);
104
93
 
105
94
  let bestCommunity = currentCommunity;
106
95
  let bestGain = 0;
@@ -112,7 +101,13 @@ export function leiden(
112
101
  }
113
102
 
114
103
  const gain = calculateModularityGain(
115
- node, community, graph, communities, degrees, totalWeight, resolution,
104
+ node,
105
+ community,
106
+ currentGraph,
107
+ communities,
108
+ degrees,
109
+ totalWeight,
110
+ resolution,
116
111
  );
117
112
 
118
113
  if (gain > bestGain) {
@@ -131,12 +126,10 @@ export function leiden(
131
126
 
132
127
  // Phase 2: Refinement (Leiden improvement over Louvain)
133
128
  // Create aggregate network based on current partition
134
- createAggregateNetwork(graph, communities);
129
+ createAggregateNetwork(currentGraph, communities);
135
130
 
136
131
  // Refine partition using aggregate network
137
- const subsetPartition = refinePartition(
138
- graph, communities,
139
- );
132
+ const subsetPartition = refinePartition(currentGraph, communities);
140
133
 
141
134
  // Apply refined partition
142
135
  for (const [node, newCommunity] of subsetPartition) {
@@ -144,7 +137,7 @@ export function leiden(
144
137
  }
145
138
 
146
139
  // Recalculate modularity
147
- modularity = calculateModularity(graph, communities, degrees, totalWeight, resolution);
140
+ modularity = calculateModularity(currentGraph, communities, degrees, totalWeight, resolution);
148
141
 
149
142
  // Check if we've improved
150
143
  if (modularity > bestModularity + threshold) {
@@ -158,17 +151,17 @@ export function leiden(
158
151
  }
159
152
 
160
153
  // Phase 3: Aggregate network (create super-nodes)
161
- const aggregated = aggregateCommunities(graph, communities);
162
- if (aggregated.graph.size === graph.size) {
154
+ const aggregated = aggregateCommunities(currentGraph, communities);
155
+ if (aggregated.graph.size === currentGraph.size) {
163
156
  break;
164
157
  } // No aggregation possible
165
158
 
166
159
  // Continue with aggregated network
167
- const {graph: newGraph} = aggregated;
168
- graph = newGraph;
160
+ const { graph: aggregatedGraph } = aggregated;
161
+ currentGraph = aggregatedGraph;
169
162
  communities.clear();
170
163
  let communityId = 0;
171
- for (const node of graph.keys()) {
164
+ for (const node of currentGraph.keys()) {
172
165
  communities.set(node, communityId++);
173
166
  }
174
167
  }
@@ -201,6 +194,12 @@ export function leiden(
201
194
 
202
195
  /**
203
196
  * Calculate modularity of a partition
197
+ * @param graph - Map representation of the graph
198
+ * @param communities - Map of node IDs to community IDs
199
+ * @param degrees - Map of node IDs to their weighted degrees
200
+ * @param totalWeight - Total weight of all edges in the graph
201
+ * @param resolution - Resolution parameter for modularity calculation
202
+ * @returns The modularity score of the partition
204
203
  */
205
204
  function calculateModularity(
206
205
  graph: Map<string, Map<string, number>>,
@@ -242,11 +241,11 @@ function calculateModularity(
242
241
  }
243
242
 
244
243
  // Normalize and apply resolution
245
- modularity /= (2 * totalWeight);
244
+ modularity /= 2 * totalWeight;
246
245
 
247
246
  // Subtract expected edges
248
247
  for (const weight of communityWeights.values()) {
249
- modularity -= resolution * ((weight / (2 * totalWeight)) ** 2);
248
+ modularity -= resolution * (weight / (2 * totalWeight)) ** 2;
250
249
  }
251
250
 
252
251
  return modularity;
@@ -254,6 +253,10 @@ function calculateModularity(
254
253
 
255
254
  /**
256
255
  * Get communities of neighbors
256
+ * @param node - The node ID to get neighbor communities for
257
+ * @param graph - Map representation of the graph
258
+ * @param communities - Map of node IDs to community IDs
259
+ * @returns Map of community IDs to total edge weight connecting to that community
257
260
  */
258
261
  function getNeighborCommunities(
259
262
  node: string,
@@ -277,6 +280,14 @@ function getNeighborCommunities(
277
280
 
278
281
  /**
279
282
  * Calculate modularity gain from moving a node to a community
283
+ * @param node - The node ID to move
284
+ * @param targetCommunity - The target community ID
285
+ * @param graph - Map representation of the graph
286
+ * @param communities - Map of node IDs to community IDs
287
+ * @param degrees - Map of node IDs to their weighted degrees
288
+ * @param totalWeight - Total weight of all edges in the graph
289
+ * @param resolution - Resolution parameter for modularity calculation
290
+ * @returns The modularity gain from moving the node to the target community
280
291
  */
281
292
  function calculateModularityGain(
282
293
  node: string,
@@ -333,22 +344,26 @@ function calculateModularityGain(
333
344
 
334
345
  // Modularity gain calculation
335
346
  const m2 = 2 * totalWeight;
336
- const gain = ((weightToTarget - weightToCurrent) / totalWeight) -
337
- (resolution * nodeDegree * (targetDegree - currentDegree) / (m2 * m2));
347
+ const gain =
348
+ (weightToTarget - weightToCurrent) / totalWeight -
349
+ (resolution * nodeDegree * (targetDegree - currentDegree)) / (m2 * m2);
338
350
 
339
351
  return gain;
340
352
  }
341
353
 
342
354
  /**
343
355
  * Create aggregate network where each community becomes a super-node
356
+ * @param graph - Map representation of the graph
357
+ * @param communities - Map of node IDs to community IDs
358
+ * @returns Object with aggregate graph and node-to-community mapping
344
359
  */
345
360
  function createAggregateNetwork(
346
361
  graph: Map<string, Map<string, number>>,
347
362
  communities: Map<string, number>,
348
363
  ): {
349
- aggregateGraph: Map<number, Map<number, number>>;
350
- nodeMapping: Map<string, number>;
351
- } {
364
+ aggregateGraph: Map<number, Map<number, number>>;
365
+ nodeMapping: Map<string, number>;
366
+ } {
352
367
  const aggregateGraph = new Map<number, Map<number, number>>();
353
368
  const nodeMapping = new Map<string, number>();
354
369
 
@@ -381,12 +396,15 @@ function createAggregateNetwork(
381
396
  }
382
397
  }
383
398
 
384
- return {aggregateGraph, nodeMapping};
399
+ return { aggregateGraph, nodeMapping };
385
400
  }
386
401
 
387
402
  /**
388
403
  * Refine partition (Leiden-specific improvement)
389
404
  * Ensures well-connected communities by considering subsets
405
+ * @param originalGraph - Map representation of the original graph
406
+ * @param communities - Map of node IDs to community IDs
407
+ * @returns Refined community assignments with well-connected communities
390
408
  */
391
409
  function refinePartition(
392
410
  originalGraph: Map<string, Map<string, number>>,
@@ -454,6 +472,8 @@ function refinePartition(
454
472
 
455
473
  /**
456
474
  * Find connected components in undirected graph
475
+ * @param graph - Map representation of the graph (node to set of neighbors)
476
+ * @returns Array of connected components (each is a set of node IDs)
457
477
  */
458
478
  function findConnectedComponents(graph: Map<string, Set<string>>): Set<string>[] {
459
479
  const visited = new Set<string>();
@@ -492,14 +512,17 @@ function findConnectedComponents(graph: Map<string, Set<string>>): Set<string>[]
492
512
 
493
513
  /**
494
514
  * Aggregate communities into super-nodes
515
+ * @param graph - Map representation of the graph
516
+ * @param communities - Map of node IDs to community IDs
517
+ * @returns Object with aggregated graph and node-to-supernode mapping
495
518
  */
496
519
  function aggregateCommunities(
497
520
  graph: Map<string, Map<string, number>>,
498
521
  communities: Map<string, number>,
499
522
  ): {
500
- graph: Map<string, Map<string, number>>;
501
- mapping: Map<string, string>;
502
- } {
523
+ graph: Map<string, Map<string, number>>;
524
+ mapping: Map<string, string>;
525
+ } {
503
526
  const aggregated = new Map<string, Map<string, number>>();
504
527
  const mapping = new Map<string, string>();
505
528
 
@@ -552,21 +575,21 @@ function aggregateCommunities(
552
575
  }
553
576
  }
554
577
 
555
- return {graph: aggregated, mapping};
578
+ return { graph: aggregated, mapping };
556
579
  }
557
580
 
558
581
  /**
559
- * Fisher-Yates shuffle
582
+ * Leiden algorithm for community detection
583
+ * Improves upon Louvain by ensuring well-connected communities
584
+ * @param graph - Undirected weighted graph - accepts Graph class or Map representation
585
+ * @param options - Algorithm options
586
+ * @returns Community assignments and modularity
587
+ *
588
+ * Time Complexity: O(m) per iteration, typically O(m log m) total
589
+ * Space Complexity: O(n + m)
560
590
  */
561
- function shuffle(array: unknown[], random: () => number): void {
562
- for (let i = array.length - 1; i > 0; i--) {
563
- const j = Math.floor(random() * (i + 1));
564
- const temp = array[i];
565
- const swapItem = array[j];
566
- if (temp !== undefined && swapItem !== undefined) {
567
- array[i] = swapItem;
568
- array[j] = temp;
569
- }
570
- }
591
+ export function leiden(graph: Graph, options: LeidenOptions = {}): LeidenResult {
592
+ // Convert Graph to Map representation
593
+ const graphMap = graphToMap(graph);
594
+ return leidenImpl(graphMap, options);
571
595
  }
572
-