@graphty/algorithms 1.3.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/README.md +368 -422
  2. package/dist/algorithms.js +567 -264
  3. package/dist/algorithms.js.map +1 -1
  4. package/dist/src/algorithms/centrality/betweenness.d.ts +10 -0
  5. package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
  6. package/dist/src/algorithms/centrality/betweenness.js +27 -6
  7. package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
  8. package/dist/src/algorithms/centrality/closeness.d.ts +11 -2
  9. package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -1
  10. package/dist/src/algorithms/centrality/closeness.js +17 -3
  11. package/dist/src/algorithms/centrality/closeness.js.map +1 -1
  12. package/dist/src/algorithms/centrality/degree.d.ts +7 -0
  13. package/dist/src/algorithms/centrality/degree.d.ts.map +1 -1
  14. package/dist/src/algorithms/centrality/degree.js +9 -6
  15. package/dist/src/algorithms/centrality/degree.js.map +1 -1
  16. package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts +21 -3
  17. package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts.map +1 -1
  18. package/dist/src/algorithms/centrality/delta-pagerank-simple.js +25 -7
  19. package/dist/src/algorithms/centrality/delta-pagerank-simple.js.map +1 -1
  20. package/dist/src/algorithms/centrality/delta-pagerank.d.ts +28 -2
  21. package/dist/src/algorithms/centrality/delta-pagerank.d.ts.map +1 -1
  22. package/dist/src/algorithms/centrality/delta-pagerank.js +30 -4
  23. package/dist/src/algorithms/centrality/delta-pagerank.js.map +1 -1
  24. package/dist/src/algorithms/centrality/eigenvector.d.ts +10 -3
  25. package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -1
  26. package/dist/src/algorithms/centrality/eigenvector.js +11 -4
  27. package/dist/src/algorithms/centrality/eigenvector.js.map +1 -1
  28. package/dist/src/algorithms/centrality/hits.d.ts +10 -3
  29. package/dist/src/algorithms/centrality/hits.d.ts.map +1 -1
  30. package/dist/src/algorithms/centrality/hits.js +11 -4
  31. package/dist/src/algorithms/centrality/hits.js.map +1 -1
  32. package/dist/src/algorithms/centrality/index.d.ts +1 -1
  33. package/dist/src/algorithms/centrality/index.d.ts.map +1 -1
  34. package/dist/src/algorithms/centrality/index.js +1 -1
  35. package/dist/src/algorithms/centrality/index.js.map +1 -1
  36. package/dist/src/algorithms/centrality/katz.d.ts +10 -3
  37. package/dist/src/algorithms/centrality/katz.d.ts.map +1 -1
  38. package/dist/src/algorithms/centrality/katz.js +13 -8
  39. package/dist/src/algorithms/centrality/katz.js.map +1 -1
  40. package/dist/src/algorithms/centrality/pagerank.d.ts +14 -0
  41. package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -1
  42. package/dist/src/algorithms/centrality/pagerank.js +16 -1
  43. package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
  44. package/dist/src/algorithms/community/girvan-newman.d.ts +2 -3
  45. package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -1
  46. package/dist/src/algorithms/community/girvan-newman.js +21 -4
  47. package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
  48. package/dist/src/algorithms/community/index.d.ts.map +1 -1
  49. package/dist/src/algorithms/community/index.js.map +1 -1
  50. package/dist/src/algorithms/community/label-propagation.d.ts +0 -3
  51. package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -1
  52. package/dist/src/algorithms/community/label-propagation.js +13 -6
  53. package/dist/src/algorithms/community/label-propagation.js.map +1 -1
  54. package/dist/src/algorithms/community/leiden.d.ts +0 -1
  55. package/dist/src/algorithms/community/leiden.d.ts.map +1 -1
  56. package/dist/src/algorithms/community/leiden.js +37 -6
  57. package/dist/src/algorithms/community/leiden.js.map +1 -1
  58. package/dist/src/algorithms/community/louvain-optimized.d.ts +37 -0
  59. package/dist/src/algorithms/community/louvain-optimized.d.ts.map +1 -1
  60. package/dist/src/algorithms/community/louvain-optimized.js +42 -7
  61. package/dist/src/algorithms/community/louvain-optimized.js.map +1 -1
  62. package/dist/src/algorithms/community/louvain.d.ts +2 -3
  63. package/dist/src/algorithms/community/louvain.d.ts.map +1 -1
  64. package/dist/src/algorithms/community/louvain.js +19 -6
  65. package/dist/src/algorithms/community/louvain.js.map +1 -1
  66. package/dist/src/algorithms/community/modularity-utils.d.ts +0 -4
  67. package/dist/src/algorithms/community/modularity-utils.d.ts.map +1 -1
  68. package/dist/src/algorithms/community/modularity-utils.js +1 -5
  69. package/dist/src/algorithms/community/modularity-utils.js.map +1 -1
  70. package/dist/src/algorithms/components/connected.d.ts +23 -0
  71. package/dist/src/algorithms/components/connected.d.ts.map +1 -1
  72. package/dist/src/algorithms/components/connected.js +29 -3
  73. package/dist/src/algorithms/components/connected.js.map +1 -1
  74. package/dist/src/algorithms/matching/bipartite.d.ts +10 -0
  75. package/dist/src/algorithms/matching/bipartite.d.ts.map +1 -1
  76. package/dist/src/algorithms/matching/bipartite.js +10 -0
  77. package/dist/src/algorithms/matching/bipartite.js.map +1 -1
  78. package/dist/src/algorithms/matching/index.d.ts.map +1 -1
  79. package/dist/src/algorithms/matching/index.js.map +1 -1
  80. package/dist/src/algorithms/matching/isomorphism.d.ts +8 -0
  81. package/dist/src/algorithms/matching/isomorphism.d.ts.map +1 -1
  82. package/dist/src/algorithms/matching/isomorphism.js +36 -2
  83. package/dist/src/algorithms/matching/isomorphism.js.map +1 -1
  84. package/dist/src/algorithms/mst/index.d.ts.map +1 -1
  85. package/dist/src/algorithms/mst/index.js.map +1 -1
  86. package/dist/src/algorithms/mst/kruskal.d.ts +14 -0
  87. package/dist/src/algorithms/mst/kruskal.d.ts.map +1 -1
  88. package/dist/src/algorithms/mst/kruskal.js +17 -3
  89. package/dist/src/algorithms/mst/kruskal.js.map +1 -1
  90. package/dist/src/algorithms/mst/prim.d.ts +9 -0
  91. package/dist/src/algorithms/mst/prim.d.ts.map +1 -1
  92. package/dist/src/algorithms/mst/prim.js +9 -0
  93. package/dist/src/algorithms/mst/prim.js.map +1 -1
  94. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts +10 -0
  95. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -1
  96. package/dist/src/algorithms/shortest-path/bellman-ford.js +10 -0
  97. package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
  98. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts +12 -5
  99. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts.map +1 -1
  100. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js +19 -17
  101. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js.map +1 -1
  102. package/dist/src/algorithms/shortest-path/dijkstra.d.ts +15 -0
  103. package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -1
  104. package/dist/src/algorithms/shortest-path/dijkstra.js +15 -0
  105. package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
  106. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts +17 -0
  107. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts.map +1 -1
  108. package/dist/src/algorithms/shortest-path/floyd-warshall.js +17 -0
  109. package/dist/src/algorithms/shortest-path/floyd-warshall.js.map +1 -1
  110. package/dist/src/algorithms/shortest-path/index.d.ts.map +1 -1
  111. package/dist/src/algorithms/shortest-path/index.js.map +1 -1
  112. package/dist/src/algorithms/traversal/bfs-unified.d.ts +13 -0
  113. package/dist/src/algorithms/traversal/bfs-unified.d.ts.map +1 -1
  114. package/dist/src/algorithms/traversal/bfs-unified.js +37 -0
  115. package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -1
  116. package/dist/src/algorithms/traversal/bfs-variants.d.ts +23 -0
  117. package/dist/src/algorithms/traversal/bfs-variants.d.ts.map +1 -1
  118. package/dist/src/algorithms/traversal/bfs-variants.js +34 -0
  119. package/dist/src/algorithms/traversal/bfs-variants.js.map +1 -1
  120. package/dist/src/algorithms/traversal/bfs.d.ts +1 -1
  121. package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -1
  122. package/dist/src/algorithms/traversal/bfs.js +1 -1
  123. package/dist/src/algorithms/traversal/bfs.js.map +1 -1
  124. package/dist/src/algorithms/traversal/dfs.d.ts +10 -0
  125. package/dist/src/algorithms/traversal/dfs.d.ts.map +1 -1
  126. package/dist/src/algorithms/traversal/dfs.js +48 -0
  127. package/dist/src/algorithms/traversal/dfs.js.map +1 -1
  128. package/dist/src/algorithms/traversal/index.d.ts.map +1 -1
  129. package/dist/src/algorithms/traversal/index.js.map +1 -1
  130. package/dist/src/benchmark-all-algorithms.d.ts +2 -0
  131. package/dist/src/benchmark-all-algorithms.d.ts.map +1 -1
  132. package/dist/src/benchmark-all-algorithms.js +32 -3
  133. package/dist/src/benchmark-all-algorithms.js.map +1 -1
  134. package/dist/src/clustering/hierarchical.d.ts +8 -1
  135. package/dist/src/clustering/hierarchical.d.ts.map +1 -1
  136. package/dist/src/clustering/hierarchical.js +22 -6
  137. package/dist/src/clustering/hierarchical.js.map +1 -1
  138. package/dist/src/clustering/index.d.ts.map +1 -1
  139. package/dist/src/clustering/index.js.map +1 -1
  140. package/dist/src/clustering/k-core.d.ts +2 -5
  141. package/dist/src/clustering/k-core.d.ts.map +1 -1
  142. package/dist/src/clustering/k-core.js +14 -12
  143. package/dist/src/clustering/k-core.js.map +1 -1
  144. package/dist/src/clustering/mcl.d.ts +6 -0
  145. package/dist/src/clustering/mcl.d.ts.map +1 -1
  146. package/dist/src/clustering/mcl.js +34 -3
  147. package/dist/src/clustering/mcl.js.map +1 -1
  148. package/dist/src/clustering/spectral.d.ts +4 -1
  149. package/dist/src/clustering/spectral.d.ts.map +1 -1
  150. package/dist/src/clustering/spectral.js +61 -28
  151. package/dist/src/clustering/spectral.js.map +1 -1
  152. package/dist/src/core/graph.d.ts +45 -0
  153. package/dist/src/core/graph.d.ts.map +1 -1
  154. package/dist/src/core/graph.js +45 -1
  155. package/dist/src/core/graph.js.map +1 -1
  156. package/dist/src/data-structures/index.d.ts.map +1 -1
  157. package/dist/src/data-structures/index.js.map +1 -1
  158. package/dist/src/data-structures/priority-queue.d.ts +18 -1
  159. package/dist/src/data-structures/priority-queue.d.ts.map +1 -1
  160. package/dist/src/data-structures/priority-queue.js +26 -5
  161. package/dist/src/data-structures/priority-queue.js.map +1 -1
  162. package/dist/src/data-structures/union-find.d.ts +21 -0
  163. package/dist/src/data-structures/union-find.d.ts.map +1 -1
  164. package/dist/src/data-structures/union-find.js +21 -0
  165. package/dist/src/data-structures/union-find.js.map +1 -1
  166. package/dist/src/flow/ford-fulkerson.d.ts +4 -2
  167. package/dist/src/flow/ford-fulkerson.d.ts.map +1 -1
  168. package/dist/src/flow/ford-fulkerson.js +31 -2
  169. package/dist/src/flow/ford-fulkerson.js.map +1 -1
  170. package/dist/src/flow/min-cut.d.ts +0 -3
  171. package/dist/src/flow/min-cut.d.ts.map +1 -1
  172. package/dist/src/flow/min-cut.js +17 -4
  173. package/dist/src/flow/min-cut.js.map +1 -1
  174. package/dist/src/index.d.ts +2 -1
  175. package/dist/src/index.d.ts.map +1 -1
  176. package/dist/src/index.js +2 -1
  177. package/dist/src/index.js.map +1 -1
  178. package/dist/src/link-prediction/adamic-adar.d.ts +26 -0
  179. package/dist/src/link-prediction/adamic-adar.d.ts.map +1 -1
  180. package/dist/src/link-prediction/adamic-adar.js +36 -10
  181. package/dist/src/link-prediction/adamic-adar.js.map +1 -1
  182. package/dist/src/link-prediction/common-neighbors.d.ts +21 -0
  183. package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -1
  184. package/dist/src/link-prediction/common-neighbors.js +27 -6
  185. package/dist/src/link-prediction/common-neighbors.js.map +1 -1
  186. package/dist/src/link-prediction/index.d.ts.map +1 -1
  187. package/dist/src/optimized/bit-packed.d.ts +103 -53
  188. package/dist/src/optimized/bit-packed.d.ts.map +1 -1
  189. package/dist/src/optimized/bit-packed.js +104 -54
  190. package/dist/src/optimized/bit-packed.js.map +1 -1
  191. package/dist/src/optimized/csr-graph.d.ts +87 -24
  192. package/dist/src/optimized/csr-graph.d.ts.map +1 -1
  193. package/dist/src/optimized/csr-graph.js +87 -24
  194. package/dist/src/optimized/csr-graph.js.map +1 -1
  195. package/dist/src/optimized/direction-optimized-bfs.d.ts +37 -16
  196. package/dist/src/optimized/direction-optimized-bfs.d.ts.map +1 -1
  197. package/dist/src/optimized/direction-optimized-bfs.js +39 -20
  198. package/dist/src/optimized/direction-optimized-bfs.js.map +1 -1
  199. package/dist/src/optimized/graph-adapter.d.ts +58 -9
  200. package/dist/src/optimized/graph-adapter.d.ts.map +1 -1
  201. package/dist/src/optimized/graph-adapter.js +58 -10
  202. package/dist/src/optimized/graph-adapter.js.map +1 -1
  203. package/dist/src/optimized/index.d.ts +1 -1
  204. package/dist/src/optimized/index.d.ts.map +1 -1
  205. package/dist/src/optimized/index.js +3 -1
  206. package/dist/src/optimized/index.js.map +1 -1
  207. package/dist/src/pathfinding/astar.d.ts +25 -9
  208. package/dist/src/pathfinding/astar.d.ts.map +1 -1
  209. package/dist/src/pathfinding/astar.js +25 -10
  210. package/dist/src/pathfinding/astar.js.map +1 -1
  211. package/dist/src/pathfinding/utils.d.ts +15 -6
  212. package/dist/src/pathfinding/utils.d.ts.map +1 -1
  213. package/dist/src/pathfinding/utils.js +19 -7
  214. package/dist/src/pathfinding/utils.js.map +1 -1
  215. package/dist/src/research/grsbm.d.ts +0 -1
  216. package/dist/src/research/grsbm.d.ts.map +1 -1
  217. package/dist/src/research/grsbm.js +23 -10
  218. package/dist/src/research/grsbm.js.map +1 -1
  219. package/dist/src/research/index.d.ts.map +1 -1
  220. package/dist/src/research/index.js.map +1 -1
  221. package/dist/src/research/sync.d.ts +0 -1
  222. package/dist/src/research/sync.d.ts.map +1 -1
  223. package/dist/src/research/sync.js +29 -8
  224. package/dist/src/research/sync.js.map +1 -1
  225. package/dist/src/research/terahac.d.ts +0 -1
  226. package/dist/src/research/terahac.d.ts.map +1 -1
  227. package/dist/src/research/terahac.js +32 -4
  228. package/dist/src/research/terahac.js.map +1 -1
  229. package/dist/src/utils/graph-converters.d.ts +31 -0
  230. package/dist/src/utils/graph-converters.d.ts.map +1 -1
  231. package/dist/src/utils/graph-converters.js +31 -0
  232. package/dist/src/utils/graph-converters.js.map +1 -1
  233. package/dist/src/utils/graph-utilities.d.ts.map +1 -1
  234. package/dist/src/utils/graph-utilities.js.map +1 -1
  235. package/dist/src/utils/math-utilities.d.ts +11 -0
  236. package/dist/src/utils/math-utilities.d.ts.map +1 -1
  237. package/dist/src/utils/math-utilities.js +14 -5
  238. package/dist/src/utils/math-utilities.js.map +1 -1
  239. package/dist/src/utils/optimization-helpers.d.ts +9 -0
  240. package/dist/src/utils/optimization-helpers.d.ts.map +1 -1
  241. package/dist/src/utils/optimization-helpers.js +12 -0
  242. package/dist/src/utils/optimization-helpers.js.map +1 -1
  243. package/dist/src/utils/priorityQueue.d.ts +24 -0
  244. package/dist/src/utils/priorityQueue.d.ts.map +1 -1
  245. package/dist/src/utils/priorityQueue.js +34 -4
  246. package/dist/src/utils/priorityQueue.js.map +1 -1
  247. package/dist/tsconfig.tsbuildinfo +1 -0
  248. package/package.json +56 -65
  249. package/src/algorithms/centrality/betweenness.ts +34 -17
  250. package/src/algorithms/centrality/closeness.ts +34 -17
  251. package/src/algorithms/centrality/degree.ts +15 -19
  252. package/src/algorithms/centrality/delta-pagerank-simple.ts +36 -28
  253. package/src/algorithms/centrality/delta-pagerank.ts +34 -11
  254. package/src/algorithms/centrality/eigenvector.ts +14 -15
  255. package/src/algorithms/centrality/hits.ts +17 -17
  256. package/src/algorithms/centrality/index.ts +20 -15
  257. package/src/algorithms/centrality/katz.ts +17 -25
  258. package/src/algorithms/centrality/pagerank.ts +26 -17
  259. package/src/algorithms/community/girvan-newman.ts +39 -28
  260. package/src/algorithms/community/index.ts +6 -7
  261. package/src/algorithms/community/label-propagation.ts +20 -28
  262. package/src/algorithms/community/leiden.ts +61 -37
  263. package/src/algorithms/community/louvain-optimized.ts +49 -20
  264. package/src/algorithms/community/louvain.ts +35 -25
  265. package/src/algorithms/community/modularity-utils.ts +5 -17
  266. package/src/algorithms/components/connected.ts +40 -17
  267. package/src/algorithms/matching/bipartite.ts +17 -10
  268. package/src/algorithms/matching/index.ts +4 -4
  269. package/src/algorithms/matching/isomorphism.ts +53 -23
  270. package/src/algorithms/mst/index.ts +3 -4
  271. package/src/algorithms/mst/kruskal.ts +21 -6
  272. package/src/algorithms/mst/prim.ts +13 -4
  273. package/src/algorithms/shortest-path/bellman-ford.ts +16 -15
  274. package/src/algorithms/shortest-path/bidirectional-dijkstra.ts +29 -29
  275. package/src/algorithms/shortest-path/dijkstra.ts +23 -17
  276. package/src/algorithms/shortest-path/floyd-warshall.ts +21 -4
  277. package/src/algorithms/shortest-path/index.ts +5 -5
  278. package/src/algorithms/traversal/bfs-unified.ts +64 -60
  279. package/src/algorithms/traversal/bfs-variants.ts +61 -37
  280. package/src/algorithms/traversal/bfs.ts +1 -7
  281. package/src/algorithms/traversal/dfs.ts +61 -42
  282. package/src/algorithms/traversal/index.ts +3 -3
  283. package/src/benchmark-all-algorithms.ts +57 -25
  284. package/src/clustering/hierarchical.ts +40 -34
  285. package/src/clustering/index.ts +8 -8
  286. package/src/clustering/k-core.ts +26 -42
  287. package/src/clustering/mcl.ts +53 -23
  288. package/src/clustering/spectral.ts +91 -57
  289. package/src/core/graph.ts +54 -14
  290. package/src/data-structures/index.ts +2 -2
  291. package/src/data-structures/priority-queue.ts +36 -11
  292. package/src/data-structures/union-find.ts +22 -1
  293. package/src/flow/ford-fulkerson.ts +62 -35
  294. package/src/flow/min-cut.ts +43 -45
  295. package/src/index.ts +3 -2
  296. package/src/link-prediction/adamic-adar.ts +65 -51
  297. package/src/link-prediction/common-neighbors.ts +45 -36
  298. package/src/link-prediction/index.ts +1 -1
  299. package/src/optimized/bit-packed.ts +106 -56
  300. package/src/optimized/csr-graph.ts +93 -30
  301. package/src/optimized/direction-optimized-bfs.ts +44 -25
  302. package/src/optimized/graph-adapter.ts +64 -16
  303. package/src/optimized/index.ts +7 -9
  304. package/src/pathfinding/astar.ts +40 -25
  305. package/src/pathfinding/utils.ts +20 -13
  306. package/src/research/grsbm.ts +31 -25
  307. package/src/research/index.ts +4 -4
  308. package/src/research/sync.ts +40 -24
  309. package/src/research/terahac.ts +54 -20
  310. package/src/utils/graph-converters.ts +42 -14
  311. package/src/utils/graph-utilities.ts +11 -37
  312. package/src/utils/math-utilities.ts +17 -8
  313. package/src/utils/optimization-helpers.ts +27 -21
  314. package/src/utils/priorityQueue.ts +40 -6
@@ -1,6 +1,6 @@
1
- import {Graph} from "../../core/graph.js";
2
- import type {CommunityResult, ComponentResult, GirvanNewmanOptions, NodeId} from "../../types/index.js";
3
- import {connectedComponents} from "../components/connected.js";
1
+ import { Graph } from "../../core/graph.js";
2
+ import type { CommunityResult, ComponentResult, GirvanNewmanOptions, NodeId } from "../../types/index.js";
3
+ import { connectedComponents } from "../components/connected.js";
4
4
 
5
5
  /**
6
6
  * Girvan-Newman community detection algorithm
@@ -14,18 +14,14 @@ import {connectedComponents} from "../components/connected.js";
14
14
  *
15
15
  * References:
16
16
  * - Girvan, M., & Newman, M. E. J. (2002). Community structure in social
17
- * and biological networks. Proceedings of the National Academy of Sciences,
18
- * 99(12), 7821-7826.
19
- *
17
+ * and biological networks. Proceedings of the National Academy of Sciences,
18
+ * 99(12), 7821-7826.
20
19
  * @param graph - The input graph
21
20
  * @param options - Algorithm options
22
21
  * @returns Array of community detection results representing the dendrogram
23
22
  */
24
- export function girvanNewman(
25
- graph: Graph,
26
- options: GirvanNewmanOptions = {},
27
- ): CommunityResult[] {
28
- const {maxCommunities} = options;
23
+ export function girvanNewman(graph: Graph, options: GirvanNewmanOptions = {}): CommunityResult[] {
24
+ const { maxCommunities } = options;
29
25
  const minCommunitySize = options.minCommunitySize ?? 1;
30
26
  const maxIterations = options.maxIterations ?? 100; // Prevent infinite loops
31
27
 
@@ -50,20 +46,20 @@ export function girvanNewman(
50
46
  }
51
47
 
52
48
  // Find edges with maximum betweenness
53
- const maxBetweenness = Math.max(... edgeBetweenness.values());
54
- const edgesToRemove: {source: NodeId, target: NodeId}[] = [];
49
+ const maxBetweenness = Math.max(...edgeBetweenness.values());
50
+ const edgesToRemove: { source: NodeId; target: NodeId }[] = [];
55
51
 
56
52
  for (const [edgeKey, centrality] of edgeBetweenness) {
57
53
  if (Math.abs(centrality - maxBetweenness) < 1e-10) {
58
54
  const [source, target] = edgeKey.split("|");
59
55
  if (source && target) {
60
- edgesToRemove.push({source, target});
56
+ edgesToRemove.push({ source, target });
61
57
  }
62
58
  }
63
59
  }
64
60
 
65
61
  // Remove edges with highest betweenness
66
- for (const {source, target} of edgesToRemove) {
62
+ for (const { source, target } of edgesToRemove) {
67
63
  workingGraph.removeEdge(source, target);
68
64
  }
69
65
 
@@ -71,9 +67,7 @@ export function girvanNewman(
71
67
  components = getConnectedComponentsResult(workingGraph);
72
68
 
73
69
  // Filter communities by minimum size
74
- const validCommunities = components.components.filter(
75
- (community) => community.length >= minCommunitySize,
76
- );
70
+ const validCommunities = components.components.filter((community) => community.length >= minCommunitySize);
77
71
 
78
72
  // Calculate modularity for the new community structure
79
73
  const modularity = calculateModularity(graph, components.componentMap);
@@ -102,6 +96,8 @@ export function girvanNewman(
102
96
  *
103
97
  * Edge betweenness is the fraction of shortest paths that pass through the edge.
104
98
  * We adapt node betweenness centrality calculation to work with edges.
99
+ * @param graph - The input graph to analyze
100
+ * @returns Map of edge keys to their betweenness centrality values
105
101
  */
106
102
  function calculateEdgeBetweenness(graph: Graph): Map<string, number> {
107
103
  const edgeBetweenness = new Map<string, number>();
@@ -117,7 +113,7 @@ function calculateEdgeBetweenness(graph: Graph): Map<string, number> {
117
113
  const source = sourceNode.id;
118
114
 
119
115
  // Run BFS to find all shortest paths from source
120
- const {distances, predecessors, pathCounts} = findAllShortestPaths(graph, source);
116
+ const { distances, predecessors, pathCounts } = findAllShortestPaths(graph, source);
121
117
 
122
118
  // Calculate dependency for each node and accumulate edge betweenness
123
119
  const dependency = new Map<NodeId, number>();
@@ -191,8 +187,14 @@ function calculateEdgeBetweenness(graph: Graph): Map<string, number> {
191
187
 
192
188
  /**
193
189
  * Find all shortest paths from a source node using optimized BFS
190
+ * @param graph - The input graph to search
191
+ * @param source - The source node to compute shortest paths from
192
+ * @returns Object containing distances, predecessors, and path counts
194
193
  */
195
- function findAllShortestPaths(graph: Graph, source: NodeId): {
194
+ function findAllShortestPaths(
195
+ graph: Graph,
196
+ source: NodeId,
197
+ ): {
196
198
  distances: Map<NodeId, number>;
197
199
  predecessors: Map<NodeId, NodeId[]>;
198
200
  pathCounts: Map<NodeId, number>;
@@ -262,11 +264,14 @@ function findAllShortestPaths(graph: Graph, source: NodeId): {
262
264
  }
263
265
  }
264
266
 
265
- return {distances, predecessors, pathCounts};
267
+ return { distances, predecessors, pathCounts };
266
268
  }
267
269
 
268
270
  /**
269
271
  * Generate a consistent edge key for undirected graphs
272
+ * @param source - The source node ID
273
+ * @param target - The target node ID
274
+ * @returns A consistent string key for the edge (ordered alphabetically)
270
275
  */
271
276
  function getEdgeKey(source: NodeId, target: NodeId): string {
272
277
  // For undirected graphs, ensure consistent ordering
@@ -282,11 +287,11 @@ function getEdgeKey(source: NodeId, target: NodeId): string {
282
287
 
283
288
  /**
284
289
  * Calculate modularity for a given community structure - optimized version
290
+ * @param graph - The original graph
291
+ * @param communityMap - Map from node IDs to community indices
292
+ * @returns The modularity score of the partition
285
293
  */
286
- function calculateModularity(
287
- graph: Graph,
288
- communityMap: Map<NodeId, number>,
289
- ): number {
294
+ function calculateModularity(graph: Graph, communityMap: Map<NodeId, number>): number {
290
295
  const totalEdgeWeight = getTotalEdgeWeight(graph);
291
296
  if (totalEdgeWeight === 0) {
292
297
  return 0;
@@ -313,7 +318,7 @@ function calculateModularity(
313
318
  continue;
314
319
  }
315
320
 
316
- modularity += edgeWeight - ((degreeI * degreeJ) / (2 * totalEdgeWeight));
321
+ modularity += edgeWeight - (degreeI * degreeJ) / (2 * totalEdgeWeight);
317
322
  }
318
323
  }
319
324
 
@@ -322,6 +327,8 @@ function calculateModularity(
322
327
 
323
328
  /**
324
329
  * Calculate total edge weight in the graph
330
+ * @param graph - The input graph
331
+ * @returns Total sum of all edge weights
325
332
  */
326
333
  function getTotalEdgeWeight(graph: Graph): number {
327
334
  let totalWeight = 0;
@@ -335,6 +342,9 @@ function getTotalEdgeWeight(graph: Graph): number {
335
342
 
336
343
  /**
337
344
  * Get the total degree (sum of edge weights) for a node
345
+ * @param graph - The input graph
346
+ * @param nodeId - The node ID to compute degree for
347
+ * @returns The weighted degree of the node
338
348
  */
339
349
  function getNodeDegree(graph: Graph, nodeId: NodeId): number {
340
350
  let degree = 0;
@@ -349,6 +359,8 @@ function getNodeDegree(graph: Graph, nodeId: NodeId): number {
349
359
 
350
360
  /**
351
361
  * Convert connected components result to ComponentResult format
362
+ * @param graph - The input graph
363
+ * @returns Object containing components array and node-to-component map
352
364
  */
353
365
  function getConnectedComponentsResult(graph: Graph): ComponentResult {
354
366
  const components = connectedComponents(graph);
@@ -360,6 +372,5 @@ function getConnectedComponentsResult(graph: Graph): ComponentResult {
360
372
  });
361
373
  });
362
374
 
363
- return {components, componentMap};
375
+ return { components, componentMap };
364
376
  }
365
-
@@ -6,10 +6,9 @@
6
6
  * than with the rest of the network.
7
7
  */
8
8
 
9
- export {girvanNewman} from "./girvan-newman.js";
10
- export type {LabelPropagationOptions, LabelPropagationResult} from "./label-propagation.js";
11
- export {labelPropagation, labelPropagationAsync, labelPropagationSemiSupervised} from "./label-propagation.js";
12
- export type {LeidenOptions, LeidenResult} from "./leiden.js";
13
- export {leiden} from "./leiden.js";
14
- export {louvain} from "./louvain.js";
15
-
9
+ export { girvanNewman } from "./girvan-newman.js";
10
+ export type { LabelPropagationOptions, LabelPropagationResult } from "./label-propagation.js";
11
+ export { labelPropagation, labelPropagationAsync, labelPropagationSemiSupervised } from "./label-propagation.js";
12
+ export type { LeidenOptions, LeidenResult } from "./leiden.js";
13
+ export { leiden } from "./leiden.js";
14
+ export { louvain } from "./louvain.js";
@@ -9,9 +9,9 @@
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";
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
15
 
16
16
  export interface LabelPropagationOptions {
17
17
  maxIterations?: number;
@@ -26,15 +26,15 @@ export interface LabelPropagationResult {
26
26
 
27
27
  /**
28
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
29
32
  */
30
33
  function labelPropagationImpl(
31
34
  graph: Map<string, Map<string, number>>,
32
35
  options: LabelPropagationOptions = {},
33
36
  ): LabelPropagationResult {
34
- const {
35
- maxIterations = 100,
36
- randomSeed = 42,
37
- } = options;
37
+ const { maxIterations = 100, randomSeed = 42 } = options;
38
38
 
39
39
  if (graph.size === 0) {
40
40
  return {
@@ -61,7 +61,7 @@ function labelPropagationImpl(
61
61
  converged = true;
62
62
 
63
63
  // Create random order for node updates
64
- const nodeOrder = [... nodes];
64
+ const nodeOrder = [...nodes];
65
65
  shuffle(nodeOrder, random);
66
66
 
67
67
  // Update each node's label
@@ -151,14 +151,15 @@ function labelPropagationImpl(
151
151
  /**
152
152
  * Internal implementation of Asynchronous Label Propagation
153
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
154
157
  */
155
158
  function labelPropagationAsyncImpl(
156
159
  graph: Map<string, Map<string, number>>,
157
160
  options: LabelPropagationOptions = {},
158
161
  ): LabelPropagationResult {
159
- const {
160
- maxIterations = 100,
161
- } = options;
162
+ const { maxIterations = 100 } = options;
162
163
 
163
164
  if (graph.size === 0) {
164
165
  return {
@@ -261,16 +262,17 @@ function labelPropagationAsyncImpl(
261
262
  /**
262
263
  * Internal implementation of Semi-supervised Label Propagation
263
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
264
269
  */
265
270
  function labelPropagationSemiSupervisedImpl(
266
271
  graph: Map<string, Map<string, number>>,
267
272
  seedLabels: Map<string, number>,
268
273
  options: LabelPropagationOptions = {},
269
274
  ): LabelPropagationResult {
270
- const {
271
- maxIterations = 100,
272
- randomSeed = 42,
273
- } = options;
275
+ const { maxIterations = 100, randomSeed = 42 } = options;
274
276
 
275
277
  // Initialize random number generator
276
278
  const random = SeededRandom.createGenerator(randomSeed);
@@ -278,7 +280,7 @@ function labelPropagationSemiSupervisedImpl(
278
280
  // Initialize labels
279
281
  const labels = new Map<string, number>();
280
282
  const nodes = Array.from(graph.keys());
281
- let labelCounter = Math.max(... Array.from(seedLabels.values())) + 1;
283
+ let labelCounter = Math.max(...Array.from(seedLabels.values())) + 1;
282
284
 
283
285
  for (const node of nodes) {
284
286
  if (seedLabels.has(node)) {
@@ -366,7 +368,6 @@ function labelPropagationSemiSupervisedImpl(
366
368
  /**
367
369
  * Label Propagation Algorithm
368
370
  * Each node adopts the most frequent label among its neighbors
369
- *
370
371
  * @param graph - Undirected graph (can be weighted)
371
372
  * @param options - Algorithm options
372
373
  * @returns Community assignments
@@ -374,10 +375,7 @@ function labelPropagationSemiSupervisedImpl(
374
375
  * Time Complexity: O(m) per iteration, typically O(km) for k iterations
375
376
  * Space Complexity: O(n)
376
377
  */
377
- export function labelPropagation(
378
- graph: Graph,
379
- options: LabelPropagationOptions = {},
380
- ): LabelPropagationResult {
378
+ export function labelPropagation(graph: Graph, options: LabelPropagationOptions = {}): LabelPropagationResult {
381
379
  // Convert Graph to Map representation
382
380
  const graphMap = graphToMap(graph);
383
381
  return labelPropagationImpl(graphMap, options);
@@ -386,15 +384,11 @@ export function labelPropagation(
386
384
  /**
387
385
  * Asynchronous Label Propagation
388
386
  * Updates all nodes simultaneously (can lead to oscillations)
389
- *
390
387
  * @param graph - Undirected graph (can be weighted)
391
388
  * @param options - Algorithm options
392
389
  * @returns Community assignments
393
390
  */
394
- export function labelPropagationAsync(
395
- graph: Graph,
396
- options: LabelPropagationOptions = {},
397
- ): LabelPropagationResult {
391
+ export function labelPropagationAsync(graph: Graph, options: LabelPropagationOptions = {}): LabelPropagationResult {
398
392
  // Convert Graph to Map representation
399
393
  const graphMap = graphToMap(graph);
400
394
  return labelPropagationAsyncImpl(graphMap, options);
@@ -403,7 +397,6 @@ export function labelPropagationAsync(
403
397
  /**
404
398
  * Semi-supervised Label Propagation
405
399
  * Some nodes have fixed labels that don't change
406
- *
407
400
  * @param graph - Undirected graph (can be weighted)
408
401
  * @param seedLabels - Initial fixed labels for some nodes
409
402
  * @param options - Algorithm options
@@ -418,4 +411,3 @@ export function labelPropagationSemiSupervised(
418
411
  const graphMap = graphToMap(graph);
419
412
  return labelPropagationSemiSupervisedImpl(graphMap, seedLabels, options);
420
413
  }
421
-
@@ -8,9 +8,9 @@
8
8
  * "From Louvain to Leiden: guaranteeing well-connected communities"
9
9
  */
10
10
 
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";
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";
14
14
 
15
15
  export interface LeidenOptions {
16
16
  resolution?: number;
@@ -28,17 +28,12 @@ export interface LeidenResult {
28
28
  /**
29
29
  * Internal implementation of Leiden algorithm for community detection
30
30
  * Improves upon Louvain by ensuring well-connected communities
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
31
34
  */
32
- function leidenImpl(
33
- inputGraph: Map<string, Map<string, number>>,
34
- options: LeidenOptions = {},
35
- ): LeidenResult {
36
- const {
37
- resolution = 1.0,
38
- randomSeed = 42,
39
- maxIterations = 100,
40
- threshold = 1e-7,
41
- } = 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;
42
37
 
43
38
  // Handle empty graph
44
39
  if (inputGraph.size === 0) {
@@ -85,7 +80,7 @@ function leidenImpl(
85
80
  let improved = false;
86
81
 
87
82
  // Phase 1: Local moving of nodes (fast)
88
- const nodeOrder = [... nodes];
83
+ const nodeOrder = [...nodes];
89
84
  shuffle(nodeOrder, random);
90
85
 
91
86
  for (const node of nodeOrder) {
@@ -106,7 +101,13 @@ function leidenImpl(
106
101
  }
107
102
 
108
103
  const gain = calculateModularityGain(
109
- node, community, currentGraph, communities, degrees, totalWeight, resolution,
104
+ node,
105
+ community,
106
+ currentGraph,
107
+ communities,
108
+ degrees,
109
+ totalWeight,
110
+ resolution,
110
111
  );
111
112
 
112
113
  if (gain > bestGain) {
@@ -128,9 +129,7 @@ function leidenImpl(
128
129
  createAggregateNetwork(currentGraph, communities);
129
130
 
130
131
  // Refine partition using aggregate network
131
- const subsetPartition = refinePartition(
132
- currentGraph, communities,
133
- );
132
+ const subsetPartition = refinePartition(currentGraph, communities);
134
133
 
135
134
  // Apply refined partition
136
135
  for (const [node, newCommunity] of subsetPartition) {
@@ -158,7 +157,7 @@ function leidenImpl(
158
157
  } // No aggregation possible
159
158
 
160
159
  // Continue with aggregated network
161
- const {graph: aggregatedGraph} = aggregated;
160
+ const { graph: aggregatedGraph } = aggregated;
162
161
  currentGraph = aggregatedGraph;
163
162
  communities.clear();
164
163
  let communityId = 0;
@@ -195,6 +194,12 @@ function leidenImpl(
195
194
 
196
195
  /**
197
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
198
203
  */
199
204
  function calculateModularity(
200
205
  graph: Map<string, Map<string, number>>,
@@ -236,11 +241,11 @@ function calculateModularity(
236
241
  }
237
242
 
238
243
  // Normalize and apply resolution
239
- modularity /= (2 * totalWeight);
244
+ modularity /= 2 * totalWeight;
240
245
 
241
246
  // Subtract expected edges
242
247
  for (const weight of communityWeights.values()) {
243
- modularity -= resolution * ((weight / (2 * totalWeight)) ** 2);
248
+ modularity -= resolution * (weight / (2 * totalWeight)) ** 2;
244
249
  }
245
250
 
246
251
  return modularity;
@@ -248,6 +253,10 @@ function calculateModularity(
248
253
 
249
254
  /**
250
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
251
260
  */
252
261
  function getNeighborCommunities(
253
262
  node: string,
@@ -271,6 +280,14 @@ function getNeighborCommunities(
271
280
 
272
281
  /**
273
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
274
291
  */
275
292
  function calculateModularityGain(
276
293
  node: string,
@@ -327,22 +344,26 @@ function calculateModularityGain(
327
344
 
328
345
  // Modularity gain calculation
329
346
  const m2 = 2 * totalWeight;
330
- const gain = ((weightToTarget - weightToCurrent) / totalWeight) -
331
- (resolution * nodeDegree * (targetDegree - currentDegree) / (m2 * m2));
347
+ const gain =
348
+ (weightToTarget - weightToCurrent) / totalWeight -
349
+ (resolution * nodeDegree * (targetDegree - currentDegree)) / (m2 * m2);
332
350
 
333
351
  return gain;
334
352
  }
335
353
 
336
354
  /**
337
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
338
359
  */
339
360
  function createAggregateNetwork(
340
361
  graph: Map<string, Map<string, number>>,
341
362
  communities: Map<string, number>,
342
363
  ): {
343
- aggregateGraph: Map<number, Map<number, number>>;
344
- nodeMapping: Map<string, number>;
345
- } {
364
+ aggregateGraph: Map<number, Map<number, number>>;
365
+ nodeMapping: Map<string, number>;
366
+ } {
346
367
  const aggregateGraph = new Map<number, Map<number, number>>();
347
368
  const nodeMapping = new Map<string, number>();
348
369
 
@@ -375,12 +396,15 @@ function createAggregateNetwork(
375
396
  }
376
397
  }
377
398
 
378
- return {aggregateGraph, nodeMapping};
399
+ return { aggregateGraph, nodeMapping };
379
400
  }
380
401
 
381
402
  /**
382
403
  * Refine partition (Leiden-specific improvement)
383
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
384
408
  */
385
409
  function refinePartition(
386
410
  originalGraph: Map<string, Map<string, number>>,
@@ -448,6 +472,8 @@ function refinePartition(
448
472
 
449
473
  /**
450
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)
451
477
  */
452
478
  function findConnectedComponents(graph: Map<string, Set<string>>): Set<string>[] {
453
479
  const visited = new Set<string>();
@@ -486,14 +512,17 @@ function findConnectedComponents(graph: Map<string, Set<string>>): Set<string>[]
486
512
 
487
513
  /**
488
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
489
518
  */
490
519
  function aggregateCommunities(
491
520
  graph: Map<string, Map<string, number>>,
492
521
  communities: Map<string, number>,
493
522
  ): {
494
- graph: Map<string, Map<string, number>>;
495
- mapping: Map<string, string>;
496
- } {
523
+ graph: Map<string, Map<string, number>>;
524
+ mapping: Map<string, string>;
525
+ } {
497
526
  const aggregated = new Map<string, Map<string, number>>();
498
527
  const mapping = new Map<string, string>();
499
528
 
@@ -546,13 +575,12 @@ function aggregateCommunities(
546
575
  }
547
576
  }
548
577
 
549
- return {graph: aggregated, mapping};
578
+ return { graph: aggregated, mapping };
550
579
  }
551
580
 
552
581
  /**
553
582
  * Leiden algorithm for community detection
554
583
  * Improves upon Louvain by ensuring well-connected communities
555
- *
556
584
  * @param graph - Undirected weighted graph - accepts Graph class or Map representation
557
585
  * @param options - Algorithm options
558
586
  * @returns Community assignments and modularity
@@ -560,12 +588,8 @@ function aggregateCommunities(
560
588
  * Time Complexity: O(m) per iteration, typically O(m log m) total
561
589
  * Space Complexity: O(n + m)
562
590
  */
563
- export function leiden(
564
- graph: Graph,
565
- options: LeidenOptions = {},
566
- ): LeidenResult {
591
+ export function leiden(graph: Graph, options: LeidenOptions = {}): LeidenResult {
567
592
  // Convert Graph to Map representation
568
593
  const graphMap = graphToMap(graph);
569
594
  return leidenImpl(graphMap, options);
570
595
  }
571
-