@graphty/algorithms 2.1.1 → 2.2.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 (355) hide show
  1. package/README.md +139 -50
  2. package/dist/algorithms.js +15260 -10390
  3. package/dist/algorithms.js.map +1 -1
  4. package/dist/algorithms.standalone.js +26675 -21542
  5. package/dist/algorithms.standalone.js.map +1 -1
  6. package/dist/src/algorithms/centrality/betweenness.d.ts +18 -0
  7. package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
  8. package/dist/src/algorithms/centrality/betweenness.js +40 -1
  9. package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
  10. package/dist/src/algorithms/centrality/closeness.d.ts +20 -0
  11. package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -1
  12. package/dist/src/algorithms/centrality/closeness.js +93 -8
  13. package/dist/src/algorithms/centrality/closeness.js.map +1 -1
  14. package/dist/src/algorithms/centrality/degree.d.ts +9 -0
  15. package/dist/src/algorithms/centrality/degree.d.ts.map +1 -1
  16. package/dist/src/algorithms/centrality/degree.js +18 -0
  17. package/dist/src/algorithms/centrality/degree.js.map +1 -1
  18. package/dist/src/algorithms/centrality/eigenvector.d.ts +10 -0
  19. package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -1
  20. package/dist/src/algorithms/centrality/eigenvector.js +29 -0
  21. package/dist/src/algorithms/centrality/eigenvector.js.map +1 -1
  22. package/dist/src/algorithms/centrality/hits.d.ts +9 -0
  23. package/dist/src/algorithms/centrality/hits.d.ts.map +1 -1
  24. package/dist/src/algorithms/centrality/hits.js +23 -0
  25. package/dist/src/algorithms/centrality/hits.js.map +1 -1
  26. package/dist/src/algorithms/centrality/katz.d.ts +9 -0
  27. package/dist/src/algorithms/centrality/katz.d.ts.map +1 -1
  28. package/dist/src/algorithms/centrality/katz.js +31 -0
  29. package/dist/src/algorithms/centrality/katz.js.map +1 -1
  30. package/dist/src/algorithms/centrality/pagerank.d.ts +13 -13
  31. package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -1
  32. package/dist/src/algorithms/centrality/pagerank.js +47 -10
  33. package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
  34. package/dist/src/algorithms/community/girvan-newman-legacy.d.ts +27 -0
  35. package/dist/src/algorithms/community/girvan-newman-legacy.d.ts.map +1 -0
  36. package/dist/src/algorithms/community/girvan-newman-legacy.js +335 -0
  37. package/dist/src/algorithms/community/girvan-newman-legacy.js.map +1 -0
  38. package/dist/src/algorithms/community/girvan-newman.d.ts +5 -3
  39. package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -1
  40. package/dist/src/algorithms/community/girvan-newman.js +34 -308
  41. package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
  42. package/dist/src/algorithms/community/label-propagation.d.ts +9 -6
  43. package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -1
  44. package/dist/src/algorithms/community/label-propagation.js +24 -110
  45. package/dist/src/algorithms/community/label-propagation.js.map +1 -1
  46. package/dist/src/algorithms/components/connected.d.ts.map +1 -1
  47. package/dist/src/algorithms/components/connected.js +28 -77
  48. package/dist/src/algorithms/components/connected.js.map +1 -1
  49. package/dist/src/algorithms/mst/kruskal.d.ts.map +1 -1
  50. package/dist/src/algorithms/mst/kruskal.js +59 -3
  51. package/dist/src/algorithms/mst/kruskal.js.map +1 -1
  52. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -1
  53. package/dist/src/algorithms/shortest-path/bellman-ford.js +46 -0
  54. package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
  55. package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -1
  56. package/dist/src/algorithms/shortest-path/dijkstra.js +27 -0
  57. package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
  58. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts +15 -5
  59. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts.map +1 -1
  60. package/dist/src/algorithms/shortest-path/floyd-warshall.js +97 -107
  61. package/dist/src/algorithms/shortest-path/floyd-warshall.js.map +1 -1
  62. package/dist/src/algorithms/traversal/bfs-unified.d.ts +2 -12
  63. package/dist/src/algorithms/traversal/bfs-unified.d.ts.map +1 -1
  64. package/dist/src/algorithms/traversal/bfs-unified.js +47 -308
  65. package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -1
  66. package/dist/src/algorithms/traversal/bfs-variants.d.ts.map +1 -1
  67. package/dist/src/algorithms/traversal/bfs-variants.js +5 -25
  68. package/dist/src/algorithms/traversal/bfs-variants.js.map +1 -1
  69. package/dist/src/algorithms/traversal/bfs.d.ts +0 -3
  70. package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -1
  71. package/dist/src/algorithms/traversal/bfs.js +0 -4
  72. package/dist/src/algorithms/traversal/bfs.js.map +1 -1
  73. package/dist/src/algorithms/traversal/dfs.d.ts.map +1 -1
  74. package/dist/src/algorithms/traversal/dfs.js +33 -154
  75. package/dist/src/algorithms/traversal/dfs.js.map +1 -1
  76. package/dist/src/clustering/hierarchical-legacy.d.ts +56 -0
  77. package/dist/src/clustering/hierarchical-legacy.d.ts.map +1 -0
  78. package/dist/src/clustering/hierarchical-legacy.js +441 -0
  79. package/dist/src/clustering/hierarchical-legacy.js.map +1 -0
  80. package/dist/src/clustering/hierarchical.d.ts +7 -39
  81. package/dist/src/clustering/hierarchical.d.ts.map +1 -1
  82. package/dist/src/clustering/hierarchical.js +56 -417
  83. package/dist/src/clustering/hierarchical.js.map +1 -1
  84. package/dist/src/clustering/k-core-legacy.d.ts +30 -0
  85. package/dist/src/clustering/k-core-legacy.d.ts.map +1 -0
  86. package/dist/src/clustering/k-core-legacy.js +191 -0
  87. package/dist/src/clustering/k-core-legacy.js.map +1 -0
  88. package/dist/src/clustering/k-core.d.ts +8 -7
  89. package/dist/src/clustering/k-core.d.ts.map +1 -1
  90. package/dist/src/clustering/k-core.js +33 -174
  91. package/dist/src/clustering/k-core.js.map +1 -1
  92. package/dist/src/clustering/mcl-legacy.d.ts +42 -0
  93. package/dist/src/clustering/mcl-legacy.d.ts.map +1 -0
  94. package/dist/src/clustering/mcl-legacy.js +386 -0
  95. package/dist/src/clustering/mcl-legacy.js.map +1 -0
  96. package/dist/src/clustering/mcl.d.ts +9 -32
  97. package/dist/src/clustering/mcl.d.ts.map +1 -1
  98. package/dist/src/clustering/mcl.js +48 -374
  99. package/dist/src/clustering/mcl.js.map +1 -1
  100. package/dist/src/index.d.ts +29 -3
  101. package/dist/src/index.d.ts.map +1 -1
  102. package/dist/src/index.js +2 -1
  103. package/dist/src/index.js.map +1 -1
  104. package/dist/src/indexed/accelerator.d.ts +141 -11
  105. package/dist/src/indexed/accelerator.d.ts.map +1 -1
  106. package/dist/src/indexed/accelerator.js +319 -5
  107. package/dist/src/indexed/accelerator.js.map +1 -1
  108. package/dist/src/indexed/all-pairs.d.ts +59 -0
  109. package/dist/src/indexed/all-pairs.d.ts.map +1 -0
  110. package/dist/src/indexed/all-pairs.js +274 -0
  111. package/dist/src/indexed/all-pairs.js.map +1 -0
  112. package/dist/src/indexed/bellman-ford.d.ts +25 -0
  113. package/dist/src/indexed/bellman-ford.d.ts.map +1 -0
  114. package/dist/src/indexed/bellman-ford.js +59 -0
  115. package/dist/src/indexed/bellman-ford.js.map +1 -0
  116. package/dist/src/indexed/betweenness.d.ts +85 -0
  117. package/dist/src/indexed/betweenness.d.ts.map +1 -0
  118. package/dist/src/indexed/betweenness.js +188 -0
  119. package/dist/src/indexed/betweenness.js.map +1 -0
  120. package/dist/src/indexed/bfs.d.ts +69 -2
  121. package/dist/src/indexed/bfs.d.ts.map +1 -1
  122. package/dist/src/indexed/bfs.js +148 -1
  123. package/dist/src/indexed/bfs.js.map +1 -1
  124. package/dist/src/indexed/bipartite.d.ts +37 -0
  125. package/dist/src/indexed/bipartite.d.ts.map +1 -0
  126. package/dist/src/indexed/bipartite.js +54 -0
  127. package/dist/src/indexed/bipartite.js.map +1 -0
  128. package/dist/src/indexed/closeness.d.ts +49 -0
  129. package/dist/src/indexed/closeness.d.ts.map +1 -0
  130. package/dist/src/indexed/closeness.js +127 -0
  131. package/dist/src/indexed/closeness.js.map +1 -0
  132. package/dist/src/indexed/common-neighbors.d.ts +14 -1
  133. package/dist/src/indexed/common-neighbors.d.ts.map +1 -1
  134. package/dist/src/indexed/common-neighbors.js +24 -14
  135. package/dist/src/indexed/common-neighbors.js.map +1 -1
  136. package/dist/src/indexed/degree.d.ts +19 -0
  137. package/dist/src/indexed/degree.d.ts.map +1 -0
  138. package/dist/src/indexed/degree.js +45 -0
  139. package/dist/src/indexed/degree.js.map +1 -0
  140. package/dist/src/indexed/delta-pagerank.d.ts +145 -0
  141. package/dist/src/indexed/delta-pagerank.d.ts.map +1 -0
  142. package/dist/src/indexed/delta-pagerank.js +428 -0
  143. package/dist/src/indexed/delta-pagerank.js.map +1 -0
  144. package/dist/src/indexed/dfs.d.ts +55 -0
  145. package/dist/src/indexed/dfs.d.ts.map +1 -0
  146. package/dist/src/indexed/dfs.js +146 -0
  147. package/dist/src/indexed/dfs.js.map +1 -0
  148. package/dist/src/indexed/eigenvector.d.ts +48 -0
  149. package/dist/src/indexed/eigenvector.d.ts.map +1 -0
  150. package/dist/src/indexed/eigenvector.js +162 -0
  151. package/dist/src/indexed/eigenvector.js.map +1 -0
  152. package/dist/src/indexed/facade.d.ts +109 -0
  153. package/dist/src/indexed/facade.d.ts.map +1 -0
  154. package/dist/src/indexed/facade.js +204 -0
  155. package/dist/src/indexed/facade.js.map +1 -0
  156. package/dist/src/indexed/flow.d.ts +120 -0
  157. package/dist/src/indexed/flow.d.ts.map +1 -0
  158. package/dist/src/indexed/flow.js +377 -0
  159. package/dist/src/indexed/flow.js.map +1 -0
  160. package/dist/src/indexed/girvan-newman.d.ts +42 -0
  161. package/dist/src/indexed/girvan-newman.d.ts.map +1 -0
  162. package/dist/src/indexed/girvan-newman.js +90 -0
  163. package/dist/src/indexed/girvan-newman.js.map +1 -0
  164. package/dist/src/indexed/grsbm.d.ts +85 -0
  165. package/dist/src/indexed/grsbm.d.ts.map +1 -0
  166. package/dist/src/indexed/grsbm.js +287 -0
  167. package/dist/src/indexed/grsbm.js.map +1 -0
  168. package/dist/src/indexed/hierarchical.d.ts +69 -0
  169. package/dist/src/indexed/hierarchical.d.ts.map +1 -0
  170. package/dist/src/indexed/hierarchical.js +245 -0
  171. package/dist/src/indexed/hierarchical.js.map +1 -0
  172. package/dist/src/indexed/index.d.ts +29 -3
  173. package/dist/src/indexed/index.d.ts.map +1 -1
  174. package/dist/src/indexed/index.js +29 -3
  175. package/dist/src/indexed/index.js.map +1 -1
  176. package/dist/src/indexed/isomorphism.d.ts +42 -0
  177. package/dist/src/indexed/isomorphism.d.ts.map +1 -0
  178. package/dist/src/indexed/isomorphism.js +269 -0
  179. package/dist/src/indexed/isomorphism.js.map +1 -0
  180. package/dist/src/indexed/label-propagation.d.ts +134 -0
  181. package/dist/src/indexed/label-propagation.d.ts.map +1 -0
  182. package/dist/src/indexed/label-propagation.js +486 -0
  183. package/dist/src/indexed/label-propagation.js.map +1 -0
  184. package/dist/src/indexed/leiden.d.ts +52 -0
  185. package/dist/src/indexed/leiden.d.ts.map +1 -0
  186. package/dist/src/indexed/leiden.js +384 -0
  187. package/dist/src/indexed/leiden.js.map +1 -0
  188. package/dist/src/indexed/link-prediction.d.ts +147 -0
  189. package/dist/src/indexed/link-prediction.d.ts.map +1 -0
  190. package/dist/src/indexed/link-prediction.js +317 -0
  191. package/dist/src/indexed/link-prediction.js.map +1 -0
  192. package/dist/src/indexed/markov.d.ts +54 -0
  193. package/dist/src/indexed/markov.d.ts.map +1 -0
  194. package/dist/src/indexed/markov.js +284 -0
  195. package/dist/src/indexed/markov.js.map +1 -0
  196. package/dist/src/indexed/matching.d.ts +53 -0
  197. package/dist/src/indexed/matching.d.ts.map +1 -0
  198. package/dist/src/indexed/matching.js +139 -0
  199. package/dist/src/indexed/matching.js.map +1 -0
  200. package/dist/src/indexed/min-cut.d.ts +48 -0
  201. package/dist/src/indexed/min-cut.d.ts.map +1 -0
  202. package/dist/src/indexed/min-cut.js +175 -0
  203. package/dist/src/indexed/min-cut.js.map +1 -0
  204. package/dist/src/indexed/modularity.d.ts +34 -0
  205. package/dist/src/indexed/modularity.d.ts.map +1 -0
  206. package/dist/src/indexed/modularity.js +74 -0
  207. package/dist/src/indexed/modularity.js.map +1 -0
  208. package/dist/src/indexed/mst.d.ts +29 -1
  209. package/dist/src/indexed/mst.d.ts.map +1 -1
  210. package/dist/src/indexed/mst.js +62 -0
  211. package/dist/src/indexed/mst.js.map +1 -1
  212. package/dist/src/indexed/pagerank.d.ts +29 -6
  213. package/dist/src/indexed/pagerank.d.ts.map +1 -1
  214. package/dist/src/indexed/pagerank.js +107 -11
  215. package/dist/src/indexed/pagerank.js.map +1 -1
  216. package/dist/src/indexed/point-to-point.d.ts +53 -0
  217. package/dist/src/indexed/point-to-point.d.ts.map +1 -0
  218. package/dist/src/indexed/point-to-point.js +173 -0
  219. package/dist/src/indexed/point-to-point.js.map +1 -0
  220. package/dist/src/indexed/scc.d.ts +53 -0
  221. package/dist/src/indexed/scc.d.ts.map +1 -0
  222. package/dist/src/indexed/scc.js +110 -0
  223. package/dist/src/indexed/scc.js.map +1 -0
  224. package/dist/src/indexed/spectral.d.ts +61 -0
  225. package/dist/src/indexed/spectral.d.ts.map +1 -0
  226. package/dist/src/indexed/spectral.js +476 -0
  227. package/dist/src/indexed/spectral.js.map +1 -0
  228. package/dist/src/indexed/structures/bit-set.d.ts +45 -0
  229. package/dist/src/indexed/structures/bit-set.d.ts.map +1 -0
  230. package/dist/src/indexed/structures/bit-set.js +57 -0
  231. package/dist/src/indexed/structures/bit-set.js.map +1 -0
  232. package/dist/src/indexed/structures/max-heap.d.ts +52 -0
  233. package/dist/src/indexed/structures/max-heap.d.ts.map +1 -0
  234. package/dist/src/indexed/structures/max-heap.js +66 -0
  235. package/dist/src/indexed/structures/max-heap.js.map +1 -0
  236. package/dist/src/indexed/structures/min-heap.d.ts +30 -1
  237. package/dist/src/indexed/structures/min-heap.d.ts.map +1 -1
  238. package/dist/src/indexed/structures/min-heap.js +46 -6
  239. package/dist/src/indexed/structures/min-heap.js.map +1 -1
  240. package/dist/src/indexed/structures/ring-queue.d.ts +41 -0
  241. package/dist/src/indexed/structures/ring-queue.d.ts.map +1 -0
  242. package/dist/src/indexed/structures/ring-queue.js +64 -0
  243. package/dist/src/indexed/structures/ring-queue.js.map +1 -0
  244. package/dist/src/indexed/sync.d.ts +50 -0
  245. package/dist/src/indexed/sync.d.ts.map +1 -0
  246. package/dist/src/indexed/sync.js +175 -0
  247. package/dist/src/indexed/sync.js.map +1 -0
  248. package/dist/src/indexed/terahac.d.ts +58 -0
  249. package/dist/src/indexed/terahac.d.ts.map +1 -0
  250. package/dist/src/indexed/terahac.js +244 -0
  251. package/dist/src/indexed/terahac.js.map +1 -0
  252. package/dist/src/indexed/to-snapshot.d.ts +45 -2
  253. package/dist/src/indexed/to-snapshot.d.ts.map +1 -1
  254. package/dist/src/indexed/to-snapshot.js +140 -6
  255. package/dist/src/indexed/to-snapshot.js.map +1 -1
  256. package/dist/src/link-prediction/common-neighbors-legacy.d.ts +71 -0
  257. package/dist/src/link-prediction/common-neighbors-legacy.d.ts.map +1 -0
  258. package/dist/src/link-prediction/common-neighbors-legacy.js +172 -0
  259. package/dist/src/link-prediction/common-neighbors-legacy.js.map +1 -0
  260. package/dist/src/link-prediction/common-neighbors.d.ts +11 -19
  261. package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -1
  262. package/dist/src/link-prediction/common-neighbors.js +56 -123
  263. package/dist/src/link-prediction/common-neighbors.js.map +1 -1
  264. package/dist/src/optimized/direction-optimized-bfs.d.ts +6 -0
  265. package/dist/src/optimized/direction-optimized-bfs.d.ts.map +1 -1
  266. package/dist/src/optimized/direction-optimized-bfs.js +6 -0
  267. package/dist/src/optimized/direction-optimized-bfs.js.map +1 -1
  268. package/dist/src/research/grsbm-legacy.d.ts +82 -0
  269. package/dist/src/research/grsbm-legacy.d.ts.map +1 -0
  270. package/dist/src/research/grsbm-legacy.js +416 -0
  271. package/dist/src/research/grsbm-legacy.js.map +1 -0
  272. package/dist/src/research/grsbm.d.ts +9 -66
  273. package/dist/src/research/grsbm.d.ts.map +1 -1
  274. package/dist/src/research/grsbm.js +67 -391
  275. package/dist/src/research/grsbm.js.map +1 -1
  276. package/dist/src/research/sync-legacy.d.ts +48 -0
  277. package/dist/src/research/sync-legacy.d.ts.map +1 -0
  278. package/dist/src/research/sync-legacy.js +337 -0
  279. package/dist/src/research/sync-legacy.js.map +1 -0
  280. package/dist/src/research/sync.d.ts +10 -32
  281. package/dist/src/research/sync.d.ts.map +1 -1
  282. package/dist/src/research/sync.js +28 -316
  283. package/dist/src/research/sync.js.map +1 -1
  284. package/package.json +4 -3
  285. package/src/algorithms/centrality/betweenness.ts +51 -1
  286. package/src/algorithms/centrality/closeness.ts +112 -12
  287. package/src/algorithms/centrality/degree.ts +19 -0
  288. package/src/algorithms/centrality/eigenvector.ts +34 -0
  289. package/src/algorithms/centrality/hits.ts +24 -0
  290. package/src/algorithms/centrality/katz.ts +32 -0
  291. package/src/algorithms/centrality/pagerank.ts +53 -13
  292. package/src/algorithms/community/girvan-newman-legacy.ts +414 -0
  293. package/src/algorithms/community/girvan-newman.ts +36 -386
  294. package/src/algorithms/community/label-propagation.ts +24 -133
  295. package/src/algorithms/components/connected.ts +28 -95
  296. package/src/algorithms/mst/kruskal.ts +65 -4
  297. package/src/algorithms/shortest-path/bellman-ford.ts +49 -0
  298. package/src/algorithms/shortest-path/dijkstra.ts +29 -0
  299. package/src/algorithms/shortest-path/floyd-warshall.ts +106 -136
  300. package/src/algorithms/traversal/bfs-unified.ts +52 -366
  301. package/src/algorithms/traversal/bfs-variants.ts +5 -28
  302. package/src/algorithms/traversal/bfs.ts +0 -4
  303. package/src/algorithms/traversal/dfs.ts +39 -182
  304. package/src/clustering/hierarchical-legacy.ts +551 -0
  305. package/src/clustering/hierarchical.ts +64 -520
  306. package/src/clustering/k-core-legacy.ts +229 -0
  307. package/src/clustering/k-core.ts +38 -209
  308. package/src/clustering/mcl-legacy.ts +498 -0
  309. package/src/clustering/mcl.ts +46 -479
  310. package/src/index.ts +90 -3
  311. package/src/indexed/accelerator.ts +502 -16
  312. package/src/indexed/all-pairs.ts +342 -0
  313. package/src/indexed/bellman-ford.ts +72 -0
  314. package/src/indexed/betweenness.ts +258 -0
  315. package/src/indexed/bfs.ts +189 -3
  316. package/src/indexed/bipartite.ts +77 -0
  317. package/src/indexed/closeness.ts +160 -0
  318. package/src/indexed/common-neighbors.ts +31 -14
  319. package/src/indexed/degree.ts +55 -0
  320. package/src/indexed/delta-pagerank.ts +513 -0
  321. package/src/indexed/dfs.ts +189 -0
  322. package/src/indexed/eigenvector.ts +202 -0
  323. package/src/indexed/facade.ts +229 -0
  324. package/src/indexed/flow.ts +500 -0
  325. package/src/indexed/girvan-newman.ts +120 -0
  326. package/src/indexed/grsbm.ts +390 -0
  327. package/src/indexed/hierarchical.ts +295 -0
  328. package/src/indexed/index.ts +94 -3
  329. package/src/indexed/isomorphism.ts +305 -0
  330. package/src/indexed/label-propagation.ts +582 -0
  331. package/src/indexed/leiden.ts +436 -0
  332. package/src/indexed/link-prediction.ts +399 -0
  333. package/src/indexed/markov.ts +324 -0
  334. package/src/indexed/matching.ts +192 -0
  335. package/src/indexed/min-cut.ts +201 -0
  336. package/src/indexed/modularity.ts +81 -0
  337. package/src/indexed/mst.ts +79 -1
  338. package/src/indexed/pagerank.ts +128 -15
  339. package/src/indexed/point-to-point.ts +220 -0
  340. package/src/indexed/scc.ts +132 -0
  341. package/src/indexed/spectral.ts +550 -0
  342. package/src/indexed/structures/bit-set.ts +65 -0
  343. package/src/indexed/structures/max-heap.ts +74 -0
  344. package/src/indexed/structures/min-heap.ts +51 -6
  345. package/src/indexed/structures/ring-queue.ts +70 -0
  346. package/src/indexed/sync.ts +229 -0
  347. package/src/indexed/terahac.ts +290 -0
  348. package/src/indexed/to-snapshot.ts +156 -6
  349. package/src/link-prediction/common-neighbors-legacy.ts +252 -0
  350. package/src/link-prediction/common-neighbors.ts +65 -168
  351. package/src/optimized/direction-optimized-bfs.ts +6 -1
  352. package/src/research/grsbm-legacy.ts +586 -0
  353. package/src/research/grsbm.ts +76 -555
  354. package/src/research/sync-legacy.ts +456 -0
  355. package/src/research/sync.ts +30 -431
@@ -0,0 +1,498 @@
1
+ import type { Graph } from "../core/graph.js";
2
+ import type { NodeId } from "../types/index.js";
3
+
4
+ /**
5
+ * Markov Clustering (MCL) algorithm implementation
6
+ *
7
+ * MCL simulates flow in graphs and finds clusters based on the notion that
8
+ * random walks stay within clusters and rarely move between clusters.
9
+ * The algorithm alternates between expansion (matrix squaring) and
10
+ * inflation (element-wise powering and normalization).
11
+ *
12
+ * Time complexity: O(V³) per iteration
13
+ * Space complexity: O(V²)
14
+ */
15
+
16
+ export interface MCLOptions {
17
+ expansion?: number; // Expansion parameter (default: 2)
18
+ inflation?: number; // Inflation parameter (default: 2)
19
+ maxIterations?: number; // Maximum iterations (default: 100)
20
+ tolerance?: number; // Convergence tolerance (default: 1e-6)
21
+ pruningThreshold?: number; // Pruning threshold (default: 1e-5)
22
+ selfLoops?: boolean; // Add self-loops (default: true)
23
+ }
24
+
25
+ export interface MCLResult {
26
+ communities: NodeId[][];
27
+ attractors: Set<NodeId>; // Attractor nodes (cluster representatives)
28
+ iterations: number;
29
+ converged: boolean;
30
+ }
31
+
32
+ /**
33
+ * Perform Markov Clustering on a graph
34
+ * @param graph - The input graph to cluster
35
+ * @param options - MCL algorithm options (expansion, inflation, iterations, etc.)
36
+ * @returns MCL clustering result with communities, attractors, and convergence info
37
+ */
38
+ export function markovClustering(graph: Graph, options: MCLOptions = {}): MCLResult {
39
+ const {
40
+ expansion = 2,
41
+ inflation = 2,
42
+ maxIterations = 100,
43
+ tolerance = 1e-6,
44
+ pruningThreshold = 1e-5,
45
+ selfLoops = true,
46
+ } = options;
47
+
48
+ const nodes = Array.from(graph.nodes());
49
+ const nodeIds = nodes.map((node) => node.id);
50
+ const n = nodeIds.length;
51
+
52
+ if (n === 0) {
53
+ return {
54
+ communities: [],
55
+ attractors: new Set(),
56
+ iterations: 0,
57
+ converged: true,
58
+ };
59
+ }
60
+
61
+ // Build initial transition matrix
62
+ let matrix = buildTransitionMatrix(graph, nodeIds, selfLoops);
63
+
64
+ let converged = false;
65
+ let iteration = 0;
66
+
67
+ for (iteration = 0; iteration < maxIterations; iteration++) {
68
+ const oldMatrix = matrix.map((row) => [...row]);
69
+
70
+ // Expansion step (matrix multiplication)
71
+ matrix = matrixPower(matrix, expansion);
72
+
73
+ // Inflation step (element-wise powering and column normalization)
74
+ matrix = inflate(matrix, inflation);
75
+
76
+ // Pruning step (remove small values)
77
+ matrix = prune(matrix, pruningThreshold);
78
+
79
+ // Check for convergence
80
+ if (hasConverged(oldMatrix, matrix, tolerance)) {
81
+ converged = true;
82
+ break;
83
+ }
84
+ }
85
+
86
+ // Extract clusters from final matrix
87
+ const { communities, attractors } = extractClusters(matrix, nodeIds);
88
+
89
+ return {
90
+ communities,
91
+ attractors,
92
+ iterations: iteration + 1,
93
+ converged,
94
+ };
95
+ }
96
+
97
+ /**
98
+ * Build initial transition matrix from graph
99
+ * @param graph - The input graph
100
+ * @param nodeIds - Array of node IDs in the graph
101
+ * @param selfLoops - Whether to add self-loops to the matrix
102
+ * @returns Column-normalized transition matrix
103
+ */
104
+ function buildTransitionMatrix(graph: Graph, nodeIds: NodeId[], selfLoops: boolean): number[][] {
105
+ const n = nodeIds.length;
106
+ const matrix = Array.from({ length: n }, (): number[] => Array(n).fill(0) as number[]);
107
+ const nodeToIndex = new Map<NodeId, number>();
108
+
109
+ nodeIds.forEach((id, index) => nodeToIndex.set(id, index));
110
+
111
+ // Fill adjacency values
112
+ for (let i = 0; i < n; i++) {
113
+ const nodeId = nodeIds[i];
114
+ if (nodeId === undefined) {
115
+ continue;
116
+ }
117
+
118
+ const neighbors = graph.neighbors(nodeId);
119
+
120
+ for (const neighbor of neighbors) {
121
+ const j = nodeToIndex.get(neighbor);
122
+ if (j !== undefined) {
123
+ const edge = graph.getEdge(nodeId, neighbor);
124
+ const weight = edge?.weight ?? 1;
125
+ const row = matrix[i];
126
+ if (!row) {
127
+ continue;
128
+ }
129
+
130
+ row[j] = weight;
131
+ }
132
+ }
133
+
134
+ // Add self-loops
135
+ if (selfLoops) {
136
+ const row = matrix[i];
137
+ if (!row) {
138
+ continue;
139
+ }
140
+
141
+ row[i] = 1;
142
+ }
143
+ }
144
+
145
+ // Column-normalize the matrix
146
+ for (let j = 0; j < n; j++) {
147
+ let colSum = 0;
148
+ for (let i = 0; i < n; i++) {
149
+ const val = matrix[i]?.[j];
150
+ if (val !== undefined) {
151
+ colSum += val;
152
+ }
153
+ }
154
+
155
+ if (colSum > 0) {
156
+ for (let i = 0; i < n; i++) {
157
+ const row = matrix[i];
158
+ if (!row) {
159
+ continue;
160
+ }
161
+
162
+ const val = row[j];
163
+ if (val !== undefined) {
164
+ row[j] = val / colSum;
165
+ }
166
+ }
167
+ }
168
+ }
169
+
170
+ return matrix;
171
+ }
172
+
173
+ /**
174
+ * Raise matrix to a power (for expansion step)
175
+ * @param matrix - Input square matrix
176
+ * @param power - Power to raise the matrix to
177
+ * @returns Matrix raised to the specified power
178
+ */
179
+ function matrixPower(matrix: number[][], power: number): number[][] {
180
+ if (power === 1) {
181
+ return matrix;
182
+ }
183
+
184
+ if (power === 2) {
185
+ return matrixMultiply(matrix, matrix);
186
+ }
187
+
188
+ let result = matrix;
189
+ for (let i = 1; i < power; i++) {
190
+ result = matrixMultiply(result, matrix);
191
+ }
192
+ return result;
193
+ }
194
+
195
+ /**
196
+ * Multiply two matrices
197
+ * @param a - First matrix
198
+ * @param b - Second matrix
199
+ * @returns Product matrix a * b
200
+ */
201
+ function matrixMultiply(a: number[][], b: number[][]): number[][] {
202
+ const n = a.length;
203
+ const m = b[0]?.length ?? 0;
204
+ const p = b.length;
205
+
206
+ const result: number[][] = Array.from({ length: n }, () => Array(m).fill(0) as number[]);
207
+
208
+ for (let i = 0; i < n; i++) {
209
+ for (let j = 0; j < m; j++) {
210
+ for (let k = 0; k < p; k++) {
211
+ const aVal = a[i]?.[k] ?? 0;
212
+ const bVal = b[k]?.[j] ?? 0;
213
+ const resultRow = result[i];
214
+ if (!resultRow) {
215
+ continue;
216
+ }
217
+
218
+ const prevVal = resultRow[j];
219
+ if (prevVal !== undefined) {
220
+ resultRow[j] = prevVal + aVal * bVal;
221
+ }
222
+ }
223
+ }
224
+ }
225
+
226
+ return result;
227
+ }
228
+
229
+ /**
230
+ * Inflation step: element-wise powering and column normalization
231
+ * @param matrix - Input matrix to inflate
232
+ * @param inflation - Inflation parameter for element-wise powering
233
+ * @returns Inflated and column-normalized matrix
234
+ */
235
+ function inflate(matrix: number[][], inflation: number): number[][] {
236
+ const n = matrix.length;
237
+ const result: number[][] = Array.from({ length: n }, () => Array(n).fill(0) as number[]);
238
+
239
+ // Element-wise powering
240
+ for (let i = 0; i < n; i++) {
241
+ for (let j = 0; j < n; j++) {
242
+ const val = matrix[i]?.[j];
243
+ if (val !== undefined) {
244
+ const resultRow = result[i];
245
+ if (resultRow) {
246
+ resultRow[j] = Math.pow(val, inflation);
247
+ }
248
+ }
249
+ }
250
+ }
251
+
252
+ // Column normalization
253
+ for (let j = 0; j < n; j++) {
254
+ let colSum = 0;
255
+ for (let i = 0; i < n; i++) {
256
+ const val = result[i]?.[j];
257
+ if (val !== undefined) {
258
+ colSum += val;
259
+ }
260
+ }
261
+
262
+ if (colSum > 0) {
263
+ for (let i = 0; i < n; i++) {
264
+ const row = result[i];
265
+ if (!row) {
266
+ continue;
267
+ }
268
+
269
+ const val = row[j];
270
+ if (val !== undefined) {
271
+ row[j] = val / colSum;
272
+ }
273
+ }
274
+ }
275
+ }
276
+
277
+ return result;
278
+ }
279
+
280
+ /**
281
+ * Pruning step: remove small values
282
+ * @param matrix - Input matrix to prune
283
+ * @param threshold - Values below this threshold are set to zero
284
+ * @returns Pruned and re-normalized matrix
285
+ */
286
+ function prune(matrix: number[][], threshold: number): number[][] {
287
+ const n = matrix.length;
288
+ const result: number[][] = Array.from({ length: n }, () => Array(n).fill(0) as number[]);
289
+
290
+ for (let i = 0; i < n; i++) {
291
+ for (let j = 0; j < n; j++) {
292
+ const matrixRow = matrix[i];
293
+ if (!matrixRow) {
294
+ continue;
295
+ }
296
+
297
+ const matrixVal = matrixRow[j];
298
+ if (matrixVal !== undefined && matrixVal >= threshold) {
299
+ const resultRow = result[i];
300
+ if (resultRow) {
301
+ resultRow[j] = matrixVal;
302
+ }
303
+ }
304
+ }
305
+ }
306
+
307
+ // Re-normalize columns after pruning
308
+ for (let j = 0; j < n; j++) {
309
+ let colSum = 0;
310
+ for (let i = 0; i < n; i++) {
311
+ const resultRow = result[i];
312
+ if (!resultRow) {
313
+ continue;
314
+ }
315
+
316
+ const val = resultRow[j];
317
+ if (val !== undefined) {
318
+ colSum += val;
319
+ }
320
+ }
321
+
322
+ if (colSum > 0) {
323
+ for (let i = 0; i < n; i++) {
324
+ const resultRow = result[i];
325
+ if (!resultRow) {
326
+ continue;
327
+ }
328
+
329
+ const val = resultRow[j];
330
+ if (val !== undefined) {
331
+ resultRow[j] = val / colSum;
332
+ }
333
+ }
334
+ }
335
+ }
336
+
337
+ return result;
338
+ }
339
+
340
+ /**
341
+ * Check if the algorithm has converged
342
+ * @param oldMatrix - Matrix from previous iteration
343
+ * @param newMatrix - Matrix from current iteration
344
+ * @param tolerance - Convergence tolerance threshold
345
+ * @returns True if the maximum difference between matrices is below tolerance
346
+ */
347
+ function hasConverged(oldMatrix: number[][], newMatrix: number[][], tolerance: number): boolean {
348
+ const n = oldMatrix.length;
349
+
350
+ for (let i = 0; i < n; i++) {
351
+ for (let j = 0; j < n; j++) {
352
+ const oldRow = oldMatrix[i];
353
+ const newRow = newMatrix[i];
354
+ if (!oldRow || !newRow) {
355
+ continue;
356
+ }
357
+
358
+ const oldVal = oldRow[j];
359
+ const newVal = newRow[j];
360
+ if (oldVal !== undefined && newVal !== undefined && Math.abs(oldVal - newVal) > tolerance) {
361
+ return false;
362
+ }
363
+ }
364
+ }
365
+
366
+ return true;
367
+ }
368
+
369
+ /**
370
+ * Extract clusters from the final matrix
371
+ * @param matrix - Final converged MCL matrix
372
+ * @param nodeIds - Array of node IDs corresponding to matrix indices
373
+ * @returns Object containing communities and attractor nodes
374
+ */
375
+ function extractClusters(
376
+ matrix: number[][],
377
+ nodeIds: NodeId[],
378
+ ): {
379
+ communities: NodeId[][];
380
+ attractors: Set<NodeId>;
381
+ } {
382
+ const n = matrix.length;
383
+ const attractors = new Set<NodeId>();
384
+ const communities: NodeId[][] = [];
385
+ const nodeToCluster = new Map<number, number>();
386
+
387
+ // Find attractors (columns with non-zero diagonal elements)
388
+ for (let i = 0; i < n; i++) {
389
+ const matrixRow = matrix[i];
390
+ if (!matrixRow) {
391
+ continue;
392
+ }
393
+
394
+ const diagonalVal = matrixRow[i];
395
+ const nodeId = nodeIds[i];
396
+ if (diagonalVal !== undefined && diagonalVal > 0 && nodeId !== undefined) {
397
+ attractors.add(nodeId);
398
+ }
399
+ }
400
+
401
+ // Assign nodes (columns) to clusters based on which attractor (row) they flow to
402
+ // After MCL convergence, matrix[i][j] > 0 means node j belongs to attractor i's cluster
403
+ const attractorToCommunity = new Map<number, number[]>();
404
+
405
+ for (let j = 0; j < n; j++) {
406
+ // Find the attractor for this column (node j)
407
+ // Look for the row with the highest non-zero value in column j
408
+ let maxVal = 0;
409
+ let attractorRow = -1;
410
+
411
+ for (let i = 0; i < n; i++) {
412
+ const matrixRow = matrix[i];
413
+ if (!matrixRow) {
414
+ continue;
415
+ }
416
+
417
+ const val = matrixRow[j];
418
+ if (val !== undefined && val > maxVal) {
419
+ maxVal = val;
420
+ attractorRow = i;
421
+ }
422
+ }
423
+
424
+ if (attractorRow >= 0) {
425
+ // Node j belongs to the cluster of attractor at row attractorRow
426
+ let community = attractorToCommunity.get(attractorRow);
427
+ if (!community) {
428
+ community = [];
429
+ attractorToCommunity.set(attractorRow, community);
430
+ }
431
+ community.push(j);
432
+ nodeToCluster.set(j, attractorRow);
433
+ }
434
+ }
435
+
436
+ // Convert attractor communities to node ID arrays
437
+ for (const [, memberIndices] of attractorToCommunity) {
438
+ communities.push(
439
+ memberIndices
440
+ .map((idx) => {
441
+ const nodeId = nodeIds[idx];
442
+ return nodeId;
443
+ })
444
+ .filter((node): node is NodeId => node !== undefined),
445
+ );
446
+ }
447
+
448
+ // Handle isolated nodes (nodes with all-zero columns)
449
+ for (let j = 0; j < n; j++) {
450
+ if (!nodeToCluster.has(j)) {
451
+ const nodeId = nodeIds[j];
452
+ if (nodeId !== undefined) {
453
+ communities.push([nodeId]);
454
+ }
455
+ }
456
+ }
457
+
458
+ return { communities, attractors };
459
+ }
460
+
461
+ /**
462
+ * Calculate modularity of MCL clustering result
463
+ * @param graph - The original graph that was clustered
464
+ * @param communities - Array of communities (each community is an array of node IDs)
465
+ * @returns Modularity score between -0.5 and 1.0
466
+ */
467
+ export function calculateMCLModularity(graph: Graph, communities: NodeId[][]): number {
468
+ const m = graph.totalEdgeCount;
469
+ if (m === 0) {
470
+ return 0;
471
+ }
472
+
473
+ let modularity = 0;
474
+ const communityMap = new Map<NodeId, number>();
475
+
476
+ // Build community map
477
+ communities.forEach((community, index) => {
478
+ community.forEach((nodeId) => {
479
+ communityMap.set(nodeId, index);
480
+ });
481
+ });
482
+
483
+ // Calculate modularity
484
+ for (const edge of graph.edges()) {
485
+ const sourceCommunity = communityMap.get(edge.source);
486
+ const targetCommunity = communityMap.get(edge.target);
487
+
488
+ if (sourceCommunity !== undefined && targetCommunity !== undefined && sourceCommunity === targetCommunity) {
489
+ modularity += 1;
490
+ }
491
+
492
+ const sourceDegree = graph.degree(edge.source);
493
+ const targetDegree = graph.degree(edge.target);
494
+ modularity -= (sourceDegree * targetDegree) / (2 * m);
495
+ }
496
+
497
+ return modularity / (2 * m);
498
+ }