@graphty/algorithms 2.1.2 → 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
@@ -1,40 +1,20 @@
1
- import type { Graph } from "../core/graph.js";
2
- import type { NodeId } from "../types/index.js";
3
- import { euclideanDistance, SeededRandom } from "../utils/math-utilities.js";
4
-
5
1
  /**
6
- * Configuration options for the SynC (Synergistic Deep Graph Clustering) algorithm
2
+ * SynC (Synergistic Deep Graph Clustering) over a legacy `Graph`. `syncClustering` delegates to
3
+ * `indexed.syncClustering` over an unweighted snapshot of the graph (SynC never reads a weight);
4
+ * clusters, embeddings, loss, iterations and convergence equal the pre-migration implementation in
5
+ * `sync-legacy.ts`, the floats to rounding. A run that diverges (a large learning rate) amplifies
6
+ * that rounding, so its embeddings and loss can differ from the old code's in the leading digits. A
7
+ * cluster count that is not an integer keeps the old code, which mostly fails on one ("Invalid array
8
+ * length"). Unlike the old code the port never replaces `Math.random`.
7
9
  */
8
- export interface SynCConfig {
9
- /** Number of clusters to find */
10
- numClusters: number;
11
- /** Maximum number of iterations for convergence */
12
- maxIterations?: number;
13
- /** Convergence tolerance */
14
- tolerance?: number;
15
- /** Random seed for reproducibility */
16
- seed?: number;
17
- /** Learning rate for optimization */
18
- learningRate?: number;
19
- /** Regularization parameter */
20
- lambda?: number;
21
- }
22
10
 
23
- /**
24
- * Result of the SynC clustering algorithm
25
- */
26
- export interface SynCResult {
27
- /** Cluster assignments for each node */
28
- clusters: Map<NodeId, number>;
29
- /** Final loss value */
30
- loss: number;
31
- /** Number of iterations performed */
32
- iterations: number;
33
- /** Node embeddings learned by the algorithm */
34
- embeddings: Map<NodeId, number[]>;
35
- /** Whether the algorithm converged */
36
- converged: boolean;
37
- }
11
+ import type { Graph } from "../core/graph.js";
12
+ import { syncClustering as indexedSyncClustering } from "../indexed/sync.js";
13
+ import { toTopologySnapshot } from "../indexed/to-snapshot.js";
14
+ import type { NodeId } from "../types/index.js";
15
+ import { syncClustering as legacySyncClustering, type SynCConfig, type SynCResult } from "./sync-legacy.js";
16
+
17
+ export type { SynCConfig, SynCResult } from "./sync-legacy.js";
38
18
 
39
19
  /**
40
20
  * Synergistic Deep Graph Clustering (SynC) Algorithm
@@ -49,408 +29,27 @@ export interface SynCResult {
49
29
  * @returns Clustering result with assignments and embeddings
50
30
  */
51
31
  export function syncClustering(graph: Graph, config: SynCConfig): SynCResult {
52
- const { numClusters, maxIterations = 100, tolerance = 1e-6, seed = 42, learningRate = 0.01, lambda = 0.1 } = config;
53
-
54
- // Set random seed for reproducibility (save original)
55
- const originalRandom = Math.random;
56
- const rng = SeededRandom.createGenerator(seed);
57
- Math.random = rng;
58
-
59
- const nodes = Array.from(graph.nodes());
60
- const nodeCount = nodes.length;
61
-
62
- if (nodeCount === 0) {
63
- return {
64
- clusters: new Map(),
65
- loss: 0,
66
- iterations: 0,
67
- embeddings: new Map(),
68
- converged: true,
69
- };
32
+ if (!Number.isInteger(config.numClusters)) {
33
+ return legacySyncClustering(graph, config);
70
34
  }
35
+ const s = toTopologySnapshot(graph);
36
+ const n = s.nodeCount;
37
+ const r = indexedSyncClustering(s, config);
71
38
 
72
- if (numClusters <= 0 || numClusters > nodeCount) {
73
- throw new Error(
74
- `Invalid number of clusters: ${String(numClusters)}. Must be between 1 and ${String(nodeCount)}`,
75
- );
76
- }
77
-
78
- // Initialize node embeddings (simplified version using graph features)
79
- const embeddingDim = Math.min(64, nodeCount);
39
+ const clusters = new Map<NodeId, number>();
80
40
  const embeddings = new Map<NodeId, number[]>();
81
-
82
- // Initialize embeddings based on node features
83
- for (const node of nodes) {
84
- const embedding = initializeNodeEmbedding(graph, node.id, embeddingDim);
85
- embeddings.set(node.id, embedding);
86
- }
87
-
88
- // Initialize cluster centers
89
- const clusterCenters = initializeClusterCenters(embeddings, numClusters);
90
-
91
- let previousLoss = Infinity;
92
- let iterations = 0;
93
- let converged = false;
94
-
95
- for (iterations = 0; iterations < maxIterations; iterations++) {
96
- // E-step: Assign nodes to clusters
97
- const clusters = new Map<NodeId, number>();
98
-
99
- for (const node of nodes) {
100
- const nodeEmbedding = embeddings.get(node.id);
101
- if (!nodeEmbedding) {
102
- continue;
103
- }
104
-
105
- let bestCluster = 0;
106
- let minDistance = Infinity;
107
-
108
- for (let k = 0; k < numClusters; k++) {
109
- const center = clusterCenters[k];
110
- if (!center) {
111
- continue;
112
- }
113
-
114
- const distance = euclideanDistance(nodeEmbedding, center);
115
- if (distance < minDistance) {
116
- minDistance = distance;
117
- bestCluster = k;
118
- }
119
- }
120
-
121
- clusters.set(node.id, bestCluster);
122
- }
123
-
124
- // M-step: Update embeddings and cluster centers
125
- updateEmbeddings(graph, embeddings, clusters, learningRate, lambda);
126
- updateClusterCenters(embeddings, clusters, clusterCenters, numClusters);
127
-
128
- // Calculate current loss
129
- const currentLoss = calculateLoss(graph, embeddings, clusters, clusterCenters, lambda);
130
-
131
- // Check for convergence
132
- if (Math.abs(previousLoss - currentLoss) < tolerance) {
133
- converged = true;
134
- break;
135
- }
136
-
137
- previousLoss = currentLoss;
41
+ for (let i = 0; i < n; i++) {
42
+ const id = s.ids.idOf(i);
43
+ clusters.set(id, r.labels[i]);
44
+ embeddings.set(id, Array.from(r.embeddings.subarray(i * r.dimensions, (i + 1) * r.dimensions)));
138
45
  }
139
-
140
- // Final cluster assignment
141
- const finalClusters = new Map<NodeId, number>();
142
- for (const node of nodes) {
143
- const nodeEmbedding = embeddings.get(node.id);
144
- if (!nodeEmbedding) {
145
- continue;
146
- }
147
-
148
- let bestCluster = 0;
149
- let minDistance = Infinity;
150
-
151
- for (let k = 0; k < numClusters; k++) {
152
- const center = clusterCenters[k];
153
- if (!center) {
154
- continue;
155
- }
156
-
157
- const distance = euclideanDistance(nodeEmbedding, center);
158
- if (distance < minDistance) {
159
- minDistance = distance;
160
- bestCluster = k;
161
- }
162
- }
163
-
164
- finalClusters.set(node.id, bestCluster);
165
- }
166
-
167
- // Restore original random function
168
- Math.random = originalRandom;
169
-
170
46
  return {
171
- clusters: finalClusters,
172
- loss: previousLoss,
173
- iterations: iterations + 1,
47
+ clusters,
48
+ // The old code reported the loss of the round before the converging one.
49
+ loss: r.converged && r.iterations > 1 ? r.previousLoss : r.loss,
50
+ // ...and one round more than it ran when it stopped at the cap.
51
+ iterations: r.iterations + (r.converged ? 0 : 1),
174
52
  embeddings,
175
- converged,
53
+ converged: r.converged,
176
54
  };
177
55
  }
178
-
179
- /**
180
- * Initialize node embedding based on graph structure and features
181
- * @param graph - The input graph
182
- * @param nodeId - The node ID to initialize embedding for
183
- * @param dim - The embedding dimension
184
- * @returns The initialized embedding vector
185
- */
186
- function initializeNodeEmbedding(graph: Graph, nodeId: NodeId, dim: number): number[] {
187
- const embedding = new Array<number>(dim).fill(0);
188
-
189
- // Use node degree as a base feature
190
- const degree = graph.degree(nodeId);
191
- const normalizedDegree = degree / Math.max(1, graph.nodeCount - 1);
192
-
193
- // Initialize with small random values influenced by graph structure
194
- for (let i = 0; i < dim; i++) {
195
- embedding[i] = (Math.random() - 0.5) * 0.1 + normalizedDegree * 0.1;
196
- }
197
-
198
- return embedding;
199
- }
200
-
201
- /**
202
- * Initialize cluster centers using k-means++ style initialization
203
- * @param embeddings - Map of node IDs to embedding vectors
204
- * @param numClusters - Number of cluster centers to initialize
205
- * @returns Array of initialized cluster center vectors
206
- */
207
- function initializeClusterCenters(embeddings: Map<NodeId, number[]>, numClusters: number): number[][] {
208
- const embeddingArray = Array.from(embeddings.values());
209
- const centers: number[][] = [];
210
-
211
- // Choose first center randomly
212
- const firstCenter = embeddingArray[Math.floor(Math.random() * embeddingArray.length)];
213
- if (firstCenter) {
214
- centers.push([...firstCenter] as number[]);
215
- }
216
-
217
- // Choose remaining centers using k-means++ initialization
218
- for (let k = 1; k < numClusters; k++) {
219
- const distances: number[] = [];
220
- let totalDistance = 0;
221
-
222
- for (const embedding of embeddingArray) {
223
- let minDistance = Infinity;
224
- for (const center of centers) {
225
- const distance = euclideanDistance(embedding, center);
226
- minDistance = Math.min(minDistance, distance);
227
- }
228
- distances.push(minDistance * minDistance);
229
- totalDistance += minDistance * minDistance;
230
- }
231
-
232
- // Choose next center with probability proportional to squared distance
233
- let randomValue = Math.random() * totalDistance;
234
- for (let i = 0; i < embeddingArray.length; i++) {
235
- const distanceValue = distances[i];
236
- if (distanceValue !== undefined) {
237
- randomValue -= distanceValue;
238
- }
239
-
240
- if (randomValue <= 0) {
241
- const newCenter = embeddingArray[i];
242
- if (newCenter) {
243
- centers.push([...newCenter] as number[]);
244
- }
245
-
246
- break;
247
- }
248
- }
249
- }
250
-
251
- return centers;
252
- }
253
-
254
- /**
255
- * Update node embeddings using gradient descent
256
- * @param graph - The input graph
257
- * @param embeddings - Map of node IDs to embedding vectors
258
- * @param _clusters - Map of node IDs to cluster assignments (reserved for future use)
259
- * @param learningRate - Learning rate for gradient descent
260
- * @param lambda - Regularization parameter
261
- */
262
- function updateEmbeddings(
263
- graph: Graph,
264
- embeddings: Map<NodeId, number[]>,
265
- _clusters: Map<NodeId, number>,
266
- learningRate: number,
267
- lambda: number,
268
- ): void {
269
- const gradients = new Map<NodeId, number[]>();
270
-
271
- // Initialize gradients
272
- for (const [nodeId, embedding] of embeddings) {
273
- gradients.set(nodeId, new Array<number>(embedding.length).fill(0));
274
- }
275
-
276
- // Calculate gradients based on graph structure (simplified)
277
- for (const node of graph.nodes()) {
278
- const nodeId = node.id;
279
- const nodeEmbedding = embeddings.get(nodeId);
280
- if (!nodeEmbedding) {
281
- continue;
282
- }
283
-
284
- const gradient = gradients.get(nodeId);
285
- if (!gradient) {
286
- continue;
287
- }
288
-
289
- // Neighbor reconstruction loss gradient
290
- for (const neighborId of graph.neighbors(nodeId)) {
291
- const neighborEmbedding = embeddings.get(neighborId);
292
- if (!neighborEmbedding) {
293
- continue;
294
- }
295
-
296
- const diff = nodeEmbedding.map((val: number, i: number) => val - (neighborEmbedding[i] ?? 0));
297
-
298
- for (let i = 0; i < gradient.length; i++) {
299
- const gradVal = gradient[i];
300
- const diffVal = diff[i];
301
- if (gradVal !== undefined && diffVal !== undefined) {
302
- gradient[i] = gradVal + lambda * diffVal;
303
- }
304
- }
305
- }
306
-
307
- // Regularization gradient
308
- for (let i = 0; i < gradient.length; i++) {
309
- const gradVal = gradient[i];
310
- const nodeVal = nodeEmbedding[i];
311
- if (gradVal !== undefined && nodeVal !== undefined) {
312
- gradient[i] = gradVal + lambda * nodeVal;
313
- }
314
- }
315
- }
316
-
317
- // Update embeddings
318
- for (const [nodeId, embedding] of embeddings) {
319
- const gradient = gradients.get(nodeId);
320
- if (!gradient) {
321
- continue;
322
- }
323
-
324
- for (let i = 0; i < embedding.length; i++) {
325
- const embVal = embedding[i];
326
- const gradVal = gradient[i];
327
- if (embVal !== undefined && gradVal !== undefined) {
328
- embedding[i] = embVal - learningRate * gradVal;
329
- }
330
- }
331
- }
332
- }
333
-
334
- /**
335
- * Update cluster centers based on current assignments
336
- * @param embeddings - Map of node IDs to embedding vectors
337
- * @param clusters - Map of node IDs to cluster assignments
338
- * @param clusterCenters - Array of cluster center vectors to update
339
- * @param numClusters - Number of clusters
340
- */
341
- function updateClusterCenters(
342
- embeddings: Map<NodeId, number[]>,
343
- clusters: Map<NodeId, number>,
344
- clusterCenters: number[][],
345
- numClusters: number,
346
- ): void {
347
- const dimensions = clusterCenters[0]?.length ?? 0;
348
- const clusterSums: number[][] = Array.from(
349
- { length: numClusters },
350
- () => new Array(dimensions).fill(0) as number[],
351
- );
352
- const clusterCounts = new Array<number>(numClusters).fill(0);
353
-
354
- // Sum embeddings for each cluster
355
- for (const [nodeId, clusterIdx] of clusters) {
356
- const embedding = embeddings.get(nodeId);
357
- if (!embedding) {
358
- continue;
359
- }
360
-
361
- for (let i = 0; i < embedding.length; i++) {
362
- const clusterSum = clusterSums[clusterIdx];
363
- if (!clusterSum) {
364
- continue;
365
- }
366
-
367
- const sumVal = clusterSum[i];
368
- const embVal = embedding[i];
369
- if (sumVal !== undefined && embVal !== undefined) {
370
- clusterSum[i] = sumVal + embVal;
371
- }
372
- }
373
- if (clusterCounts[clusterIdx] !== undefined) {
374
- clusterCounts[clusterIdx]++;
375
- }
376
- }
377
-
378
- // Update cluster centers (average of assigned embeddings)
379
- for (let k = 0; k < numClusters; k++) {
380
- const count = clusterCounts[k];
381
- const center = clusterCenters[k];
382
- const sum = clusterSums[k];
383
- if (count !== undefined && count > 0 && center && sum) {
384
- for (let i = 0; i < center.length; i++) {
385
- const sumVal = sum[i];
386
- if (sumVal !== undefined) {
387
- center[i] = sumVal / count;
388
- }
389
- }
390
- }
391
- }
392
- }
393
-
394
- /**
395
- * Calculate the total loss function
396
- * @param graph - The input graph
397
- * @param embeddings - Map of node IDs to embedding vectors
398
- * @param clusters - Map of node IDs to cluster assignments
399
- * @param clusterCenters - Array of cluster center vectors
400
- * @param lambda - Regularization parameter
401
- * @returns The total loss value
402
- */
403
- function calculateLoss(
404
- graph: Graph,
405
- embeddings: Map<NodeId, number[]>,
406
- clusters: Map<NodeId, number>,
407
- clusterCenters: number[][],
408
- lambda: number,
409
- ): number {
410
- let clusteringLoss = 0;
411
- let reconstructionLoss = 0;
412
- let regularizationLoss = 0;
413
-
414
- // Clustering loss (distance to cluster centers)
415
- for (const [nodeId, clusterIdx] of clusters) {
416
- const embedding = embeddings.get(nodeId);
417
- if (!embedding) {
418
- continue;
419
- }
420
-
421
- const center = clusterCenters[clusterIdx];
422
- if (!center) {
423
- continue;
424
- }
425
-
426
- clusteringLoss += euclideanDistance(embedding, center) ** 2;
427
- }
428
-
429
- // Graph reconstruction loss
430
- for (const node of graph.nodes()) {
431
- const nodeId = node.id;
432
- const nodeEmbedding = embeddings.get(nodeId);
433
- if (!nodeEmbedding) {
434
- continue;
435
- }
436
-
437
- for (const neighborId of graph.neighbors(nodeId)) {
438
- const neighborEmbedding = embeddings.get(neighborId);
439
- if (!neighborEmbedding) {
440
- continue;
441
- }
442
-
443
- const distance = euclideanDistance(nodeEmbedding, neighborEmbedding);
444
- reconstructionLoss += distance ** 2;
445
- }
446
- }
447
-
448
- // Regularization loss
449
- for (const embedding of embeddings.values()) {
450
- for (const value of embedding) {
451
- regularizationLoss += value ** 2;
452
- }
453
- }
454
-
455
- return clusteringLoss + lambda * reconstructionLoss + lambda * regularizationLoss;
456
- }