@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
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import * as algorithms from "./algorithms/index.js";
11
- import {Graph} from "./core/graph.js";
11
+ import { Graph } from "./core/graph.js";
12
12
 
13
13
  interface BenchmarkResult {
14
14
  algorithm: string;
@@ -35,8 +35,8 @@ const ALGORITHM_CATEGORIES = {
35
35
  ],
36
36
  config: {
37
37
  name: "Traversal",
38
- quick: {nodes: 1000, edges: 5000, runs: 3},
39
- full: {nodes: 10000, edges: 50000, runs: 10},
38
+ quick: { nodes: 1000, edges: 5000, runs: 3 },
39
+ full: { nodes: 10000, edges: 50000, runs: 10 },
40
40
  },
41
41
  },
42
42
  shortestPath: {
@@ -54,8 +54,8 @@ const ALGORITHM_CATEGORIES = {
54
54
  ],
55
55
  config: {
56
56
  name: "Shortest Path",
57
- quick: {nodes: 100, edges: 500, runs: 1}, // Smaller for O(V³) algorithms
58
- full: {nodes: 500, edges: 2500, runs: 3},
57
+ quick: { nodes: 100, edges: 500, runs: 1 }, // Smaller for O(V³) algorithms
58
+ full: { nodes: 500, edges: 2500, runs: 3 },
59
59
  },
60
60
  },
61
61
  centrality: {
@@ -71,8 +71,8 @@ const ALGORITHM_CATEGORIES = {
71
71
  ],
72
72
  config: {
73
73
  name: "Centrality",
74
- quick: {nodes: 500, edges: 2500, runs: 1},
75
- full: {nodes: 2000, edges: 10000, runs: 3},
74
+ quick: { nodes: 500, edges: 2500, runs: 1 },
75
+ full: { nodes: 2000, edges: 10000, runs: 3 },
76
76
  },
77
77
  },
78
78
  components: {
@@ -90,44 +90,48 @@ const ALGORITHM_CATEGORIES = {
90
90
  ],
91
91
  config: {
92
92
  name: "Components",
93
- quick: {nodes: 2000, edges: 10000, runs: 3},
94
- full: {nodes: 10000, edges: 50000, runs: 10},
93
+ quick: { nodes: 2000, edges: 10000, runs: 3 },
94
+ full: { nodes: 10000, edges: 50000, runs: 10 },
95
95
  },
96
96
  },
97
97
  mst: {
98
98
  algorithms: ["kruskalMST", "primMST", "minimumSpanningTree"],
99
99
  config: {
100
100
  name: "Minimum Spanning Tree",
101
- quick: {nodes: 1000, edges: 5000, runs: 5},
102
- full: {nodes: 5000, edges: 25000, runs: 10},
101
+ quick: { nodes: 1000, edges: 5000, runs: 5 },
102
+ full: { nodes: 5000, edges: 25000, runs: 10 },
103
103
  },
104
104
  },
105
105
  community: {
106
106
  algorithms: ["girvanNewman", "labelPropagation", "leiden", "louvain"],
107
107
  config: {
108
108
  name: "Community Detection",
109
- quick: {nodes: 200, edges: 1000, runs: 1}, // Very expensive algorithms
110
- full: {nodes: 1000, edges: 5000, runs: 2},
109
+ quick: { nodes: 200, edges: 1000, runs: 1 }, // Very expensive algorithms
110
+ full: { nodes: 1000, edges: 5000, runs: 2 },
111
111
  },
112
112
  },
113
113
  matching: {
114
114
  algorithms: ["bipartitePartition", "greedyBipartiteMatching", "maximumBipartiteMatching"],
115
115
  config: {
116
116
  name: "Matching",
117
- quick: {nodes: 500, edges: 1000, runs: 3},
118
- full: {nodes: 2000, edges: 4000, runs: 5},
117
+ quick: { nodes: 500, edges: 1000, runs: 3 },
118
+ full: { nodes: 2000, edges: 4000, runs: 5 },
119
119
  },
120
120
  },
121
121
  } as const;
122
122
 
123
123
  /**
124
124
  * Main benchmark runner
125
+ * @param mode - The benchmark mode: "quick" for fast tests or "full" for comprehensive tests
126
+ * @returns Array of benchmark results for all tested algorithms
125
127
  */
126
128
  export function runAllAlgorithmsBenchmark(mode: "quick" | "full" = "full"): BenchmarkResult[] {
127
129
  const startTime = Date.now();
128
130
  const timeLimit = mode === "quick" ? 2 * 60 * 1000 : 60 * 60 * 1000; // 2 min or 1 hour
129
131
 
130
- console.log(`🚀 ${mode === "quick" ? "Quick" : "Comprehensive"} Benchmark - All ${String(getTotalAlgorithmCount())} Algorithms`);
132
+ console.log(
133
+ `🚀 ${mode === "quick" ? "Quick" : "Comprehensive"} Benchmark - All ${String(getTotalAlgorithmCount())} Algorithms`,
134
+ );
131
135
  console.log(`=${"=".repeat(60)}`);
132
136
  console.log(`Time limit: ${mode === "quick" ? "2 minutes" : "1 hour"}`);
133
137
  console.log(`Start time: ${new Date().toLocaleTimeString()}\n`);
@@ -175,7 +179,9 @@ export function runAllAlgorithmsBenchmark(mode: "quick" | "full" = "full"): Benc
175
179
  console.log("===================");
176
180
  console.log(`Total time: ${totalTime.toFixed(1)}s`);
177
181
  console.log(`Algorithms tested: ${String(totalTested)}`);
178
- console.log(`Success rate: ${String(totalPassed)}/${String(totalTested)} (${(totalPassed / totalTested * 100).toFixed(1)}%)`);
182
+ console.log(
183
+ `Success rate: ${String(totalPassed)}/${String(totalTested)} (${((totalPassed / totalTested) * 100).toFixed(1)}%)`,
184
+ );
179
185
 
180
186
  if (mode === "full") {
181
187
  displayDetailedResults(results);
@@ -186,6 +192,12 @@ export function runAllAlgorithmsBenchmark(mode: "quick" | "full" = "full"): Benc
186
192
 
187
193
  /**
188
194
  * Benchmark a single algorithm
195
+ * @param algoName - The name of the algorithm to benchmark
196
+ * @param category - The category the algorithm belongs to
197
+ * @param graph - The test graph to run the algorithm on
198
+ * @param runs - Number of times to run the algorithm for averaging
199
+ * @param mode - The benchmark mode (quick or full)
200
+ * @returns The benchmark result containing timing and success information
189
201
  */
190
202
  function benchmarkAlgorithm(
191
203
  algoName: string,
@@ -216,7 +228,7 @@ function benchmarkAlgorithm(
216
228
  const args = getAlgorithmArgs(algoName, graph);
217
229
  const start = performance.now();
218
230
 
219
- (algo as (... args: unknown[]) => unknown)(... args);
231
+ (algo as (...args: unknown[]) => unknown)(...args);
220
232
 
221
233
  const time = performance.now() - start;
222
234
  times.push(time);
@@ -251,6 +263,9 @@ function benchmarkAlgorithm(
251
263
 
252
264
  /**
253
265
  * Get appropriate arguments for each algorithm
266
+ * @param algoName - The name of the algorithm to get arguments for
267
+ * @param graph - The base graph to use for generating arguments
268
+ * @returns Array of arguments to pass to the algorithm function
254
269
  */
255
270
  function getAlgorithmArgs(algoName: string, graph: Graph): unknown[] {
256
271
  // Get random nodes for algorithms that need them
@@ -326,6 +341,10 @@ function getAlgorithmArgs(algoName: string, graph: Graph): unknown[] {
326
341
 
327
342
  /**
328
343
  * Create test graph appropriate for each algorithm category
344
+ * @param nodes - Number of nodes in the test graph
345
+ * @param edges - Target number of edges in the test graph
346
+ * @param category - The algorithm category to optimize the graph structure for
347
+ * @returns A new test graph with the specified structure
329
348
  */
330
349
  function createTestGraph(nodes: number, edges: number, category: string): Graph {
331
350
  const graph = new Graph();
@@ -362,6 +381,8 @@ function createTestGraph(nodes: number, edges: number, category: string): Graph
362
381
 
363
382
  /**
364
383
  * Create a connected random graph
384
+ * @param graph - The graph to add edges to
385
+ * @param targetEdges - Target number of edges to create
365
386
  */
366
387
  function createConnectedGraph(graph: Graph, targetEdges: number): void {
367
388
  const nodes = graph.nodeCount;
@@ -387,6 +408,8 @@ function createConnectedGraph(graph: Graph, targetEdges: number): void {
387
408
 
388
409
  /**
389
410
  * Create small-world graph (Watts-Strogatz model)
411
+ * @param graph - The graph to add edges to
412
+ * @param avgDegree - Target average degree for each node
390
413
  */
391
414
  function createSmallWorldGraph(graph: Graph, avgDegree: number): void {
392
415
  const nodes = graph.nodeCount;
@@ -418,6 +441,8 @@ function createSmallWorldGraph(graph: Graph, avgDegree: number): void {
418
441
 
419
442
  /**
420
443
  * Create graph with community structure
444
+ * @param graph - The graph to add edges to
445
+ * @param targetEdges - Target number of edges to create
421
446
  */
422
447
  function createCommunityGraph(graph: Graph, targetEdges: number): void {
423
448
  const nodes = graph.nodeCount;
@@ -433,7 +458,8 @@ function createCommunityGraph(graph: Graph, targetEdges: number): void {
433
458
 
434
459
  for (let i = start; i < end && edgesAdded < targetEdges; i++) {
435
460
  for (let j = i + 1; j < end && edgesAdded < targetEdges; j++) {
436
- if (Math.random() < 0.8) { // High probability within community
461
+ if (Math.random() < 0.8) {
462
+ // High probability within community
437
463
  graph.addEdge(i, j);
438
464
  edgesAdded++;
439
465
  }
@@ -455,9 +481,11 @@ function createCommunityGraph(graph: Graph, targetEdges: number): void {
455
481
 
456
482
  /**
457
483
  * Create directed version of graph
484
+ * @param undirectedGraph - The undirected graph to convert
485
+ * @returns A new directed graph with the same nodes and edges
458
486
  */
459
487
  function createDirectedGraph(undirectedGraph: Graph): Graph {
460
- const directedGraph = new Graph({directed: true});
488
+ const directedGraph = new Graph({ directed: true });
461
489
 
462
490
  // Copy nodes
463
491
  for (const node of undirectedGraph.nodes()) {
@@ -474,6 +502,8 @@ function createDirectedGraph(undirectedGraph: Graph): Graph {
474
502
 
475
503
  /**
476
504
  * Create bipartite graph
505
+ * @param nodesPerPartition - Number of nodes in each partition
506
+ * @returns A new bipartite graph with sparse connections between partitions
477
507
  */
478
508
  function createBipartiteGraph(nodesPerPartition: number): Graph {
479
509
  const graph = new Graph();
@@ -486,7 +516,8 @@ function createBipartiteGraph(nodesPerPartition: number): Graph {
486
516
  // Add edges only between partitions
487
517
  for (let i = 0; i < nodesPerPartition; i++) {
488
518
  for (let j = nodesPerPartition; j < nodesPerPartition * 2; j++) {
489
- if (Math.random() < 0.3) { // Sparse bipartite graph
519
+ if (Math.random() < 0.3) {
520
+ // Sparse bipartite graph
490
521
  graph.addEdge(i, j);
491
522
  }
492
523
  }
@@ -497,14 +528,15 @@ function createBipartiteGraph(nodesPerPartition: number): Graph {
497
528
 
498
529
  /**
499
530
  * Get total algorithm count
531
+ * @returns The total number of algorithms across all categories
500
532
  */
501
533
  function getTotalAlgorithmCount(): number {
502
- return Object.values(ALGORITHM_CATEGORIES).reduce((total, category) =>
503
- total + category.algorithms.length, 0);
534
+ return Object.values(ALGORITHM_CATEGORIES).reduce((total, category) => total + category.algorithms.length, 0);
504
535
  }
505
536
 
506
537
  /**
507
538
  * Display detailed results for full benchmark
539
+ * @param results - Array of benchmark results to display
508
540
  */
509
541
  function displayDetailedResults(results: BenchmarkResult[]): void {
510
542
  console.log("\n📊 Detailed Results");
@@ -530,8 +562,8 @@ function displayDetailedResults(results: BenchmarkResult[]): void {
530
562
  if (successful.length > 0) {
531
563
  const avgTime = successful.reduce((sum, r) => sum + r.executionTime, 0) / successful.length;
532
564
  console.log(` Average time: ${avgTime.toFixed(2)}ms`);
533
- const minTime = Math.min(... successful.map((r) => r.executionTime));
534
- const maxTime = Math.max(... successful.map((r) => r.executionTime));
565
+ const minTime = Math.min(...successful.map((r) => r.executionTime));
566
+ const maxTime = Math.max(...successful.map((r) => r.executionTime));
535
567
  console.log(` Range: ${minTime.toFixed(2)}ms - ${maxTime.toFixed(2)}ms`);
536
568
  }
537
569
 
@@ -6,10 +6,12 @@
6
6
  * structure in graphs.
7
7
  */
8
8
 
9
- import type {Graph} from "../core/graph.js";
9
+ import type { Graph } from "../core/graph.js";
10
10
 
11
11
  /**
12
12
  * Convert Graph to adjacency set representation for clustering
13
+ * @param graph - The input graph to convert
14
+ * @returns Map of node IDs to sets of neighbor node IDs
13
15
  */
14
16
  function graphToAdjacencySet(graph: Graph): Map<string, Set<string>> {
15
17
  const adjacency = new Map<string, Set<string>>();
@@ -62,11 +64,10 @@ export type LinkageMethod = "single" | "complete" | "average" | "ward";
62
64
 
63
65
  /**
64
66
  * Compute distance between two nodes based on graph structure
67
+ * @param graph - Adjacency map representation of the graph
68
+ * @param distances - Map to store computed distances between nodes
65
69
  */
66
- function computeGraphDistance<T>(
67
- graph: Map<T, Set<T>>,
68
- distances: Map<T, Map<T, number>>,
69
- ): void {
70
+ function computeGraphDistance<T>(graph: Map<T, Set<T>>, distances: Map<T, Map<T, number>>): void {
70
71
  // Use BFS to compute shortest path distances
71
72
  for (const start of graph.keys()) {
72
73
  const dist = new Map<T, number>();
@@ -97,6 +98,11 @@ function computeGraphDistance<T>(
97
98
 
98
99
  /**
99
100
  * Compute distance between two clusters based on linkage method
101
+ * @param cluster1 - First cluster node
102
+ * @param cluster2 - Second cluster node
103
+ * @param distances - Precomputed distance matrix between nodes
104
+ * @param linkage - Linkage method to use for computing cluster distance
105
+ * @returns The distance between the two clusters
100
106
  */
101
107
  function clusterDistance<T>(
102
108
  cluster1: ClusterNode<T>,
@@ -126,9 +132,9 @@ function clusterDistance<T>(
126
132
 
127
133
  switch (linkage) {
128
134
  case "single":
129
- return Math.min(... allDistances);
135
+ return Math.min(...allDistances);
130
136
  case "complete":
131
- return Math.max(... allDistances);
137
+ return Math.max(...allDistances);
132
138
  case "average":
133
139
  return allDistances.reduce((a, b) => a + b, 0) / allDistances.length;
134
140
  case "ward": {
@@ -139,12 +145,15 @@ function clusterDistance<T>(
139
145
  return avgDist * ((size1 * size2) / (size1 + size2));
140
146
  }
141
147
  default:
142
- return Math.min(... allDistances);
148
+ return Math.min(...allDistances);
143
149
  }
144
150
  }
145
151
 
146
152
  /**
147
153
  * Internal implementation of agglomerative hierarchical clustering
154
+ * @param graph - Adjacency map representation of the graph
155
+ * @param linkage - Linkage method for cluster distance computation
156
+ * @returns Hierarchical clustering result with dendrogram and cluster assignments
148
157
  */
149
158
  function hierarchicalClusteringImpl<T>(
150
159
  graph: Map<T, Set<T>>,
@@ -155,7 +164,7 @@ function hierarchicalClusteringImpl<T>(
155
164
 
156
165
  if (n === 0) {
157
166
  return {
158
- root: {id: "empty", members: new Set(), distance: 0, height: 0},
167
+ root: { id: "empty", members: new Set(), distance: 0, height: 0 },
159
168
  dendrogram: [],
160
169
  clusters: new Map(),
161
170
  };
@@ -173,7 +182,7 @@ function hierarchicalClusteringImpl<T>(
173
182
  height: 0,
174
183
  }));
175
184
 
176
- const dendrogram: ClusterNode<T>[] = [... clusters];
185
+ const dendrogram: ClusterNode<T>[] = [...clusters];
177
186
  let clusterCount = n;
178
187
 
179
188
  // Distance matrix between clusters
@@ -220,9 +229,8 @@ function hierarchicalClusteringImpl<T>(
220
229
  continue;
221
230
  }
222
231
 
223
- const dist = distMap.get(cluster2.id) ??
224
- clusterDistances.get(cluster2.id)?.get(cluster1.id) ??
225
- Infinity;
232
+ const dist =
233
+ distMap.get(cluster2.id) ?? clusterDistances.get(cluster2.id)?.get(cluster1.id) ?? Infinity;
226
234
 
227
235
  if (dist < minDist) {
228
236
  minDist = dist;
@@ -239,7 +247,7 @@ function hierarchicalClusteringImpl<T>(
239
247
  id: `forest-${String(clusterCount++)}`,
240
248
  members: new Set(nodes),
241
249
  distance: Infinity,
242
- height: Math.max(... trees.map((t) => t.height)) + 1,
250
+ height: Math.max(...trees.map((t) => t.height)) + 1,
243
251
  trees,
244
252
  };
245
253
  dendrogram.push(forestRoot);
@@ -251,7 +259,7 @@ function hierarchicalClusteringImpl<T>(
251
259
  // Create new cluster
252
260
  const newCluster: ClusterNode<T> = {
253
261
  id: `cluster-${String(clusterCount++)}`,
254
- members: new Set([... mergeCluster1.members, ... mergeCluster2.members]),
262
+ members: new Set([...mergeCluster1.members, ...mergeCluster2.members]),
255
263
  left: mergeCluster1,
256
264
  right: mergeCluster2,
257
265
  distance: minDist,
@@ -301,7 +309,7 @@ function hierarchicalClusteringImpl<T>(
301
309
 
302
310
  if (!root) {
303
311
  return {
304
- root: {id: "empty", members: new Set(), distance: 0, height: 0},
312
+ root: { id: "empty", members: new Set(), distance: 0, height: 0 },
305
313
  dendrogram: [],
306
314
  clusters: new Map(),
307
315
  };
@@ -320,11 +328,11 @@ function hierarchicalClusteringImpl<T>(
320
328
 
321
329
  /**
322
330
  * Cut dendrogram at specific height to get clusters
331
+ * @param root - Root node of the dendrogram
332
+ * @param height - Height at which to cut the dendrogram
333
+ * @returns Array of sets representing clusters at the specified height
323
334
  */
324
- export function cutDendrogram<T>(
325
- root: ClusterNode<T>,
326
- height: number,
327
- ): Set<T>[] {
335
+ export function cutDendrogram<T>(root: ClusterNode<T>, height: number): Set<T>[] {
328
336
  const clusters: Set<T>[] = [];
329
337
 
330
338
  function traverse(node: ClusterNode<T>): void {
@@ -354,11 +362,11 @@ export function cutDendrogram<T>(
354
362
 
355
363
  /**
356
364
  * Cut dendrogram to get exactly k clusters
365
+ * @param root - Root node of the dendrogram
366
+ * @param k - Target number of clusters
367
+ * @returns Array of sets representing exactly k clusters
357
368
  */
358
- export function cutDendrogramKClusters<T>(
359
- root: ClusterNode<T>,
360
- k: number,
361
- ): Set<T>[] {
369
+ export function cutDendrogramKClusters<T>(root: ClusterNode<T>, k: number): Set<T>[] {
362
370
  if (k <= 0) {
363
371
  return [];
364
372
  }
@@ -390,17 +398,17 @@ export function cutDendrogramKClusters<T>(
390
398
  /**
391
399
  * Compute modularity-based hierarchical clustering
392
400
  * Uses modularity gain to decide merges
401
+ * @param graph - The input graph to cluster
402
+ * @returns Hierarchical clustering result with dendrogram and cluster assignments
393
403
  */
394
- export function modularityHierarchicalClustering(
395
- graph: Graph,
396
- ): HierarchicalClusteringResult<string> {
404
+ export function modularityHierarchicalClustering(graph: Graph): HierarchicalClusteringResult<string> {
397
405
  const adjacencySet = graphToAdjacencySet(graph);
398
406
  const nodes = Array.from(adjacencySet.keys());
399
407
  const n = nodes.length;
400
408
 
401
409
  if (n === 0) {
402
410
  return {
403
- root: {id: "empty", members: new Set(), distance: 0, height: 0},
411
+ root: { id: "empty", members: new Set(), distance: 0, height: 0 },
404
412
  dendrogram: [],
405
413
  clusters: new Map(),
406
414
  };
@@ -426,7 +434,7 @@ export function modularityHierarchicalClustering(
426
434
  height: 0,
427
435
  }));
428
436
 
429
- const dendrogram: ClusterNode<string>[] = [... clusters];
437
+ const dendrogram: ClusterNode<string>[] = [...clusters];
430
438
  let clusterCount = n;
431
439
 
432
440
  // Active clusters
@@ -466,8 +474,7 @@ export function modularityHierarchicalClustering(
466
474
  }
467
475
  }
468
476
 
469
- const gain = (edgesBetween / totalEdges) -
470
- (degreeProduct / (4 * totalEdges * totalEdges));
477
+ const gain = edgesBetween / totalEdges - degreeProduct / (4 * totalEdges * totalEdges);
471
478
 
472
479
  if (gain > maxGain) {
473
480
  maxGain = gain;
@@ -484,7 +491,7 @@ export function modularityHierarchicalClustering(
484
491
  // Create new cluster
485
492
  const newCluster: ClusterNode<string> = {
486
493
  id: `cluster-${String(clusterCount++)}`,
487
- members: new Set([... mergeCluster1.members, ... mergeCluster2.members]),
494
+ members: new Set([...mergeCluster1.members, ...mergeCluster2.members]),
488
495
  left: mergeCluster1,
489
496
  right: mergeCluster2,
490
497
  distance: -maxGain, // Use negative gain as distance
@@ -507,7 +514,7 @@ export function modularityHierarchicalClustering(
507
514
 
508
515
  if (!root) {
509
516
  return {
510
- root: {id: "empty", members: new Set(), distance: 0, height: 0},
517
+ root: { id: "empty", members: new Set(), distance: 0, height: 0 },
511
518
  dendrogram: [],
512
519
  clusters: new Map(),
513
520
  };
@@ -527,7 +534,6 @@ export function modularityHierarchicalClustering(
527
534
  /**
528
535
  * Agglomerative hierarchical clustering
529
536
  * Builds clusters bottom-up by merging closest pairs
530
- *
531
537
  * @param graph - Undirected graph - accepts Graph class or Map<T, Set<T>>
532
538
  * @param linkage - Linkage method for cluster distance
533
539
  * @returns Hierarchical clustering result
@@ -1,8 +1,8 @@
1
- export type {ClusterNode, HierarchicalClusteringResult, LinkageMethod} from "./hierarchical.js";
2
- export {hierarchicalClustering} from "./hierarchical.js";
3
- export type {KCoreResult} from "./k-core.js";
4
- export {getKCore, kCoreDecomposition} from "./k-core.js";
5
- export type {MCLOptions, MCLResult} from "./mcl.js";
6
- export {calculateMCLModularity, markovClustering} from "./mcl.js";
7
- export type {SpectralClusteringOptions, SpectralClusteringResult} from "./spectral.js";
8
- export {spectralClustering} from "./spectral.js";
1
+ export type { ClusterNode, HierarchicalClusteringResult, LinkageMethod } from "./hierarchical.js";
2
+ export { hierarchicalClustering } from "./hierarchical.js";
3
+ export type { KCoreResult } from "./k-core.js";
4
+ export { getKCore, kCoreDecomposition } from "./k-core.js";
5
+ export type { MCLOptions, MCLResult } from "./mcl.js";
6
+ export { calculateMCLModularity, markovClustering } from "./mcl.js";
7
+ export type { SpectralClusteringOptions, SpectralClusteringResult } from "./spectral.js";
8
+ export { spectralClustering } from "./spectral.js";
@@ -6,10 +6,12 @@
6
6
  * understanding graph structure.
7
7
  */
8
8
 
9
- import type {Graph} from "../core/graph.js";
9
+ import type { Graph } from "../core/graph.js";
10
10
 
11
11
  /**
12
12
  * Convert Graph to adjacency set representation
13
+ * @param graph - The input graph to convert
14
+ * @returns Map of node IDs to sets of neighbor node IDs
13
15
  */
14
16
  function graphToAdjacencySet(graph: Graph): Map<string, Set<string>> {
15
17
  const adjacency = new Map<string, Set<string>>();
@@ -49,12 +51,12 @@ export interface KCoreResult<T> {
49
51
 
50
52
  /**
51
53
  * Internal implementation of K-Core decomposition algorithm
54
+ * @param graph - Adjacency map representation of the graph
55
+ * @returns K-core decomposition result with cores, coreness values, and maximum core number
52
56
  */
53
- function kCoreDecompositionImpl<T>(
54
- graph: Map<T, Set<T>>,
55
- ): KCoreResult<T> {
57
+ function kCoreDecompositionImpl<T>(graph: Map<T, Set<T>>): KCoreResult<T> {
56
58
  if (graph.size === 0) {
57
- return {cores: new Map(), coreness: new Map(), maxCore: 0};
59
+ return { cores: new Map(), coreness: new Map(), maxCore: 0 };
58
60
  }
59
61
 
60
62
  const n = graph.size;
@@ -208,22 +210,18 @@ function kCoreDecompositionImpl<T>(
208
210
  maxCore = Math.max(maxCore, core);
209
211
  }
210
212
 
211
- return {cores, coreness, maxCore};
213
+ return { cores, coreness, maxCore };
212
214
  }
213
215
 
214
216
  /**
215
217
  * Extract the k-core subgraph
216
218
  * Returns nodes that belong to k-core or higher
217
- *
218
219
  * @param graph - Undirected graph
219
220
  * @param k - Core number
220
221
  * @returns Set of nodes in k-core or higher
221
222
  */
222
- export function getKCore(
223
- graph: Graph,
224
- k: number,
225
- ): Set<string> {
226
- const {coreness} = kCoreDecomposition(graph);
223
+ export function getKCore(graph: Graph, k: number): Set<string> {
224
+ const { coreness } = kCoreDecomposition(graph);
227
225
  const kCore = new Set<string>();
228
226
 
229
227
  for (const [node, core] of coreness) {
@@ -238,15 +236,11 @@ export function getKCore(
238
236
  /**
239
237
  * Get the induced subgraph for k-core
240
238
  * Returns the actual subgraph containing only k-core nodes
241
- *
242
239
  * @param graph - Original graph
243
240
  * @param k - Core number
244
241
  * @returns K-core subgraph
245
242
  */
246
- export function getKCoreSubgraph(
247
- graph: Graph,
248
- k: number,
249
- ): Map<string, Set<string>> {
243
+ export function getKCoreSubgraph(graph: Graph, k: number): Map<string, Set<string>> {
250
244
  const kCoreNodes = getKCore(graph, k);
251
245
  const adjacencySet = graphToAdjacencySet(graph);
252
246
  const subgraph = new Map<string, Set<string>>();
@@ -270,13 +264,10 @@ export function getKCoreSubgraph(
270
264
  /**
271
265
  * Degeneracy ordering of the graph
272
266
  * Orders nodes by their coreness values
273
- *
274
267
  * @param graph - Undirected graph
275
268
  * @returns Array of nodes ordered by degeneracy
276
269
  */
277
- export function degeneracyOrdering(
278
- graph: Graph,
279
- ): string[] {
270
+ export function degeneracyOrdering(graph: Graph): string[] {
280
271
  const adjacencySet = graphToAdjacencySet(graph);
281
272
  const degree = new Map<string, number>();
282
273
  const remaining = new Map<string, Set<string>>();
@@ -290,7 +281,7 @@ export function degeneracyOrdering(
290
281
 
291
282
  // Build ordering
292
283
  while (ordering.length < adjacencySet.size) {
293
- // Find minimum degree node
284
+ // Find minimum degree node
294
285
  let minDegree = Infinity;
295
286
  let minNode: string | undefined;
296
287
 
@@ -327,15 +318,11 @@ export function degeneracyOrdering(
327
318
  /**
328
319
  * Find k-truss subgraph (triangular k-cores)
329
320
  * Each edge must be part of at least k-2 triangles
330
- *
331
321
  * @param graph - Undirected graph
332
322
  * @param k - Truss number (k >= 2)
333
323
  * @returns Edges in k-truss
334
324
  */
335
- export function kTruss(
336
- graph: Graph,
337
- k: number,
338
- ): Set<string> {
325
+ export function kTruss(graph: Graph, k: number): Set<string> {
339
326
  if (k < 2) {
340
327
  throw new Error("k must be at least 2 for k-truss");
341
328
  }
@@ -349,8 +336,9 @@ export function kTruss(
349
336
  // Initialize edges
350
337
  for (const [u, neighbors] of adjacencySet) {
351
338
  for (const v of neighbors) {
352
- if (u < v) { // Avoid duplicates
353
- const edge = `${String(u)},${String(v)}`;
339
+ if (u < v) {
340
+ // Avoid duplicates
341
+ const edge = `${u},${v}`;
354
342
  edges.add(edge);
355
343
  edgeTriangles.set(edge, 0);
356
344
  }
@@ -367,9 +355,9 @@ export function kTruss(
367
355
  for (const w of uNeighbors) {
368
356
  if (v < w && vNeighbors.has(w)) {
369
357
  // Triangle found: u-v-w
370
- const edge1 = `${String(u)},${String(v)}`;
371
- const edge2 = `${String(u)},${String(w)}`;
372
- const edge3 = `${String(v)},${String(w)}`;
358
+ const edge1 = `${u},${v}`;
359
+ const edge2 = `${u},${w}`;
360
+ const edge3 = `${v},${w}`;
373
361
 
374
362
  const edge1Count = edgeTriangles.get(edge1);
375
363
  const edge2Count = edgeTriangles.get(edge2);
@@ -428,8 +416,8 @@ export function kTruss(
428
416
  if (uNeighbors && vNeighbors) {
429
417
  for (const w of uNeighbors) {
430
418
  if (vNeighbors.has(w)) {
431
- const edge1 = u < w ? `${String(u)},${String(w)}` : `${String(w)},${String(u)}`;
432
- const edge2 = v < w ? `${String(v)},${String(w)}` : `${String(w)},${String(v)}`;
419
+ const edge1 = u < w ? `${u},${w}` : `${w},${u}`;
420
+ const edge2 = v < w ? `${v},${w}` : `${w},${v}`;
433
421
 
434
422
  if (kTrussEdges.has(edge1)) {
435
423
  const edge1Count = edgeTriangles.get(edge1);
@@ -455,10 +443,10 @@ export function kTruss(
455
443
 
456
444
  /**
457
445
  * Convert directed graph to undirected for k-core analysis
446
+ * @param directedGraph - Directed graph represented as adjacency map with edge weights
447
+ * @returns Undirected graph represented as adjacency map with neighbor sets
458
448
  */
459
- export function toUndirected<T>(
460
- directedGraph: Map<T, Map<T, number>>,
461
- ): Map<T, Set<T>> {
449
+ export function toUndirected<T>(directedGraph: Map<T, Map<T, number>>): Map<T, Set<T>> {
462
450
  const undirected = new Map<T, Set<T>>();
463
451
 
464
452
  // Initialize all nodes
@@ -491,18 +479,14 @@ export function toUndirected<T>(
491
479
  /**
492
480
  * K-Core decomposition algorithm
493
481
  * Finds all k-cores in the graph and assigns coreness values to nodes
494
- *
495
482
  * @param graph - Undirected graph - accepts Graph class or Map<T, Set<T>>
496
483
  * @returns K-core decomposition results
497
484
  *
498
485
  * Time Complexity: O(V + E)
499
486
  * Space Complexity: O(V)
500
487
  */
501
- export function kCoreDecomposition(
502
- graph: Graph,
503
- ): KCoreResult<string> {
488
+ export function kCoreDecomposition(graph: Graph): KCoreResult<string> {
504
489
  // Convert Graph to adjacency set representation
505
490
  const adjacencySet = graphToAdjacencySet(graph);
506
491
  return kCoreDecompositionImpl(adjacencySet);
507
492
  }
508
-