@graphty/algorithms 1.2.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/README.md +375 -276
  2. package/dist/algorithms.d.ts +42 -2
  3. package/dist/algorithms.js +11402 -2
  4. package/dist/algorithms.js.map +1 -1
  5. package/dist/src/algorithms/centrality/betweenness.d.ts +14 -0
  6. package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
  7. package/dist/src/algorithms/centrality/betweenness.js +144 -169
  8. package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
  9. package/dist/src/algorithms/centrality/closeness.d.ts +35 -1
  10. package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -1
  11. package/dist/src/algorithms/centrality/closeness.js +70 -149
  12. package/dist/src/algorithms/centrality/closeness.js.map +1 -1
  13. package/dist/src/algorithms/centrality/degree.d.ts +7 -0
  14. package/dist/src/algorithms/centrality/degree.d.ts.map +1 -1
  15. package/dist/src/algorithms/centrality/degree.js +12 -9
  16. package/dist/src/algorithms/centrality/degree.js.map +1 -1
  17. package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts +57 -0
  18. package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts.map +1 -0
  19. package/dist/src/algorithms/centrality/delta-pagerank-simple.js +304 -0
  20. package/dist/src/algorithms/centrality/delta-pagerank-simple.js.map +1 -0
  21. package/dist/src/algorithms/centrality/delta-pagerank.d.ts +106 -0
  22. package/dist/src/algorithms/centrality/delta-pagerank.d.ts.map +1 -0
  23. package/dist/src/algorithms/centrality/delta-pagerank.js +320 -0
  24. package/dist/src/algorithms/centrality/delta-pagerank.js.map +1 -0
  25. package/dist/src/algorithms/centrality/eigenvector.d.ts +10 -3
  26. package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -1
  27. package/dist/src/algorithms/centrality/eigenvector.js +11 -4
  28. package/dist/src/algorithms/centrality/eigenvector.js.map +1 -1
  29. package/dist/src/algorithms/centrality/hits.d.ts +10 -3
  30. package/dist/src/algorithms/centrality/hits.d.ts.map +1 -1
  31. package/dist/src/algorithms/centrality/hits.js +11 -4
  32. package/dist/src/algorithms/centrality/hits.js.map +1 -1
  33. package/dist/src/algorithms/centrality/index.d.ts +3 -1
  34. package/dist/src/algorithms/centrality/index.d.ts.map +1 -1
  35. package/dist/src/algorithms/centrality/index.js +2 -1
  36. package/dist/src/algorithms/centrality/index.js.map +1 -1
  37. package/dist/src/algorithms/centrality/katz.d.ts +10 -3
  38. package/dist/src/algorithms/centrality/katz.d.ts.map +1 -1
  39. package/dist/src/algorithms/centrality/katz.js +13 -8
  40. package/dist/src/algorithms/centrality/katz.js.map +1 -1
  41. package/dist/src/algorithms/centrality/pagerank.d.ts +31 -0
  42. package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -1
  43. package/dist/src/algorithms/centrality/pagerank.js +61 -1
  44. package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
  45. package/dist/src/algorithms/community/girvan-newman.d.ts +2 -3
  46. package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -1
  47. package/dist/src/algorithms/community/girvan-newman.js +67 -57
  48. package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
  49. package/dist/src/algorithms/community/index.d.ts +2 -0
  50. package/dist/src/algorithms/community/index.d.ts.map +1 -1
  51. package/dist/src/algorithms/community/index.js.map +1 -1
  52. package/dist/src/algorithms/community/label-propagation.d.ts +11 -4
  53. package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -1
  54. package/dist/src/algorithms/community/label-propagation.js +60 -38
  55. package/dist/src/algorithms/community/label-propagation.js.map +1 -1
  56. package/dist/src/algorithms/community/leiden.d.ts +3 -3
  57. package/dist/src/algorithms/community/leiden.d.ts.map +1 -1
  58. package/dist/src/algorithms/community/leiden.js +70 -44
  59. package/dist/src/algorithms/community/leiden.js.map +1 -1
  60. package/dist/src/algorithms/community/louvain-optimized.d.ts +149 -0
  61. package/dist/src/algorithms/community/louvain-optimized.d.ts.map +1 -0
  62. package/dist/src/algorithms/community/louvain-optimized.js +338 -0
  63. package/dist/src/algorithms/community/louvain-optimized.js.map +1 -0
  64. package/dist/src/algorithms/community/louvain.d.ts +2 -3
  65. package/dist/src/algorithms/community/louvain.d.ts.map +1 -1
  66. package/dist/src/algorithms/community/louvain.js +35 -81
  67. package/dist/src/algorithms/community/louvain.js.map +1 -1
  68. package/dist/src/algorithms/community/modularity-utils.d.ts +55 -0
  69. package/dist/src/algorithms/community/modularity-utils.d.ts.map +1 -0
  70. package/dist/src/algorithms/community/modularity-utils.js +108 -0
  71. package/dist/src/algorithms/community/modularity-utils.js.map +1 -0
  72. package/dist/src/algorithms/components/connected.d.ts +23 -0
  73. package/dist/src/algorithms/components/connected.d.ts.map +1 -1
  74. package/dist/src/algorithms/components/connected.js +29 -3
  75. package/dist/src/algorithms/components/connected.js.map +1 -1
  76. package/dist/src/algorithms/matching/bipartite.d.ts +10 -0
  77. package/dist/src/algorithms/matching/bipartite.d.ts.map +1 -1
  78. package/dist/src/algorithms/matching/bipartite.js +18 -40
  79. package/dist/src/algorithms/matching/bipartite.js.map +1 -1
  80. package/dist/src/algorithms/matching/index.d.ts.map +1 -1
  81. package/dist/src/algorithms/matching/index.js.map +1 -1
  82. package/dist/src/algorithms/matching/isomorphism.d.ts +8 -0
  83. package/dist/src/algorithms/matching/isomorphism.d.ts.map +1 -1
  84. package/dist/src/algorithms/matching/isomorphism.js +36 -2
  85. package/dist/src/algorithms/matching/isomorphism.js.map +1 -1
  86. package/dist/src/algorithms/mst/index.d.ts.map +1 -1
  87. package/dist/src/algorithms/mst/index.js.map +1 -1
  88. package/dist/src/algorithms/mst/kruskal.d.ts +14 -0
  89. package/dist/src/algorithms/mst/kruskal.d.ts.map +1 -1
  90. package/dist/src/algorithms/mst/kruskal.js +17 -3
  91. package/dist/src/algorithms/mst/kruskal.js.map +1 -1
  92. package/dist/src/algorithms/mst/prim.d.ts +9 -0
  93. package/dist/src/algorithms/mst/prim.d.ts.map +1 -1
  94. package/dist/src/algorithms/mst/prim.js +9 -0
  95. package/dist/src/algorithms/mst/prim.js.map +1 -1
  96. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts +10 -0
  97. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -1
  98. package/dist/src/algorithms/shortest-path/bellman-ford.js +11 -12
  99. package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
  100. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts +44 -0
  101. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts.map +1 -0
  102. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js +195 -0
  103. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js.map +1 -0
  104. package/dist/src/algorithms/shortest-path/dijkstra.d.ts +20 -2
  105. package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -1
  106. package/dist/src/algorithms/shortest-path/dijkstra.js +30 -14
  107. package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
  108. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts +17 -0
  109. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts.map +1 -1
  110. package/dist/src/algorithms/shortest-path/floyd-warshall.js +17 -0
  111. package/dist/src/algorithms/shortest-path/floyd-warshall.js.map +1 -1
  112. package/dist/src/algorithms/shortest-path/index.d.ts.map +1 -1
  113. package/dist/src/algorithms/shortest-path/index.js.map +1 -1
  114. package/dist/src/algorithms/traversal/bfs-unified.d.ts +42 -0
  115. package/dist/src/algorithms/traversal/bfs-unified.d.ts.map +1 -0
  116. package/dist/src/algorithms/traversal/bfs-unified.js +370 -0
  117. package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -0
  118. package/dist/src/algorithms/traversal/bfs-variants.d.ts +77 -0
  119. package/dist/src/algorithms/traversal/bfs-variants.d.ts.map +1 -0
  120. package/dist/src/algorithms/traversal/bfs-variants.js +402 -0
  121. package/dist/src/algorithms/traversal/bfs-variants.js.map +1 -0
  122. package/dist/src/algorithms/traversal/bfs.d.ts +4 -18
  123. package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -1
  124. package/dist/src/algorithms/traversal/bfs.js +5 -182
  125. package/dist/src/algorithms/traversal/bfs.js.map +1 -1
  126. package/dist/src/algorithms/traversal/dfs.d.ts +10 -0
  127. package/dist/src/algorithms/traversal/dfs.d.ts.map +1 -1
  128. package/dist/src/algorithms/traversal/dfs.js +48 -0
  129. package/dist/src/algorithms/traversal/dfs.js.map +1 -1
  130. package/dist/src/algorithms/traversal/index.d.ts.map +1 -1
  131. package/dist/src/algorithms/traversal/index.js.map +1 -1
  132. package/dist/src/benchmark-all-algorithms.d.ts +25 -0
  133. package/dist/src/benchmark-all-algorithms.d.ts.map +1 -0
  134. package/dist/src/benchmark-all-algorithms.js +491 -0
  135. package/dist/src/benchmark-all-algorithms.js.map +1 -0
  136. package/dist/src/clustering/hierarchical.d.ts +23 -15
  137. package/dist/src/clustering/hierarchical.d.ts.map +1 -1
  138. package/dist/src/clustering/hierarchical.js +226 -224
  139. package/dist/src/clustering/hierarchical.js.map +1 -1
  140. package/dist/src/clustering/index.d.ts +4 -2
  141. package/dist/src/clustering/index.d.ts.map +1 -1
  142. package/dist/src/clustering/index.js +2 -2
  143. package/dist/src/clustering/index.js.map +1 -1
  144. package/dist/src/clustering/k-core.d.ts +17 -19
  145. package/dist/src/clustering/k-core.d.ts.map +1 -1
  146. package/dist/src/clustering/k-core.js +68 -30
  147. package/dist/src/clustering/k-core.js.map +1 -1
  148. package/dist/src/clustering/mcl.d.ts +6 -0
  149. package/dist/src/clustering/mcl.d.ts.map +1 -1
  150. package/dist/src/clustering/mcl.js +34 -3
  151. package/dist/src/clustering/mcl.js.map +1 -1
  152. package/dist/src/clustering/spectral.d.ts +11 -0
  153. package/dist/src/clustering/spectral.d.ts.map +1 -1
  154. package/dist/src/clustering/spectral.js +99 -47
  155. package/dist/src/clustering/spectral.js.map +1 -1
  156. package/dist/src/core/graph.d.ts +45 -0
  157. package/dist/src/core/graph.d.ts.map +1 -1
  158. package/dist/src/core/graph.js +49 -5
  159. package/dist/src/core/graph.js.map +1 -1
  160. package/dist/src/data-structures/index.d.ts.map +1 -1
  161. package/dist/src/data-structures/index.js.map +1 -1
  162. package/dist/src/data-structures/priority-queue.d.ts +18 -1
  163. package/dist/src/data-structures/priority-queue.d.ts.map +1 -1
  164. package/dist/src/data-structures/priority-queue.js +26 -5
  165. package/dist/src/data-structures/priority-queue.js.map +1 -1
  166. package/dist/src/data-structures/union-find.d.ts +21 -0
  167. package/dist/src/data-structures/union-find.d.ts.map +1 -1
  168. package/dist/src/data-structures/union-find.js +21 -0
  169. package/dist/src/data-structures/union-find.js.map +1 -1
  170. package/dist/src/flow/ford-fulkerson.d.ts +20 -12
  171. package/dist/src/flow/ford-fulkerson.d.ts.map +1 -1
  172. package/dist/src/flow/ford-fulkerson.js +170 -217
  173. package/dist/src/flow/ford-fulkerson.js.map +1 -1
  174. package/dist/src/flow/min-cut.d.ts +6 -8
  175. package/dist/src/flow/min-cut.d.ts.map +1 -1
  176. package/dist/src/flow/min-cut.js +34 -12
  177. package/dist/src/flow/min-cut.js.map +1 -1
  178. package/dist/src/index.d.ts +3 -1
  179. package/dist/src/index.d.ts.map +1 -1
  180. package/dist/src/index.js +6 -1
  181. package/dist/src/index.js.map +1 -1
  182. package/dist/src/link-prediction/adamic-adar.d.ts +26 -0
  183. package/dist/src/link-prediction/adamic-adar.d.ts.map +1 -1
  184. package/dist/src/link-prediction/adamic-adar.js +47 -30
  185. package/dist/src/link-prediction/adamic-adar.js.map +1 -1
  186. package/dist/src/link-prediction/common-neighbors.d.ts +21 -0
  187. package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -1
  188. package/dist/src/link-prediction/common-neighbors.js +31 -14
  189. package/dist/src/link-prediction/common-neighbors.js.map +1 -1
  190. package/dist/src/link-prediction/index.d.ts.map +1 -1
  191. package/dist/src/optimized/bit-packed.d.ts +193 -0
  192. package/dist/src/optimized/bit-packed.d.ts.map +1 -0
  193. package/dist/src/optimized/bit-packed.js +342 -0
  194. package/dist/src/optimized/bit-packed.js.map +1 -0
  195. package/dist/src/optimized/csr-graph.d.ts +149 -0
  196. package/dist/src/optimized/csr-graph.d.ts.map +1 -0
  197. package/dist/src/optimized/csr-graph.js +404 -0
  198. package/dist/src/optimized/csr-graph.js.map +1 -0
  199. package/dist/src/optimized/direction-optimized-bfs.d.ts +95 -0
  200. package/dist/src/optimized/direction-optimized-bfs.d.ts.map +1 -0
  201. package/dist/src/optimized/direction-optimized-bfs.js +242 -0
  202. package/dist/src/optimized/direction-optimized-bfs.js.map +1 -0
  203. package/dist/src/optimized/graph-adapter.d.ts +111 -0
  204. package/dist/src/optimized/graph-adapter.d.ts.map +1 -0
  205. package/dist/src/optimized/graph-adapter.js +194 -0
  206. package/dist/src/optimized/graph-adapter.js.map +1 -0
  207. package/dist/src/optimized/index.d.ts +14 -0
  208. package/dist/src/optimized/index.d.ts.map +1 -0
  209. package/dist/src/optimized/index.js +30 -0
  210. package/dist/src/optimized/index.js.map +1 -0
  211. package/dist/src/pathfinding/astar.d.ts +25 -9
  212. package/dist/src/pathfinding/astar.d.ts.map +1 -1
  213. package/dist/src/pathfinding/astar.js +25 -10
  214. package/dist/src/pathfinding/astar.js.map +1 -1
  215. package/dist/src/pathfinding/utils.d.ts +15 -6
  216. package/dist/src/pathfinding/utils.d.ts.map +1 -1
  217. package/dist/src/pathfinding/utils.js +19 -7
  218. package/dist/src/pathfinding/utils.js.map +1 -1
  219. package/dist/src/research/grsbm.d.ts +0 -1
  220. package/dist/src/research/grsbm.d.ts.map +1 -1
  221. package/dist/src/research/grsbm.js +28 -23
  222. package/dist/src/research/grsbm.js.map +1 -1
  223. package/dist/src/research/index.d.ts.map +1 -1
  224. package/dist/src/research/index.js.map +1 -1
  225. package/dist/src/research/sync.d.ts +0 -1
  226. package/dist/src/research/sync.d.ts.map +1 -1
  227. package/dist/src/research/sync.js +31 -36
  228. package/dist/src/research/sync.js.map +1 -1
  229. package/dist/src/research/terahac.d.ts +2 -1
  230. package/dist/src/research/terahac.d.ts.map +1 -1
  231. package/dist/src/research/terahac.js +39 -7
  232. package/dist/src/research/terahac.js.map +1 -1
  233. package/dist/src/types/index.d.ts +8 -0
  234. package/dist/src/types/index.d.ts.map +1 -1
  235. package/dist/src/utils/algorithm-utilities.d.ts +2 -0
  236. package/dist/src/utils/algorithm-utilities.d.ts.map +1 -0
  237. package/dist/src/utils/algorithm-utilities.js +2 -0
  238. package/dist/src/utils/algorithm-utilities.js.map +1 -0
  239. package/dist/src/utils/graph-converters.d.ts +110 -0
  240. package/dist/src/utils/graph-converters.d.ts.map +1 -0
  241. package/dist/src/utils/graph-converters.js +227 -0
  242. package/dist/src/utils/graph-converters.js.map +1 -0
  243. package/dist/src/utils/graph-utilities.d.ts +62 -0
  244. package/dist/src/utils/graph-utilities.d.ts.map +1 -0
  245. package/dist/src/utils/graph-utilities.js +148 -0
  246. package/dist/src/utils/graph-utilities.js.map +1 -0
  247. package/dist/src/utils/index.d.ts +5 -0
  248. package/dist/src/utils/index.d.ts.map +1 -0
  249. package/dist/src/utils/index.js +5 -0
  250. package/dist/src/utils/index.js.map +1 -0
  251. package/dist/src/utils/math-utilities.d.ts +63 -0
  252. package/dist/src/utils/math-utilities.d.ts.map +1 -0
  253. package/dist/src/utils/math-utilities.js +132 -0
  254. package/dist/src/utils/math-utilities.js.map +1 -0
  255. package/dist/src/utils/matrix-utilities.d.ts +2 -0
  256. package/dist/src/utils/matrix-utilities.d.ts.map +1 -0
  257. package/dist/src/utils/matrix-utilities.js +2 -0
  258. package/dist/src/utils/matrix-utilities.js.map +1 -0
  259. package/dist/src/utils/optimization-helpers.d.ts +42 -0
  260. package/dist/src/utils/optimization-helpers.d.ts.map +1 -0
  261. package/dist/src/utils/optimization-helpers.js +59 -0
  262. package/dist/src/utils/optimization-helpers.js.map +1 -0
  263. package/dist/src/utils/priorityQueue.d.ts +24 -0
  264. package/dist/src/utils/priorityQueue.d.ts.map +1 -1
  265. package/dist/src/utils/priorityQueue.js +34 -4
  266. package/dist/src/utils/priorityQueue.js.map +1 -1
  267. package/package.json +58 -39
  268. package/src/algorithms/centrality/betweenness.ts +185 -200
  269. package/src/algorithms/centrality/closeness.ts +93 -194
  270. package/src/algorithms/centrality/degree.ts +18 -22
  271. package/src/algorithms/centrality/delta-pagerank-simple.ts +374 -0
  272. package/src/algorithms/centrality/delta-pagerank.ts +458 -0
  273. package/src/algorithms/centrality/eigenvector.ts +14 -15
  274. package/src/algorithms/centrality/hits.ts +17 -17
  275. package/src/algorithms/centrality/index.ts +20 -13
  276. package/src/algorithms/centrality/katz.ts +17 -25
  277. package/src/algorithms/centrality/pagerank.ts +91 -16
  278. package/src/algorithms/community/girvan-newman.ts +90 -86
  279. package/src/algorithms/community/index.ts +6 -5
  280. package/src/algorithms/community/label-propagation.ts +69 -48
  281. package/src/algorithms/community/leiden.ts +88 -65
  282. package/src/algorithms/community/louvain-optimized.ts +474 -0
  283. package/src/algorithms/community/louvain.ts +52 -122
  284. package/src/algorithms/community/modularity-utils.ts +134 -0
  285. package/src/algorithms/components/connected.ts +40 -17
  286. package/src/algorithms/matching/bipartite.ts +24 -53
  287. package/src/algorithms/matching/index.ts +4 -4
  288. package/src/algorithms/matching/isomorphism.ts +53 -23
  289. package/src/algorithms/mst/index.ts +3 -4
  290. package/src/algorithms/mst/kruskal.ts +21 -6
  291. package/src/algorithms/mst/prim.ts +13 -4
  292. package/src/algorithms/shortest-path/bellman-ford.ts +16 -28
  293. package/src/algorithms/shortest-path/bidirectional-dijkstra.ts +248 -0
  294. package/src/algorithms/shortest-path/dijkstra.ts +38 -30
  295. package/src/algorithms/shortest-path/floyd-warshall.ts +21 -4
  296. package/src/algorithms/shortest-path/index.ts +5 -5
  297. package/src/algorithms/traversal/bfs-unified.ts +437 -0
  298. package/src/algorithms/traversal/bfs-variants.ts +520 -0
  299. package/src/algorithms/traversal/bfs.ts +5 -229
  300. package/src/algorithms/traversal/dfs.ts +61 -42
  301. package/src/algorithms/traversal/index.ts +3 -3
  302. package/src/benchmark-all-algorithms.ts +580 -0
  303. package/src/clustering/hierarchical.ts +268 -272
  304. package/src/clustering/index.ts +8 -6
  305. package/src/clustering/k-core.ts +93 -61
  306. package/src/clustering/mcl.ts +53 -23
  307. package/src/clustering/spectral.ts +130 -72
  308. package/src/core/graph.ts +58 -18
  309. package/src/data-structures/index.ts +2 -2
  310. package/src/data-structures/priority-queue.ts +36 -11
  311. package/src/data-structures/union-find.ts +22 -1
  312. package/src/flow/ford-fulkerson.ts +221 -262
  313. package/src/flow/min-cut.ts +59 -51
  314. package/src/index.ts +9 -2
  315. package/src/link-prediction/adamic-adar.ts +75 -74
  316. package/src/link-prediction/common-neighbors.ts +49 -49
  317. package/src/link-prediction/index.ts +1 -1
  318. package/src/optimized/bit-packed.ts +390 -0
  319. package/src/optimized/csr-graph.ts +518 -0
  320. package/src/optimized/direction-optimized-bfs.ts +310 -0
  321. package/src/optimized/graph-adapter.ts +248 -0
  322. package/src/optimized/index.ts +34 -0
  323. package/src/pathfinding/astar.ts +40 -25
  324. package/src/pathfinding/utils.ts +20 -13
  325. package/src/research/grsbm.ts +36 -39
  326. package/src/research/index.ts +4 -4
  327. package/src/research/sync.ts +41 -54
  328. package/src/research/terahac.ts +63 -21
  329. package/src/types/index.ts +8 -0
  330. package/src/utils/algorithm-utilities.ts +2 -0
  331. package/src/utils/graph-converters.ts +269 -0
  332. package/src/utils/graph-utilities.ts +173 -0
  333. package/src/utils/index.ts +4 -0
  334. package/src/utils/math-utilities.ts +149 -0
  335. package/src/utils/matrix-utilities.ts +2 -0
  336. package/src/utils/optimization-helpers.ts +87 -0
  337. package/src/utils/priorityQueue.ts +40 -6
package/README.md CHANGED
@@ -4,18 +4,58 @@
4
4
  [![Coverage Status](https://coveralls.io/repos/github/graphty-org/algorithms/badge.svg)](https://coveralls.io/github/graphty-org/algorithms)
5
5
  [![npm version](https://img.shields.io/npm/v/@graphty/algorithms.svg)](https://www.npmjs.com/package/@graphty/algorithms)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![Examples](https://img.shields.io/badge/demo-github%20pages-blue)](https://graphty-org.github.io/algorithms/)
7
8
 
8
- A comprehensive TypeScript graph algorithms library with 100+ algorithms optimized for browser environments and visualization applications.
9
+ A comprehensive TypeScript graph algorithms library with 98 algorithms optimized for browser environments and visualization applications.
9
10
 
10
11
  ## Features
11
12
 
12
13
  - **TypeScript-first**: Full type safety with comprehensive type definitions
13
14
  - **Browser-optimized**: Designed to run efficiently in web browsers
14
15
  - **Modular**: Import only the algorithms you need
15
- - **Comprehensive**: 100+ graph algorithms including traversal, shortest paths, centrality, clustering, flow, matching, link prediction, and more
16
+ - **Comprehensive**: 98 graph algorithms including traversal, shortest paths, centrality, clustering, flow, matching, link prediction, and more
17
+ - **Interactive Examples**: [Live demos](https://graphty-org.github.io/algorithms/) with visualizations for all algorithms
18
+ - **Performance Analysis**: [Detailed benchmarks](https://graphty-org.github.io/algorithms/benchmarks/) comparing algorithm performance
16
19
  - **Well-tested**: Extensive test suite with high coverage
17
20
  - **Standards-compliant**: Follows conventional commits and semantic versioning
18
21
 
22
+ ## Performance Optimizations
23
+
24
+ The library automatically optimizes performance for large graphs (≥10,000 nodes) using:
25
+
26
+ - **Direction-Optimized BFS**: Dynamically switches between top-down and bottom-up search strategies, providing up to 42x speedup on large graphs
27
+ - **CSR Graph Format**: Compressed Sparse Row format for cache-efficient memory access
28
+ - **Bit-Packed Data Structures**: 8x memory reduction using bit arrays for boolean data
29
+
30
+ These optimizations are applied automatically - no configuration needed! Just use the standard API:
31
+
32
+ ```typescript
33
+ // Automatically uses optimized implementation for large graphs
34
+ const result = breadthFirstSearch(largeGraph, startNode);
35
+ ```
36
+
37
+ All BFS-based algorithms benefit from these optimizations:
38
+
39
+ - `breadthFirstSearch`, `shortestPathBFS`, `singleSourceShortestPathBFS`
40
+ - `betweennessCentrality`, `closenessCentrality`
41
+ - Connected component algorithms
42
+
43
+ ### Performance Benchmarks
44
+
45
+ | Graph Size | Standard BFS | Optimized BFS | Speedup |
46
+ | ---------- | ------------ | ------------- | ------- |
47
+ | 10K nodes | 4.40ms | 6.34ms | 0.69x |
48
+ | 50K nodes | 158.64ms | 44.27ms | 3.58x |
49
+ | 100K nodes | 5,370ms | 126ms | 42.58x |
50
+
51
+ _Note: Optimizations activate automatically for graphs ≥10K nodes to avoid conversion overhead on smaller graphs._
52
+
53
+ ### Learn More
54
+
55
+ - 📖 [Performance Guide](docs/PERFORMANCE_GUIDE.md) - Detailed optimization explanations
56
+ - 🔄 [Migration Guide](docs/MIGRATION_GUIDE.md) - Upgrading from older versions
57
+ - 💾 [Memory vs Speed Tradeoffs](docs/PERFORMANCE_GUIDE.md#memory-vs-speed-tradeoffs) - Making the right choices
58
+
19
59
  ## Installation
20
60
 
21
61
  ```bash
@@ -25,30 +65,30 @@ npm install @graphty/algorithms
25
65
  ## Quick Start
26
66
 
27
67
  ```typescript
28
- import { Graph, breadthFirstSearch, dijkstra } from '@graphty/algorithms';
68
+ import { Graph, breadthFirstSearch, dijkstra } from "@graphty/algorithms";
29
69
 
30
70
  // Create a new graph
31
71
  const graph = new Graph();
32
72
 
33
73
  // Add nodes and edges
34
- graph.addNode('A');
35
- graph.addNode('B');
36
- graph.addNode('C');
37
- graph.addEdge('A', 'B', 1); // source, target, weight
38
- graph.addEdge('B', 'C', 2);
74
+ graph.addNode("A");
75
+ graph.addNode("B");
76
+ graph.addNode("C");
77
+ graph.addEdge("A", "B", 1); // source, target, weight
78
+ graph.addEdge("B", "C", 2);
39
79
 
40
80
  // Basic graph operations
41
81
  console.log(graph.nodeCount); // 3
42
82
  console.log(graph.totalEdgeCount); // 2
43
- console.log(graph.hasEdge('A', 'B')); // true
83
+ console.log(graph.hasEdge("A", "B")); // true
44
84
 
45
85
  // Run algorithms
46
- const traversal = breadthFirstSearch(graph, 'A');
86
+ const traversal = breadthFirstSearch(graph, "A");
47
87
  console.log(traversal.order); // ['A', 'B', 'C']
48
88
 
49
- const shortestPaths = dijkstra(graph, 'A');
89
+ const shortestPaths = dijkstra(graph, "A");
50
90
  // Get distance to C
51
- const pathToC = shortestPaths.get('C');
91
+ const pathToC = shortestPaths.get("C");
52
92
  console.log(pathToC?.distance); // 3
53
93
  ```
54
94
 
@@ -60,7 +100,7 @@ The core data structure for representing graphs.
60
100
 
61
101
  ```typescript
62
102
  class Graph {
63
- constructor(config?: Partial<GraphConfig>)
103
+ constructor(config?: Partial<GraphConfig>);
64
104
  }
65
105
  ```
66
106
 
@@ -68,9 +108,9 @@ class Graph {
68
108
 
69
109
  ```typescript
70
110
  interface GraphConfig {
71
- directed: boolean; // Default: false
72
- allowSelfLoops: boolean; // Default: false
73
- allowParallelEdges: boolean; // Default: false
111
+ directed: boolean; // Default: false
112
+ allowSelfLoops: boolean; // Default: false
113
+ allowParallelEdges: boolean; // Default: false
74
114
  }
75
115
  ```
76
116
 
@@ -98,9 +138,9 @@ graph.nodes(): IterableIterator<Node>
98
138
  ```typescript
99
139
  // Add an edge with optional weight and data
100
140
  graph.addEdge(
101
- source: NodeId,
102
- target: NodeId,
103
- weight?: number,
141
+ source: NodeId,
142
+ target: NodeId,
143
+ weight?: number,
104
144
  data?: Record<string, unknown>
105
145
  ): void
106
146
 
@@ -167,6 +207,9 @@ graph.clone(): Graph
167
207
 
168
208
  // Clear all nodes and edges
169
209
  graph.clear(): void
210
+
211
+ // Get a copy of the graph configuration
212
+ graph.getConfig(): GraphConfig
170
213
  ```
171
214
 
172
215
  ### Traversal Algorithms
@@ -178,18 +221,24 @@ import { breadthFirstSearch, shortestPathBFS, singleSourceShortestPathBFS, isBip
178
221
 
179
222
  // Basic BFS traversal
180
223
  const result = breadthFirstSearch(graph, startNode, {
181
- maxDepth?: number, // Optional: limit traversal depth
182
- visitCallback?: (node: NodeId, depth: number) => void
224
+ targetNode?: NodeId, // Optional: stop when target is reached
225
+ visitCallback?: (node: NodeId, level: number) => void
183
226
  });
184
- // Returns: TraversalResult { visited: Set<NodeId>, order: NodeId[], tree?: Map<NodeId, NodeId> }
227
+ // Returns: TraversalResult { visited: Set<NodeId>, order: NodeId[], tree?: Map<NodeId, NodeId | null> }
228
+
229
+ // Note: For graphs with ≥10K nodes, BFS automatically uses:
230
+ // - Direction-Optimized BFS (switches between top-down/bottom-up)
231
+ // - CSR graph format for cache efficiency
232
+ // - Bit-packed data structures for memory efficiency
185
233
 
186
234
  // Find shortest path between two nodes (unweighted)
187
235
  const path = shortestPathBFS(graph, source, target);
188
- // Returns: NodeId[] | null
236
+ // Returns: ShortestPathResult | null
237
+ // ShortestPathResult = { distance: number, path: NodeId[], predecessor: Map<NodeId, NodeId | null> }
189
238
 
190
239
  // Find all shortest paths from a source
191
240
  const paths = singleSourceShortestPathBFS(graph, source);
192
- // Returns: Map<NodeId, NodeId[]>
241
+ // Returns: Map<NodeId, ShortestPathResult>
193
242
 
194
243
  // Check if graph is bipartite
195
244
  const bipartite = isBipartite(graph);
@@ -203,8 +252,10 @@ import { depthFirstSearch, topologicalSort, hasCycleDFS, findStronglyConnectedCo
203
252
 
204
253
  // Basic DFS traversal
205
254
  const result = depthFirstSearch(graph, startNode, {
206
- previsitCallback?: (node: NodeId) => void,
207
- postvisitCallback?: (node: NodeId) => void
255
+ targetNode?: NodeId, // Optional: stop when target is reached
256
+ visitCallback?: (node: NodeId, level: number) => void,
257
+ recursive?: boolean, // Use recursive implementation (default: false)
258
+ preOrder?: boolean // Visit nodes in pre-order (default: true)
208
259
  });
209
260
  // Returns: TraversalResult
210
261
 
@@ -226,37 +277,42 @@ const sccs = findStronglyConnectedComponents(graph);
226
277
  #### Dijkstra's Algorithm
227
278
 
228
279
  ```typescript
229
- import { dijkstra, dijkstraPath, singleSourceShortestPath, allPairsShortestPath } from '@graphty/algorithms';
280
+ import {
281
+ dijkstra,
282
+ dijkstraPath,
283
+ singleSourceShortestPath,
284
+ allPairsShortestPath
285
+ } from '@graphty/algorithms'
230
286
 
231
287
  // Single-source shortest paths
232
288
  const result = dijkstra(graph, source, {
233
- target?: NodeId // Optional: stop when target is reached
234
- });
289
+ target?: NodeId // Optional: stop when target is reached
290
+ })
235
291
  // Returns: Map<NodeId, ShortestPathResult>
236
292
  // ShortestPathResult = { distance: number, path: NodeId[], predecessor: Map<NodeId, NodeId | null> }
237
293
 
238
294
  // Get specific path
239
- const path = dijkstraPath(graph, source, target);
295
+ const path = dijkstraPath(graph, source, target)
240
296
  // Returns: ShortestPathResult | null
241
297
 
242
298
  // All shortest paths from source
243
- const paths = singleSourceShortestPath(graph, source);
299
+ const paths = singleSourceShortestPath(graph, source)
244
300
  // Returns: Map<NodeId, ShortestPathResult>
245
301
 
246
302
  // All pairs shortest paths
247
- const allPairs = allPairsShortestPath(graph);
303
+ const allPairs = allPairsShortestPath(graph)
248
304
  // Returns: Map<NodeId, Map<NodeId, ShortestPathResult>>
249
305
  ```
250
306
 
251
307
  #### Bellman-Ford Algorithm
252
308
 
253
309
  ```typescript
254
- import { bellmanFord, bellmanFordPath, hasNegativeCycle } from '@graphty/algorithms';
310
+ import { bellmanFord, bellmanFordPath, hasNegativeCycle } from "@graphty/algorithms";
255
311
 
256
312
  // Single-source shortest paths (handles negative weights)
257
313
  const result = bellmanFord(graph, source);
258
- // Returns: BellmanFordResult {
259
- // distances: Map<NodeId, number>,
314
+ // Returns: BellmanFordResult {
315
+ // distances: Map<NodeId, number>,
260
316
  // predecessors: Map<NodeId, NodeId | null>,
261
317
  // hasNegativeCycle: boolean,
262
318
  // negativeCycleNodes?: Set<NodeId>
@@ -274,7 +330,7 @@ const result = hasNegativeCycle(graph);
274
330
  #### Floyd-Warshall Algorithm
275
331
 
276
332
  ```typescript
277
- import { floydWarshall, floydWarshallPath, transitiveClosure } from '@graphty/algorithms';
333
+ import { floydWarshall, floydWarshallPath, transitiveClosure } from "@graphty/algorithms";
278
334
 
279
335
  // All pairs shortest paths
280
336
  const result = floydWarshall(graph);
@@ -294,30 +350,30 @@ const closure = transitiveClosure(graph);
294
350
  #### Degree Centrality
295
351
 
296
352
  ```typescript
297
- import { degreeCentrality, nodeDegreeCentrality } from '@graphty/algorithms';
353
+ import { degreeCentrality, nodeDegreeCentrality } from "@graphty/algorithms";
298
354
 
299
355
  // Calculate for all nodes
300
356
  const centralities = degreeCentrality(graph, {
301
- normalized?: boolean, // Default: false
302
- weight?: string // Optional: edge property for weighted degree
357
+ normalized: boolean, // Default: false
358
+ weight: string, // Optional: edge property for weighted degree
303
359
  });
304
360
  // Returns: CentralityResult (Record<string, number>)
305
361
 
306
362
  // Calculate for single node
307
- const centrality = nodeDegreeCentrality(graph, nodeId, { normalized?: boolean });
363
+ const centrality = nodeDegreeCentrality(graph, nodeId, { normalized: boolean });
308
364
  // Returns: number
309
365
  ```
310
366
 
311
367
  #### Betweenness Centrality
312
368
 
313
369
  ```typescript
314
- import { betweennessCentrality, nodeBetweennessCentrality, edgeBetweennessCentrality } from '@graphty/algorithms';
370
+ import { betweennessCentrality, nodeBetweennessCentrality, edgeBetweennessCentrality } from "@graphty/algorithms";
315
371
 
316
372
  // Node betweenness for all nodes
317
373
  const centralities = betweennessCentrality(graph, {
318
- normalized?: boolean, // Default: false
319
- weight?: string, // Optional: use weighted shortest paths
320
- endpoints?: boolean // Default: false, include endpoints in paths
374
+ normalized: boolean, // Default: false
375
+ weight: string, // Optional: use weighted shortest paths
376
+ endpoints: boolean, // Default: false, include endpoints in paths
321
377
  });
322
378
  // Returns: CentralityResult (Record<string, number>)
323
379
 
@@ -333,38 +389,47 @@ const edgeCentralities = edgeBetweennessCentrality(graph, options);
333
389
  #### Closeness Centrality
334
390
 
335
391
  ```typescript
336
- import { closenessCentrality, nodeClosenessCentrality, weightedClosenessCentrality } from '@graphty/algorithms';
392
+ import { closenessCentrality, nodeClosenessCentrality, weightedClosenessCentrality } from "@graphty/algorithms";
337
393
 
338
394
  // Closeness for all nodes
339
395
  const centralities = closenessCentrality(graph, {
340
- normalized?: boolean // Default: false
396
+ normalized: boolean, // Default: false
341
397
  });
342
398
  // Returns: CentralityResult (Record<string, number>)
343
399
 
344
400
  // Single node closeness
345
- const centrality = nodeClosenessCentrality(graph, nodeId, { normalized?: boolean });
401
+ const centrality = nodeClosenessCentrality(graph, nodeId, {
402
+ normalized: boolean,
403
+ });
346
404
  // Returns: number
347
405
 
348
406
  // Weighted closeness
349
407
  const centralities = weightedClosenessCentrality(graph, {
350
- normalized?: boolean,
351
- weight?: string // Edge property for weights
408
+ normalized: boolean,
409
+ weight: string, // Edge property for weights
352
410
  });
353
411
  // Returns: CentralityResult (Record<string, number>)
412
+
413
+ // Single node weighted closeness
414
+ const centrality = nodeWeightedClosenessCentrality(graph, nodeId, {
415
+ normalized: boolean,
416
+ weight: string, // Edge property for weights
417
+ });
418
+ // Returns: number
354
419
  ```
355
420
 
356
421
  #### PageRank
357
422
 
358
423
  ```typescript
359
- import { pageRank, personalizedPageRank, topPageRankNodes } from '@graphty/algorithms';
424
+ import { pageRank, personalizedPageRank, topPageRankNodes } from "@graphty/algorithms";
360
425
 
361
426
  // Standard PageRank
362
427
  const result = pageRank(graph, {
363
- dampingFactor?: number, // Default: 0.85
364
- maxIterations?: number, // Default: 100
365
- tolerance?: number, // Default: 1e-6
366
- initialRanks?: Record<string, number>,
367
- personalization?: Record<string, number>
428
+ dampingFactor: number, // Default: 0.85
429
+ maxIterations: number, // Default: 100
430
+ tolerance: number, // Default: 1e-6
431
+ initialRanks: Record<string, number>,
432
+ personalization: Record<string, number>,
368
433
  });
369
434
  // Returns: { ranks: Record<string, number>, iterations: number, converged: boolean }
370
435
 
@@ -376,17 +441,21 @@ const ranks = personalizedPageRank(graph, personalization, options);
376
441
  // Get top N nodes by PageRank
377
442
  const topNodes = topPageRankNodes(graph, n, options);
378
443
  // Returns: Array<{ node: NodeId, rank: number }>
444
+
445
+ // Alternative PageRank that returns CentralityResult format
446
+ const centralities = pageRankCentrality(graph, options);
447
+ // Returns: CentralityResult (Record<string, number>)
379
448
  ```
380
449
 
381
450
  #### Eigenvector Centrality
382
451
 
383
452
  ```typescript
384
- import { eigenvectorCentrality, nodeEigenvectorCentrality } from '@graphty/algorithms';
453
+ import { eigenvectorCentrality, nodeEigenvectorCentrality } from "@graphty/algorithms";
385
454
 
386
455
  // Calculate eigenvector centrality for all nodes
387
456
  const centralities = eigenvectorCentrality(graph, {
388
- maxIterations?: number, // Default: 100
389
- tolerance?: number // Default: 1e-6
457
+ maxIterations: number, // Default: 100
458
+ tolerance: number, // Default: 1e-6
390
459
  });
391
460
  // Returns: CentralityResult (Record<string, number>)
392
461
 
@@ -398,15 +467,15 @@ const centrality = nodeEigenvectorCentrality(graph, nodeId, options);
398
467
  #### Katz Centrality
399
468
 
400
469
  ```typescript
401
- import { katzCentrality, nodeKatzCentrality } from '@graphty/algorithms';
470
+ import { katzCentrality, nodeKatzCentrality } from "@graphty/algorithms";
402
471
 
403
472
  // Calculate Katz centrality for all nodes
404
473
  const centralities = katzCentrality(graph, {
405
- alpha?: number, // Attenuation factor (default: 0.1)
406
- beta?: number, // Weight for direct connections (default: 1.0)
407
- maxIterations?: number, // Default: 100
408
- tolerance?: number, // Default: 1e-6
409
- normalized?: boolean // Default: true
474
+ alpha: number, // Attenuation factor (default: 0.1)
475
+ beta: number, // Weight for direct connections (default: 1.0)
476
+ maxIterations: number, // Default: 100
477
+ tolerance: number, // Default: 1e-6
478
+ normalized: boolean, // Default: true
410
479
  });
411
480
  // Returns: CentralityResult (Record<string, number>)
412
481
 
@@ -418,12 +487,12 @@ const centrality = nodeKatzCentrality(graph, nodeId, options);
418
487
  #### HITS Algorithm
419
488
 
420
489
  ```typescript
421
- import { hits, nodeHITS } from '@graphty/algorithms';
490
+ import { hits, nodeHITS } from "@graphty/algorithms";
422
491
 
423
492
  // Calculate hub and authority scores
424
493
  const result = hits(graph, {
425
- maxIterations?: number, // Default: 100
426
- tolerance?: number // Default: 1e-6
494
+ maxIterations: number, // Default: 100
495
+ tolerance: number, // Default: 1e-6
427
496
  });
428
497
  // Returns: HITSResult { hubs: CentralityResult, authorities: CentralityResult }
429
498
 
@@ -437,13 +506,13 @@ const scores = nodeHITS(graph, nodeId, options);
437
506
  #### Basic Component Operations
438
507
 
439
508
  ```typescript
440
- import {
441
- connectedComponents,
442
- isConnected,
443
- numberOfConnectedComponents,
444
- largestConnectedComponent,
445
- getConnectedComponent
446
- } from '@graphty/algorithms';
509
+ import {
510
+ connectedComponents,
511
+ isConnected,
512
+ numberOfConnectedComponents,
513
+ largestConnectedComponent,
514
+ getConnectedComponent,
515
+ } from "@graphty/algorithms";
447
516
 
448
517
  // Find all components
449
518
  const components = connectedComponents(graph);
@@ -469,12 +538,12 @@ const component = getConnectedComponent(graph, nodeId);
469
538
  #### Strongly Connected Components
470
539
 
471
540
  ```typescript
472
- import {
473
- stronglyConnectedComponents,
474
- findStronglyConnectedComponents,
475
- isStronglyConnected,
476
- condensationGraph
477
- } from '@graphty/algorithms';
541
+ import {
542
+ stronglyConnectedComponents,
543
+ findStronglyConnectedComponents,
544
+ isStronglyConnected,
545
+ condensationGraph,
546
+ } from "@graphty/algorithms";
478
547
 
479
548
  // Find SCCs using Tarjan's algorithm
480
549
  const sccs = stronglyConnectedComponents(graph);
@@ -500,7 +569,7 @@ const components = connectedComponentsDFS(graph);
500
569
  #### Weakly Connected Components
501
570
 
502
571
  ```typescript
503
- import { weaklyConnectedComponents, isWeaklyConnected } from '@graphty/algorithms';
572
+ import { weaklyConnectedComponents, isWeaklyConnected } from "@graphty/algorithms";
504
573
 
505
574
  // Find WCCs (ignoring edge direction)
506
575
  const wccs = weaklyConnectedComponents(graph);
@@ -518,7 +587,7 @@ const weaklyConnected = isWeaklyConnected(graph);
518
587
  Min-heap implementation used internally by algorithms.
519
588
 
520
589
  ```typescript
521
- import { PriorityQueue } from '@graphty/algorithms';
590
+ import { PriorityQueue } from "@graphty/algorithms";
522
591
 
523
592
  const pq = new PriorityQueue<T>((a, b) => a.priority - b.priority);
524
593
 
@@ -535,7 +604,7 @@ pq.clear();
535
604
  Efficient data structure for tracking connected components.
536
605
 
537
606
  ```typescript
538
- import { UnionFind } from '@graphty/algorithms';
607
+ import { UnionFind } from "@graphty/algorithms";
539
608
 
540
609
  const uf = new UnionFind<T>();
541
610
 
@@ -552,7 +621,7 @@ uf.numberOfSets;
552
621
  #### Kruskal's Algorithm
553
622
 
554
623
  ```typescript
555
- import { kruskalMST, minimumSpanningTree } from '@graphty/algorithms';
624
+ import { kruskalMST, minimumSpanningTree } from "@graphty/algorithms";
556
625
 
557
626
  // Find MST using Kruskal's algorithm
558
627
  const mst = kruskalMST(graph);
@@ -577,12 +646,12 @@ const mst = primMST(graph, startNode?);
577
646
  #### Louvain Method
578
647
 
579
648
  ```typescript
580
- import { louvain } from '@graphty/algorithms';
649
+ import { louvain } from "@graphty/algorithms";
581
650
 
582
651
  // Detect communities using Louvain method
583
652
  const communities = louvain(graph, {
584
- resolution?: number, // Default: 1.0
585
- randomSeed?: number
653
+ resolution: number, // Default: 1.0
654
+ randomSeed: number,
586
655
  });
587
656
  // Returns: { communities: Map<NodeId, number>, modularity: number }
588
657
  ```
@@ -590,13 +659,13 @@ const communities = louvain(graph, {
590
659
  #### Leiden Algorithm
591
660
 
592
661
  ```typescript
593
- import { leiden } from '@graphty/algorithms';
662
+ import { leiden } from "@graphty/algorithms";
594
663
 
595
664
  // Improved community detection
596
665
  const communities = leiden(graph, {
597
- resolution?: number, // Default: 1.0
598
- iterations?: number, // Default: 10
599
- randomSeed?: number
666
+ resolution: number, // Default: 1.0
667
+ iterations: number, // Default: 10
668
+ randomSeed: number,
600
669
  });
601
670
  // Returns: { communities: Map<NodeId, number>, modularity: number }
602
671
  ```
@@ -604,11 +673,11 @@ const communities = leiden(graph, {
604
673
  #### Label Propagation
605
674
 
606
675
  ```typescript
607
- import { labelPropagation, labelPropagationAsync, labelPropagationSemiSupervised } from '@graphty/algorithms';
676
+ import { labelPropagation, labelPropagationAsync, labelPropagationSemiSupervised } from "@graphty/algorithms";
608
677
 
609
678
  // Basic label propagation
610
679
  const labels = labelPropagation(graph, {
611
- maxIterations?: number // Default: 100
680
+ maxIterations: number, // Default: 100
612
681
  });
613
682
  // Returns: Map<NodeId, number>
614
683
 
@@ -622,32 +691,30 @@ const labels = labelPropagationSemiSupervised(graph, seedLabels, options);
622
691
  #### Girvan-Newman Algorithm
623
692
 
624
693
  ```typescript
625
- import { girvanNewman } from '@graphty/algorithms';
694
+ import { girvanNewman } from "@graphty/algorithms";
626
695
 
627
696
  // Edge betweenness based community detection
628
697
  const dendrogram = girvanNewman(graph, {
629
- targetCommunities?: number // Stop at this many communities
698
+ targetCommunities: number, // Stop at this many communities
630
699
  });
631
700
  // Returns: { levels: Array<{ modularity: number, communities: NodeId[][] }> }
632
701
  ```
633
702
 
634
703
  ### Pathfinding Algorithms
635
704
 
636
- #### A* Algorithm
705
+ #### A\* Algorithm
637
706
 
638
707
  ```typescript
639
- import { astar, astarWithDetails, heuristics } from '@graphty/algorithms';
708
+ import { astar } from "@graphty/algorithms";
640
709
 
641
710
  // A* pathfinding with heuristic
642
- const path = astar(graph, start, goal, {
643
- heuristic: heuristics.euclidean, // or manhattan, chebyshev, zero
644
- weight?: (edge: Edge) => number
645
- });
646
- // Returns: { path: NodeId[], cost: number } | null
647
-
648
- // A* with search details
649
- const result = astarWithDetails(graph, start, goal, options);
650
- // Returns: { path: NodeId[], cost: number, explored: Set<NodeId>, parent: Map<NodeId, NodeId> } | null
711
+ const path = astar(
712
+ graph, // Map<T, Map<T, number>> adjacency list
713
+ start,
714
+ goal,
715
+ heuristic, // (node: T, goal: T) => number
716
+ );
717
+ // Returns: { path: T[], cost: number } | null
651
718
  ```
652
719
 
653
720
  ### Flow Algorithms
@@ -694,7 +761,7 @@ const cut = kargerMinCut(graph, iterations?);
694
761
  #### Hierarchical Clustering
695
762
 
696
763
  ```typescript
697
- import { hierarchicalClustering, cutDendrogram, cutDendrogramKClusters } from '@graphty/algorithms';
764
+ import { hierarchicalClustering, cutDendrogram, cutDendrogramKClusters } from "@graphty/algorithms";
698
765
 
699
766
  // Agglomerative clustering
700
767
  const result = hierarchicalClustering(graph, linkage);
@@ -714,7 +781,7 @@ const clusters = cutDendrogramKClusters(result.root, k);
714
781
  #### K-Core Decomposition
715
782
 
716
783
  ```typescript
717
- import { kCoreDecomposition, getKCore, kTruss, degeneracyOrdering } from '@graphty/algorithms';
784
+ import { kCoreDecomposition, getKCore, kTruss, degeneracyOrdering } from "@graphty/algorithms";
718
785
 
719
786
  // Find all k-cores
720
787
  const result = kCoreDecomposition(graph);
@@ -737,14 +804,14 @@ const ordering = degeneracyOrdering(graph);
737
804
  #### Spectral Clustering
738
805
 
739
806
  ```typescript
740
- import { spectralClustering } from '@graphty/algorithms';
807
+ import { spectralClustering } from "@graphty/algorithms";
741
808
 
742
809
  // Spectral clustering using graph Laplacian
743
810
  const result = spectralClustering(graph, {
744
- k: number, // Number of clusters
745
- laplacianType?: 'unnormalized' | 'normalized' | 'randomWalk', // Default: 'normalized'
746
- maxIterations?: number, // Default: 100
747
- tolerance?: number // Default: 1e-4
811
+ k: number, // Number of clusters
812
+ laplacianType: "unnormalized" | "normalized" | "randomWalk", // Default: 'normalized'
813
+ maxIterations: number, // Default: 100
814
+ tolerance: number, // Default: 1e-4
748
815
  });
749
816
  // Returns: SpectralClusteringResult { communities: NodeId[][], clusterAssignments: Map<NodeId, number> }
750
817
  ```
@@ -752,16 +819,20 @@ const result = spectralClustering(graph, {
752
819
  #### Markov Clustering (MCL)
753
820
 
754
821
  ```typescript
755
- import { markovClustering } from '@graphty/algorithms';
822
+ import { markovClustering, calculateMCLModularity } from "@graphty/algorithms";
756
823
 
757
824
  // MCL algorithm for network clustering
758
825
  const result = markovClustering(graph, {
759
- expansion?: number, // Expansion parameter (default: 2)
760
- inflation?: number, // Inflation parameter (default: 2)
761
- maxIterations?: number, // Default: 100
762
- tolerance?: number // Default: 1e-6
826
+ expansion: number, // Expansion parameter (default: 2)
827
+ inflation: number, // Inflation parameter (default: 2)
828
+ maxIterations: number, // Default: 100
829
+ tolerance: number, // Default: 1e-6
763
830
  });
764
831
  // Returns: MCLResult { communities: NodeId[][], attractors: Set<NodeId>, iterations: number, converged: boolean }
832
+
833
+ // Calculate modularity of MCL clustering result
834
+ const modularity = calculateMCLModularity(graph, result.communities);
835
+ // Returns: number
765
836
  ```
766
837
 
767
838
  ### Matching Algorithms
@@ -769,12 +840,12 @@ const result = markovClustering(graph, {
769
840
  #### Bipartite Matching
770
841
 
771
842
  ```typescript
772
- import { maximumBipartiteMatching, greedyBipartiteMatching, bipartitePartition } from '@graphty/algorithms';
843
+ import { maximumBipartiteMatching, greedyBipartiteMatching, bipartitePartition } from "@graphty/algorithms";
773
844
 
774
845
  // Maximum bipartite matching (Hungarian algorithm)
775
846
  const matching = maximumBipartiteMatching(graph, {
776
- leftNodes?: Set<NodeId>, // Optional: specify left partition
777
- rightNodes?: Set<NodeId>, // Optional: specify right partition
847
+ leftNodes: Set<NodeId>, // Optional: specify left partition
848
+ rightNodes: Set<NodeId>, // Optional: specify right partition
778
849
  });
779
850
  // Returns: BipartiteMatchingResult { matching: Map<NodeId, NodeId>, size: number }
780
851
 
@@ -789,13 +860,13 @@ const partition = bipartitePartition(graph);
789
860
  #### Graph Isomorphism
790
861
 
791
862
  ```typescript
792
- import { isGraphIsomorphic, findAllIsomorphisms } from '@graphty/algorithms';
863
+ import { isGraphIsomorphic, findAllIsomorphisms } from "@graphty/algorithms";
793
864
 
794
865
  // Check if two graphs are isomorphic
795
866
  const result = isGraphIsomorphic(graph1, graph2, {
796
- nodeMatch?: (node1: NodeId, node2: NodeId, g1: Graph, g2: Graph) => boolean,
797
- edgeMatch?: (edge1: [NodeId, NodeId], edge2: [NodeId, NodeId], g1: Graph, g2: Graph) => boolean,
798
- findAllMappings?: boolean // Find all possible isomorphisms
867
+ nodeMatch: (node1: NodeId, node2: NodeId, g1: Graph, g2: Graph) => boolean,
868
+ edgeMatch: (edge1: [NodeId, NodeId], edge2: [NodeId, NodeId], g1: Graph, g2: Graph) => boolean,
869
+ findAllMappings: boolean, // Find all possible isomorphisms
799
870
  });
800
871
  // Returns: IsomorphismResult { isIsomorphic: boolean, mapping?: Map<NodeId, NodeId> }
801
872
 
@@ -809,7 +880,7 @@ const mappings = findAllIsomorphisms(graph1, graph2, options);
809
880
  #### Common Neighbors
810
881
 
811
882
  ```typescript
812
- import { commonNeighborsScore, commonNeighborsPrediction, commonNeighborsForPairs } from '@graphty/algorithms';
883
+ import { commonNeighborsScore, commonNeighborsPrediction, commonNeighborsForPairs } from "@graphty/algorithms";
813
884
 
814
885
  // Score for a specific pair
815
886
  const score = commonNeighborsScore(graph, node1, node2);
@@ -817,9 +888,9 @@ const score = commonNeighborsScore(graph, node1, node2);
817
888
 
818
889
  // Predict links for all non-connected pairs
819
890
  const predictions = commonNeighborsPrediction(graph, {
820
- directed?: boolean, // Consider direction
821
- includeExisting?: boolean, // Include existing edges
822
- topK?: number // Return only top K predictions
891
+ directed: boolean, // Consider direction
892
+ includeExisting: boolean, // Include existing edges
893
+ topK: number, // Return only top K predictions
823
894
  });
824
895
  // Returns: LinkPredictionScore[]
825
896
 
@@ -832,14 +903,14 @@ const evaluation = evaluateCommonNeighbors(graph, testEdges);
832
903
  // Returns: { precision, recall, f1Score }
833
904
 
834
905
  // Get top candidates for a node
835
- const candidates = getTopCandidatesForNode(graph, nodeId, { topK?: number });
906
+ const candidates = getTopCandidatesForNode(graph, nodeId, { topK: number });
836
907
  // Returns: LinkPredictionScore[]
837
908
  ```
838
909
 
839
910
  #### Adamic-Adar Index
840
911
 
841
912
  ```typescript
842
- import { adamicAdarScore, adamicAdarPrediction, adamicAdarForPairs } from '@graphty/algorithms';
913
+ import { adamicAdarScore, adamicAdarPrediction, adamicAdarForPairs } from "@graphty/algorithms";
843
914
 
844
915
  // Adamic-Adar score for a pair (weighted by neighbor degrees)
845
916
  const score = adamicAdarScore(graph, node1, node2);
@@ -847,9 +918,9 @@ const score = adamicAdarScore(graph, node1, node2);
847
918
 
848
919
  // Predict links using Adamic-Adar
849
920
  const predictions = adamicAdarPrediction(graph, {
850
- directed?: boolean,
851
- includeExisting?: boolean,
852
- topK?: number
921
+ directed: boolean,
922
+ includeExisting: boolean,
923
+ topK: number,
853
924
  });
854
925
  // Returns: LinkPredictionScore[]
855
926
 
@@ -866,7 +937,9 @@ const evaluation = evaluateAdamicAdar(graph, testEdges);
866
937
  // Returns: { precision, recall, f1Score }
867
938
 
868
939
  // Get top candidates for a node
869
- const candidates = getTopAdamicAdarCandidatesForNode(graph, nodeId, { topK?: number });
940
+ const candidates = getTopAdamicAdarCandidatesForNode(graph, nodeId, {
941
+ topK: number,
942
+ });
870
943
  // Returns: LinkPredictionScore[]
871
944
  ```
872
945
 
@@ -877,18 +950,18 @@ Cutting-edge graph algorithms based on recent research.
877
950
  #### SynC - Synergistic Deep Graph Clustering
878
951
 
879
952
  ```typescript
880
- import { syncClustering } from '@graphty/algorithms';
953
+ import { syncClustering } from "@graphty/algorithms";
881
954
 
882
955
  // Deep learning based clustering
883
956
  const result = syncClustering(graph, {
884
- k: number, // Number of clusters
885
- maxIterations?: number, // Default: 100
886
- learningRate?: number, // Default: 0.01
887
- hiddenDim?: number, // Default: 64
888
- randomSeed?: number
957
+ k: number, // Number of clusters
958
+ maxIterations: number, // Default: 100
959
+ learningRate: number, // Default: 0.01
960
+ hiddenDim: number, // Default: 64
961
+ randomSeed: number,
889
962
  });
890
- // Returns: SynCResult {
891
- // communities: NodeId[][],
963
+ // Returns: SynCResult {
964
+ // communities: NodeId[][],
892
965
  // clusterAssignments: Map<NodeId, number>,
893
966
  // embeddings: Map<NodeId, number[]>,
894
967
  // iterations: number,
@@ -899,15 +972,15 @@ const result = syncClustering(graph, {
899
972
  #### TeraHAC - Scalable Hierarchical Agglomerative Clustering
900
973
 
901
974
  ```typescript
902
- import { teraHAC } from '@graphty/algorithms';
975
+ import { teraHAC } from "@graphty/algorithms";
903
976
 
904
977
  // Scalable hierarchical clustering
905
978
  const result = teraHAC(graph, {
906
- linkage?: 'single' | 'complete' | 'average', // Default: 'average'
907
- k?: number, // Target number of clusters
908
- threshold?: number, // Distance threshold for merging
909
- sampleSize?: number, // Default: 1000
910
- randomSeed?: number
979
+ linkage: "single" | "complete" | "average", // Default: 'average'
980
+ k: number, // Target number of clusters
981
+ threshold: number, // Distance threshold for merging
982
+ sampleSize: number, // Default: 1000
983
+ randomSeed: number,
911
984
  });
912
985
  // Returns: TeraHACResult {
913
986
  // root: TeraHACClusterNode,
@@ -920,14 +993,14 @@ const result = teraHAC(graph, {
920
993
  #### GRSBM - Greedy Recursive Spectral Bisection with Modularity
921
994
 
922
995
  ```typescript
923
- import { grsbm } from '@graphty/algorithms';
996
+ import { grsbm } from "@graphty/algorithms";
924
997
 
925
998
  // Explainable community detection
926
999
  const result = grsbm(graph, {
927
- minClusterSize?: number, // Default: 5
928
- maxDepth?: number, // Default: 10
929
- modularityThreshold?: number, // Default: 0.1
930
- explainClusters?: boolean // Default: true
1000
+ minClusterSize: number, // Default: 5
1001
+ maxDepth: number, // Default: 10
1002
+ modularityThreshold: number, // Default: 0.1
1003
+ explainClusters: boolean, // Default: true
931
1004
  });
932
1005
  // Returns: GRSBMResult {
933
1006
  // clusters: GRSBMCluster[], // Each cluster has id, nodes, modularity, explanation
@@ -941,7 +1014,7 @@ const result = grsbm(graph, {
941
1014
  ### Available Algorithms by Category:
942
1015
 
943
1016
  - **Traversal**: BFS, DFS, Topological Sort, Cycle Detection, Bipartite Check
944
- - **Shortest Path**: Dijkstra, Bellman-Ford, Floyd-Warshall, A*
1017
+ - **Shortest Path**: Dijkstra, Bellman-Ford, Floyd-Warshall, A\*
945
1018
  - **Centrality**: Degree, Betweenness, Closeness, PageRank, Eigenvector, Katz, HITS
946
1019
  - **Components**: Connected, Strongly Connected, Weakly Connected, Condensation Graph
947
1020
  - **Community Detection**: Louvain, Leiden, Label Propagation, Girvan-Newman
@@ -952,11 +1025,18 @@ const result = grsbm(graph, {
952
1025
  - **Link Prediction**: Common Neighbors, Adamic-Adar
953
1026
  - **Research Algorithms**: SynC, TeraHAC, GRSBM
954
1027
 
955
- ## Examples
1028
+ ## Interactive Examples
1029
+
1030
+ Try out all algorithms with interactive visualizations: **[Live Demo →](https://graphty-org.github.io/algorithms/)**
956
1031
 
957
- The library includes comprehensive examples demonstrating each algorithm. Find them in the [examples directory](https://github.com/graphty-org/algorithms/tree/main/examples):
1032
+ The library includes comprehensive examples demonstrating each algorithm. You can:
1033
+
1034
+ - **[Browse Interactive HTML Examples](https://graphty-org.github.io/algorithms/examples/)** - Visual demonstrations with step-by-step execution
1035
+ - **[View Performance Benchmarks](https://graphty-org.github.io/algorithms/benchmarks/)** - Comparative analysis of algorithm performance
1036
+ - **[Explore Code Examples](https://github.com/graphty-org/algorithms/tree/main/examples)** - Implementation examples for each algorithm
958
1037
 
959
1038
  ### Basic Algorithms
1039
+
960
1040
  - [BFS Traversal](https://github.com/graphty-org/algorithms/blob/main/examples/bfs-example.js) - Breadth-first search and shortest paths
961
1041
  - [DFS Traversal](https://github.com/graphty-org/algorithms/blob/main/examples/dfs-example.js) - Depth-first search and applications
962
1042
  - [Dijkstra's Algorithm](https://github.com/graphty-org/algorithms/blob/main/examples/dijkstra-example.js) - Weighted shortest paths
@@ -964,6 +1044,7 @@ The library includes comprehensive examples demonstrating each algorithm. Find t
964
1044
  - [Floyd-Warshall](https://github.com/graphty-org/algorithms/blob/main/examples/floyd-warshall-example.js) - All pairs shortest paths
965
1045
 
966
1046
  ### Centrality Measures
1047
+
967
1048
  - [Degree Centrality](https://github.com/graphty-org/algorithms/blob/main/examples/degree-centrality-example.js) - Node importance by connections
968
1049
  - [Betweenness Centrality](https://github.com/graphty-org/algorithms/blob/main/examples/betweenness-centrality-example.js) - Bridge nodes
969
1050
  - [Closeness Centrality](https://github.com/graphty-org/algorithms/blob/main/examples/closeness-centrality-example.js) - Central nodes
@@ -973,37 +1054,44 @@ The library includes comprehensive examples demonstrating each algorithm. Find t
973
1054
  - [HITS Algorithm](https://github.com/graphty-org/algorithms/blob/main/examples/hits-algorithm-example.js) - Hub and authority scores
974
1055
 
975
1056
  ### Graph Structure
1057
+
976
1058
  - [Connected Components](https://github.com/graphty-org/algorithms/blob/main/examples/connected-components-example.js) - Find graph components
977
1059
  - [Kruskal's MST](https://github.com/graphty-org/algorithms/blob/main/examples/kruskal-example.js) - Minimum spanning tree
978
1060
  - [Prim's MST](https://github.com/graphty-org/algorithms/blob/main/examples/prim-example.js) - Alternative MST algorithm
979
1061
 
980
1062
  ### Community Detection
1063
+
981
1064
  - [Louvain Method](https://github.com/graphty-org/algorithms/blob/main/examples/louvain-example.js) - Modularity-based communities
982
1065
  - [Leiden Algorithm](https://github.com/graphty-org/algorithms/blob/main/examples/leiden-community.ts) - Improved Louvain
983
1066
  - [Label Propagation](https://github.com/graphty-org/algorithms/blob/main/examples/label-propagation.ts) - Fast community detection
984
1067
  - [Girvan-Newman](https://github.com/graphty-org/algorithms/blob/main/examples/girvan-newman-example.js) - Hierarchical communities
985
1068
 
986
1069
  ### Clustering
1070
+
987
1071
  - [Hierarchical Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/hierarchical-clustering.ts) - Graph clustering
988
1072
  - [K-Core Decomposition](https://github.com/graphty-org/algorithms/blob/main/examples/k-core-decomposition.ts) - Core analysis
989
1073
  - [Spectral Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/spectral-clustering-example.js) - Eigenvalue-based clustering
990
1074
  - [MCL Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/mcl-clustering-example.js) - Markov clustering
991
1075
 
992
1076
  ### Matching
1077
+
993
1078
  - [Bipartite Matching](https://github.com/graphty-org/algorithms/blob/main/examples/bipartite-matching-example.js) - Job assignment, dating apps
994
1079
  - [Graph Isomorphism](https://github.com/graphty-org/algorithms/blob/main/examples/graph-isomorphism-example.js) - Structural equivalence
995
1080
 
996
1081
  ### Link Prediction
1082
+
997
1083
  - [Common Neighbors](https://github.com/graphty-org/algorithms/blob/main/examples/common-neighbors-example.js) - Friend suggestions
998
1084
  - [Adamic-Adar](https://github.com/graphty-org/algorithms/blob/main/examples/adamic-adar-example.js) - Weighted predictions
999
1085
 
1000
1086
  ### Advanced Algorithms
1001
- - [A* Pathfinding](https://github.com/graphty-org/algorithms/blob/main/examples/astar-pathfinding.ts) - Heuristic pathfinding
1087
+
1088
+ - [A\* Pathfinding](https://github.com/graphty-org/algorithms/blob/main/examples/astar-pathfinding.ts) - Heuristic pathfinding
1002
1089
  - [Flow Algorithms](https://github.com/graphty-org/algorithms/blob/main/examples/flow-algorithms.ts) - Maximum flow and applications
1003
1090
  - [Ford-Fulkerson Flow](https://github.com/graphty-org/algorithms/blob/main/examples/ford-fulkerson-flow.ts) - Maximum flow implementation
1004
1091
  - [Minimum Cut](https://github.com/graphty-org/algorithms/blob/main/examples/min-cut.ts) - Graph partitioning
1005
1092
 
1006
1093
  ### Research Algorithms
1094
+
1007
1095
  - [SynC Clustering](https://github.com/graphty-org/algorithms/blob/main/examples/sync-example.js) - Deep learning based clustering
1008
1096
  - [TeraHAC](https://github.com/graphty-org/algorithms/blob/main/examples/terahac-example.js) - Scalable hierarchical clustering
1009
1097
  - [GRSBM](https://github.com/graphty-org/algorithms/blob/main/examples/grsbm-example.js) - Explainable community detection
@@ -1016,13 +1104,13 @@ The library includes comprehensive examples demonstrating each algorithm. Find t
1016
1104
  const graph = new Graph();
1017
1105
 
1018
1106
  // Add weighted edges
1019
- graph.addEdge('A', 'B', 5);
1020
- graph.addEdge('B', 'C', 3);
1021
- graph.addEdge('A', 'C', 10);
1107
+ graph.addEdge("A", "B", 5);
1108
+ graph.addEdge("B", "C", 3);
1109
+ graph.addEdge("A", "C", 10);
1022
1110
 
1023
1111
  // Find shortest path considering weights
1024
- const result = dijkstra(graph, 'A');
1025
- const pathToC = dijkstraPath(graph, 'A', 'C');
1112
+ const result = dijkstra(graph, "A");
1113
+ const pathToC = dijkstraPath(graph, "A", "C");
1026
1114
  console.log(pathToC); // { path: ['A', 'B', 'C'], distance: 8 }
1027
1115
  ```
1028
1116
 
@@ -1031,9 +1119,9 @@ console.log(pathToC); // { path: ['A', 'B', 'C'], distance: 8 }
1031
1119
  ```typescript
1032
1120
  const directedGraph = new Graph({ directed: true });
1033
1121
 
1034
- directedGraph.addEdge('A', 'B');
1035
- directedGraph.addEdge('B', 'C');
1036
- directedGraph.addEdge('C', 'A');
1122
+ directedGraph.addEdge("A", "B");
1123
+ directedGraph.addEdge("B", "C");
1124
+ directedGraph.addEdge("C", "A");
1037
1125
 
1038
1126
  // Check for cycles
1039
1127
  console.log(hasCycleDFS(directedGraph)); // true
@@ -1054,8 +1142,8 @@ const influencers = topPageRankNodes(graph, 10);
1054
1142
 
1055
1143
  // Find bridges (high betweenness)
1056
1144
  const bridgers = Array.from(betweennessCentrality(graph).entries())
1057
- .sort((a, b) => b[1] - a[1])
1058
- .slice(0, 10);
1145
+ .sort((a, b) => b[1] - a[1])
1146
+ .slice(0, 10);
1059
1147
 
1060
1148
  // Find communities (connected components)
1061
1149
  const communities = connectedComponents(graph);
@@ -1068,15 +1156,15 @@ console.log(`Found ${communities.components.length} communities`);
1068
1156
  const graph = new Graph();
1069
1157
 
1070
1158
  // Add edges with custom data
1071
- graph.addEdge('A', 'B', 1, {
1072
- type: 'road',
1073
- distance: 100,
1074
- traffic: 'heavy'
1159
+ graph.addEdge("A", "B", 1, {
1160
+ type: "road",
1161
+ distance: 100,
1162
+ traffic: "heavy",
1075
1163
  });
1076
1164
 
1077
1165
  // Use custom weight in algorithms
1078
- const result = dijkstra(graph, 'A', {
1079
- weightKey: 'distance' // Use 'distance' property as weight
1166
+ const result = dijkstra(graph, "A", {
1167
+ weightKey: "distance", // Use 'distance' property as weight
1080
1168
  });
1081
1169
  ```
1082
1170
 
@@ -1091,18 +1179,18 @@ const centralities = degreeCentrality(graph, { normalized: true });
1091
1179
  const ranks = pageRank(graph);
1092
1180
 
1093
1181
  // Export for visualization
1094
- const nodes = Array.from(graph.nodes()).map(node => ({
1095
- id: node.id,
1096
- data: node.data,
1097
- size: centralities.get(node.id) || 0,
1098
- importance: ranks.get(node.id) || 0
1182
+ const nodes = Array.from(graph.nodes()).map((node) => ({
1183
+ id: node.id,
1184
+ data: node.data,
1185
+ size: centralities.get(node.id) || 0,
1186
+ importance: ranks.get(node.id) || 0,
1099
1187
  }));
1100
1188
 
1101
- const edges = Array.from(graph.edges()).map(edge => ({
1102
- source: edge.source,
1103
- target: edge.target,
1104
- weight: edge.weight || 1,
1105
- data: edge.data
1189
+ const edges = Array.from(graph.edges()).map((edge) => ({
1190
+ source: edge.source,
1191
+ target: edge.target,
1192
+ weight: edge.weight || 1,
1193
+ data: edge.data,
1106
1194
  }));
1107
1195
  ```
1108
1196
 
@@ -1114,16 +1202,16 @@ const edges = Array.from(graph.edges()).map(edge => ({
1114
1202
  type NodeId = string | number;
1115
1203
 
1116
1204
  interface Node {
1117
- id: NodeId;
1118
- data?: Record<string, unknown>;
1205
+ id: NodeId;
1206
+ data?: Record<string, unknown>;
1119
1207
  }
1120
1208
 
1121
1209
  interface Edge {
1122
- source: NodeId;
1123
- target: NodeId;
1124
- weight?: number;
1125
- id?: string;
1126
- data?: Record<string, unknown>;
1210
+ source: NodeId;
1211
+ target: NodeId;
1212
+ weight?: number;
1213
+ id?: string;
1214
+ data?: Record<string, unknown>;
1127
1215
  }
1128
1216
  ```
1129
1217
 
@@ -1131,106 +1219,106 @@ interface Edge {
1131
1219
 
1132
1220
  ```typescript
1133
1221
  interface TraversalResult {
1134
- visited: Set<NodeId>;
1135
- order: NodeId[];
1136
- tree?: Map<NodeId, NodeId>;
1222
+ visited: Set<NodeId>;
1223
+ order: NodeId[];
1224
+ tree?: Map<NodeId, NodeId | null>;
1137
1225
  }
1138
1226
 
1139
1227
  interface ShortestPathResult {
1140
- path: NodeId[];
1141
- distance: number;
1142
- predecessor: NodeId | null;
1228
+ distance: number;
1229
+ path: NodeId[];
1230
+ predecessor: Map<NodeId, NodeId | null>;
1143
1231
  }
1144
1232
 
1145
1233
  interface BellmanFordResult {
1146
- distances: Map<NodeId, number>;
1147
- predecessors: Map<NodeId, NodeId | null>;
1148
- hasNegativeCycle: boolean;
1149
- negativeCycleNodes?: Set<NodeId>;
1234
+ distances: Map<NodeId, number>;
1235
+ previous: Map<NodeId, NodeId | null>;
1236
+ hasNegativeCycle: boolean;
1237
+ negativeCycleNodes?: NodeId[];
1150
1238
  }
1151
1239
 
1152
1240
  type CentralityResult = Record<string, number>;
1153
1241
 
1154
1242
  interface PageRankResult {
1155
- ranks: Record<string, number>;
1156
- iterations: number;
1157
- converged: boolean;
1243
+ ranks: Record<string, number>;
1244
+ iterations: number;
1245
+ converged: boolean;
1158
1246
  }
1159
1247
 
1160
1248
  interface CommunityResult {
1161
- communities: Map<NodeId, number>;
1162
- modularity: number;
1249
+ communities: Map<NodeId, number>;
1250
+ modularity: number;
1163
1251
  }
1164
1252
 
1165
1253
  interface ComponentResult {
1166
- components: NodeId[][];
1167
- componentMap: Map<NodeId, number>;
1254
+ components: NodeId[][];
1255
+ componentMap: Map<NodeId, number>;
1168
1256
  }
1169
1257
 
1170
1258
  interface HITSResult {
1171
- hubs: CentralityResult;
1172
- authorities: CentralityResult;
1259
+ hubs: CentralityResult;
1260
+ authorities: CentralityResult;
1173
1261
  }
1174
1262
 
1175
1263
  interface SpectralClusteringResult {
1176
- communities: NodeId[][];
1177
- clusterAssignments: Map<NodeId, number>;
1264
+ communities: NodeId[][];
1265
+ clusterAssignments: Map<NodeId, number>;
1178
1266
  }
1179
1267
 
1180
1268
  interface MCLResult {
1181
- communities: NodeId[][];
1182
- attractors: Set<NodeId>;
1183
- iterations: number;
1184
- converged: boolean;
1269
+ communities: NodeId[][];
1270
+ attractors: Set<NodeId>;
1271
+ iterations: number;
1272
+ converged: boolean;
1185
1273
  }
1186
1274
 
1187
1275
  interface BipartiteMatchingResult {
1188
- matching: Map<NodeId, NodeId>;
1189
- size: number;
1276
+ matching: Map<NodeId, NodeId>;
1277
+ size: number;
1190
1278
  }
1191
1279
 
1192
1280
  interface LinkPredictionScore {
1193
- source: NodeId;
1194
- target: NodeId;
1195
- score: number;
1281
+ source: NodeId;
1282
+ target: NodeId;
1283
+ score: number;
1196
1284
  }
1197
1285
 
1198
1286
  interface HierarchicalClusteringResult<T> {
1199
- root: ClusterNode<T>;
1200
- dendrogram: ClusterNode<T>[];
1201
- clusters: Map<number, Set<T>[]>;
1287
+ root: ClusterNode<T>;
1288
+ dendrogram: ClusterNode<T>[];
1289
+ clusters: Map<number, Set<T>[]>;
1202
1290
  }
1203
1291
 
1204
1292
  interface KCoreResult<T> {
1205
- cores: Map<number, Set<T>>;
1206
- coreness: Map<T, number>;
1207
- maxCore: number;
1293
+ cores: Map<number, Set<T>>;
1294
+ coreness: Map<T, number>;
1295
+ maxCore: number;
1208
1296
  }
1209
1297
 
1210
1298
  interface IsomorphismResult {
1211
- isIsomorphic: boolean;
1212
- mapping?: Map<NodeId, NodeId>;
1299
+ isIsomorphic: boolean;
1300
+ mapping?: Map<NodeId, NodeId>;
1213
1301
  }
1214
1302
 
1215
1303
  interface SynCResult {
1216
- communities: NodeId[][];
1217
- clusterAssignments: Map<NodeId, number>;
1218
- embeddings: Map<NodeId, number[]>;
1219
- iterations: number;
1220
- converged: boolean;
1304
+ communities: NodeId[][];
1305
+ clusterAssignments: Map<NodeId, number>;
1306
+ embeddings: Map<NodeId, number[]>;
1307
+ iterations: number;
1308
+ converged: boolean;
1221
1309
  }
1222
1310
 
1223
1311
  interface TeraHACResult {
1224
- root: TeraHACClusterNode;
1225
- dendrogram: TeraHACClusterNode[];
1226
- clusters: NodeId[][];
1227
- mergeDistances: number[];
1312
+ root: TeraHACClusterNode;
1313
+ dendrogram: TeraHACClusterNode[];
1314
+ clusters: NodeId[][];
1315
+ mergeDistances: number[];
1228
1316
  }
1229
1317
 
1230
1318
  interface GRSBMResult {
1231
- clusters: GRSBMCluster[];
1232
- hierarchy: Map<number, number[]>;
1233
- totalModularity: number;
1319
+ clusters: GRSBMCluster[];
1320
+ hierarchy: Map<number, number[]>;
1321
+ totalModularity: number;
1234
1322
  }
1235
1323
  ```
1236
1324
 
@@ -1238,30 +1326,31 @@ interface GRSBMResult {
1238
1326
 
1239
1327
  - **Graph Representation**: Uses adjacency lists for O(1) neighbor access
1240
1328
  - **Algorithm Complexity**:
1241
- - BFS/DFS: O(V + E)
1242
- - Dijkstra: O((V + E) log V) with binary heap
1243
- - Bellman-Ford: O(VE)
1244
- - Floyd-Warshall: O(V³)
1245
- - PageRank: O(k(V + E)) where k is iterations
1246
- - Connected Components: O(V + E)
1247
- - Kruskal's MST: O(E log E)
1248
- - Prim's MST: O((V + E) log V)
1249
- - A*: O((V + E) log V) - depends on heuristic quality
1250
- - Ford-Fulkerson: O(E * f) where f is max flow
1251
- - Edmonds-Karp: O(VE²)
1252
- - Louvain/Leiden: O(n log n) average case
1253
- - Hierarchical Clustering: O(n² log n)
1254
- - SynC: O(kni) where k is clusters, n is nodes, i is iterations
1255
- - TeraHAC: O(n log n) with sampling
1256
- - GRSBM: O(m log n) where m is edges
1329
+ - BFS/DFS: O(V + E)
1330
+ - Dijkstra: O((V + E) log V) with binary heap
1331
+ - Bellman-Ford: O(VE)
1332
+ - Floyd-Warshall: O(V³)
1333
+ - PageRank: O(k(V + E)) where k is iterations
1334
+ - Connected Components: O(V + E)
1335
+ - Kruskal's MST: O(E log E)
1336
+ - Prim's MST: O((V + E) log V)
1337
+ - A\*: O((V + E) log V) - depends on heuristic quality
1338
+ - Ford-Fulkerson: O(E \* f) where f is max flow
1339
+ - Edmonds-Karp: O(VE²)
1340
+ - Louvain/Leiden: O(n log n) average case
1341
+ - Hierarchical Clustering: O(n² log n)
1342
+ - SynC: O(kni) where k is clusters, n is nodes, i is iterations
1343
+ - TeraHAC: O(n log n) with sampling
1344
+ - GRSBM: O(m log n) where m is edges
1257
1345
  - **Memory Usage**: O(V + E) for graph storage
1258
1346
  - **Browser Optimization**: Algorithms use iterative approaches where possible to avoid stack overflow
1347
+ - **Performance Benchmarks**: View detailed performance comparisons at [https://graphty-org.github.io/algorithms/benchmarks/](https://graphty-org.github.io/algorithms/benchmarks/)
1259
1348
 
1260
1349
  ## Development
1261
1350
 
1262
1351
  ### Prerequisites
1263
1352
 
1264
- - Node.js 18+
1353
+ - Node.js 18+
1265
1354
  - npm 9+
1266
1355
 
1267
1356
  ### Setup
@@ -1297,12 +1386,18 @@ npm run lint # Run ESLint
1297
1386
  npm run lint:fix # Fix ESLint issues
1298
1387
  npm run lint:pkg # Check for unused dependencies
1299
1388
 
1300
- # Git
1301
- npm run commit # Conventional commit helper
1389
+ # Benchmarking
1390
+ npm run benchmark # Run full benchmark suite
1391
+ npm run benchmark:quick # Run quick benchmark
1392
+ npm run benchmark:report # Generate performance report
1302
1393
 
1303
- # HTML Examples
1304
- npm run examples:html # Run interactive HTML examples
1394
+ # HTML Examples & Documentation
1395
+ npm run examples:html # Run interactive HTML examples locally
1305
1396
  npm run build:gh-pages # Build for GitHub Pages deployment
1397
+ npm run examples:run # Run all code examples
1398
+
1399
+ # Git
1400
+ npm run commit # Conventional commit helper
1306
1401
  ```
1307
1402
 
1308
1403
  ### Development Server
@@ -1310,30 +1405,34 @@ npm run build:gh-pages # Build for GitHub Pages deployment
1310
1405
  The project includes interactive HTML examples demonstrating each algorithm. To run them locally:
1311
1406
 
1312
1407
  1. **Copy the environment configuration:**
1313
- ```bash
1314
- cp .env.example .env
1315
- ```
1408
+
1409
+ ```bash
1410
+ cp .env.example .env
1411
+ ```
1316
1412
 
1317
1413
  2. **Configure the server (optional):**
1318
1414
  Edit `.env` to set your preferred host and port:
1319
- ```bash
1320
- # Server host (defaults to true for network exposure)
1321
- HOST=localhost # For local-only access
1322
- # HOST=0.0.0.0 # For network access
1323
- # HOST=my.server.com # Custom domain
1324
1415
 
1325
- # Server port (defaults to 9000)
1326
- PORT=9000 # Must be between 9000-9099
1327
- ```
1416
+ ```bash
1417
+ # Server host (defaults to true for network exposure)
1418
+ HOST=localhost # For local-only access
1419
+ # HOST=0.0.0.0 # For network access
1420
+ # HOST=my.server.com # Custom domain
1421
+
1422
+ # Server port (defaults to 9000)
1423
+ PORT=9000 # Must be between 9000-9099
1424
+ ```
1328
1425
 
1329
1426
  3. **Start the development server:**
1330
- ```bash
1331
- npm run examples:html
1332
- ```
1427
+
1428
+ ```bash
1429
+ npm run examples:html
1430
+ ```
1333
1431
 
1334
1432
  4. **Open your browser** to `http://localhost:9000` (or your configured host/port)
1335
1433
 
1336
1434
  The HTML examples provide:
1435
+
1337
1436
  - Interactive visualizations for each algorithm
1338
1437
  - Step-by-step execution with play/pause controls
1339
1438
  - Multiple graph types for testing