@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
@@ -0,0 +1,188 @@
1
+ import { maskTest } from "@graphty/graph-format";
2
+ /** The seed of the `k` draw. Any fixed value works: the draw only has to repeat. */
3
+ const SAMPLE_SEED = 0x9e3779b9;
4
+ /**
5
+ * `k` distinct node indices by a partial Fisher-Yates shuffle over a fixed-seed mulberry32 stream, so the same
6
+ * `(n, k)` draws the same sources every time.
7
+ * @param n - The node count
8
+ * @param k - How many to draw, at most n
9
+ * @returns The sources
10
+ */
11
+ function drawSources(n, k) {
12
+ const pool = Array.from({ length: n }, (_, i) => i);
13
+ let state = SAMPLE_SEED;
14
+ for (let i = 0; i < k; i++) {
15
+ state = (state + 0x6d2b79f5) >>> 0;
16
+ let t = Math.imul(state ^ (state >>> 15), state | 1);
17
+ t = (t + Math.imul(t ^ (t >>> 7), t | 61)) ^ t;
18
+ const unit = ((t ^ (t >>> 14)) >>> 0) / 2 ** 32;
19
+ const j = i + Math.floor(unit * (n - i));
20
+ [pool[i], pool[j]] = [pool[j], pool[i]];
21
+ }
22
+ return pool.slice(0, k);
23
+ }
24
+ /**
25
+ * The sources a call runs: `sources` as given, else `k` drawn, else every node.
26
+ * @param n - The node count
27
+ * @param sources - The caller's list
28
+ * @param k - The caller's count
29
+ * @returns The sources
30
+ * @throws RangeError for a source outside `[0, n)`, a `k` outside `[0, n]`, or a `k` that disagrees with the list
31
+ */
32
+ export function resolveSources(n, sources, k) {
33
+ if (k !== undefined && (!Number.isInteger(k) || k < 0 || k > n)) {
34
+ throw new RangeError(`betweenness: k must be an integer in [0, ${n}], got ${k}`);
35
+ }
36
+ if (sources !== undefined) {
37
+ for (const v of sources) {
38
+ if (!Number.isInteger(v) || v < 0 || v >= n) {
39
+ throw new RangeError(`betweenness: sources must be node indices in [0, ${n}), got ${v}`);
40
+ }
41
+ }
42
+ if (k !== undefined && k !== sources.length) {
43
+ throw new RangeError(`betweenness: k (${k}) must be absent or equal sources.length (${sources.length})`);
44
+ }
45
+ return sources;
46
+ }
47
+ return k === undefined ? Array.from({ length: n }, (_, i) => i) : drawSources(n, k);
48
+ }
49
+ /**
50
+ * Brandes' accumulation from every source, into `node` and/or `edge` (raw sums, before halving or
51
+ * normalising).
52
+ *
53
+ * A pair joined by parallel edges is ONE neighbour relation (graph-format design 3.5, the adjacent-skip idiom),
54
+ * so path counts are the simple graph's and equal the legacy function's. The pair's share of an edge score goes
55
+ * to the first alive parallel edge in row order; the others score 0. Removing that edge hands the whole share to
56
+ * the next parallel, so the scores of a pair's parallels always sum to the simple graph's edge score.
57
+ * Dependencies are pulled over OUT-arcs from the deepest level up, so no reverse adjacency is built.
58
+ * @param s - The snapshot
59
+ * @param sources - Source node indices
60
+ * @param node - Node sums, or null
61
+ * @param edge - Edge sums, or null
62
+ * @param alive - Kept edges, or null for all
63
+ * @param endpoints - Count path ends on the path (node sums only)
64
+ */
65
+ function accumulate(s, sources, node, edge, alive, endpoints) {
66
+ const { nodeCount: n, rowPtr, colIdx, arcToEdge } = s;
67
+ const depth = new Int32Array(n).fill(-1);
68
+ const sigma = new Float64Array(n);
69
+ const delta = new Float64Array(n);
70
+ const order = new Uint32Array(n);
71
+ for (const source of sources) {
72
+ let head = 0;
73
+ let tail = 0;
74
+ depth[source] = 0;
75
+ sigma[source] = 1;
76
+ order[tail++] = source;
77
+ while (head < tail) {
78
+ const v = order[head++];
79
+ const next = depth[v] + 1;
80
+ let prev = -1;
81
+ for (let a = rowPtr[v], end = rowPtr[v + 1]; a < end; a++) {
82
+ const w = colIdx[a];
83
+ if (w === prev || (alive !== null && !maskTest(alive, arcToEdge[a]))) {
84
+ continue;
85
+ }
86
+ prev = w;
87
+ if (depth[w] < 0) {
88
+ depth[w] = next;
89
+ order[tail++] = w;
90
+ }
91
+ if (depth[w] === next) {
92
+ sigma[w] += sigma[v];
93
+ }
94
+ }
95
+ }
96
+ for (let i = tail - 1; i >= 0; i--) {
97
+ const v = order[i];
98
+ const next = depth[v] + 1;
99
+ let prev = -1;
100
+ for (let a = rowPtr[v], end = rowPtr[v + 1]; a < end; a++) {
101
+ const w = colIdx[a];
102
+ if (w === prev || (alive !== null && !maskTest(alive, arcToEdge[a]))) {
103
+ continue;
104
+ }
105
+ prev = w;
106
+ if (depth[w] === next) {
107
+ const c = (sigma[v] / sigma[w]) * (1 + delta[w]);
108
+ delta[v] += c;
109
+ if (edge !== null) {
110
+ edge[arcToEdge[a]] += c;
111
+ }
112
+ }
113
+ }
114
+ if (node !== null && v !== source) {
115
+ node[v] += endpoints ? delta[v] + 1 : delta[v];
116
+ }
117
+ }
118
+ if (node !== null && endpoints) {
119
+ node[source] += tail - 1;
120
+ }
121
+ for (let i = 0; i < tail; i++) {
122
+ const v = order[i];
123
+ depth[v] = -1;
124
+ sigma[v] = 0;
125
+ delta[v] = 0;
126
+ }
127
+ }
128
+ }
129
+ /**
130
+ * Halve on an undirected snapshot (each unordered pair was counted from both ends) and divide by `factor` when
131
+ * normalising and it is positive.
132
+ * @param s - The snapshot
133
+ * @param scores - The raw sums, scaled in place
134
+ * @param normalized - Whether to normalise
135
+ * @param factor - The directed pair count to normalise by
136
+ */
137
+ function scale(s, scores, normalized, factor) {
138
+ // Undirected: halving and then dividing by half the directed pair count is dividing by the whole count.
139
+ const halve = s.directed ? 1 : 2;
140
+ const divisor = normalized === true && factor > 0 ? factor : halve;
141
+ for (let i = 0; i < scores.length; i++) {
142
+ scores[i] /= divisor;
143
+ }
144
+ }
145
+ /**
146
+ * Node betweenness centrality by Brandes' algorithm: breadth-first, so weights are ignored, as in the legacy
147
+ * `betweennessCentrality`, whose scores this equals on every graph it can hold. A sampled run (`sources` or `k`)
148
+ * is the UNSCALED sum over the sources run, as the WebGPU accelerator reports it.
149
+ * @param s - The snapshot
150
+ * @param options - Normalisation, endpoints and sampling
151
+ * @returns One score per node index; `iterations` is the number of sources run
152
+ * @throws RangeError for a bad `sources` or `k`
153
+ * @public
154
+ */
155
+ export function betweennessCentrality(s, options = {}) {
156
+ const n = s.nodeCount;
157
+ const sources = resolveSources(n, options.sources, options.k);
158
+ const scores = new Float64Array(n);
159
+ const endpoints = options.endpoints === true;
160
+ accumulate(s, sources, scores, null, null, endpoints);
161
+ scale(s, scores, options.normalized, endpoints ? n * (n - 1) : (n - 1) * (n - 2));
162
+ return { scores, iterations: sources.length, converged: true };
163
+ }
164
+ /**
165
+ * Edge betweenness centrality by Brandes' algorithm, one score per logical edge.
166
+ *
167
+ * On a directed snapshot an edge's score equals the legacy `edgeBetweennessCentrality` value keyed
168
+ * `"source-target"`. On an undirected one it is the number of pairs whose shortest paths cross the edge in
169
+ * either direction, which is the SUM of the two values the legacy function reports under `"u-v"` and `"v-u"`
170
+ * (each of those holds half), and is the score the WebGPU accelerator returns.
171
+ * @param s - The snapshot
172
+ * @param options - Normalisation, sampling and the alive-edge mask
173
+ * @returns One score per logical edge
174
+ * @throws RangeError for a bad `sources` or `k`, or an `alive` mask shorter than the edge count
175
+ * @public
176
+ */
177
+ export function edgeBetweennessCentrality(s, options = {}) {
178
+ const n = s.nodeCount;
179
+ const alive = options.alive ?? null;
180
+ if (alive !== null && alive.length < Math.ceil(s.edgeCount / 32)) {
181
+ throw new RangeError(`edgeBetweennessCentrality: alive covers fewer than ${s.edgeCount} edges`);
182
+ }
183
+ const scores = new Float64Array(s.edgeCount);
184
+ accumulate(s, resolveSources(n, options.sources, options.k), null, scores, alive, false);
185
+ scale(s, scores, options.normalized, (n - 1) * (n - 2));
186
+ return { scores };
187
+ }
188
+ //# sourceMappingURL=betweenness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"betweenness.js","sourceRoot":"","sources":["../../../src/indexed/betweenness.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { type AdjacencyView, type U32 } from "@graphty/graph-format";
1
+ import { type AdjacencyView, type GraphSnapshot, type U32 } from "@graphty/graph-format";
2
2
  /** Result of the index-based BFS (graph-format design 14.2 Port 1). @public */
3
3
  export interface BfsResult {
4
4
  /** Visit order, one entry per visited node; a subarray of length `visitedCount`. */
@@ -10,11 +10,53 @@ export interface BfsResult {
10
10
  /** How many nodes were visited. */
11
11
  readonly visitedCount: number;
12
12
  }
13
+ /** The neighbour-order option the order-sensitive traversals share. @public */
14
+ export interface ArcOrderOption {
15
+ /**
16
+ * A permutation of the arc indices, `arcCount` long, whose slice `[rowPtr[u], rowPtr[u + 1])`
17
+ * lists node `u`'s arcs in the order to try them. The default is row order (ascending neighbour
18
+ * index). A caller that must reproduce a traversal over another neighbour order -- a legacy
19
+ * `Graph` hands out neighbours in insertion order -- passes that order here.
20
+ */
21
+ readonly arcOrder?: U32 | undefined;
22
+ }
13
23
  /** Options of the index-based BFS. @public */
14
- export interface BfsOptions {
24
+ export interface BfsOptions extends ArcOrderOption {
15
25
  /** Stop expanding at this depth; unbounded when omitted. */
16
26
  readonly maxDepth?: number | undefined;
27
+ /**
28
+ * Stop when this node index is taken off the queue, before its neighbours are expanded. Every
29
+ * node discovered by then stays in `order`; the target's own position in `order` ends the
30
+ * prefix of nodes that were expanded.
31
+ * @throws RangeError when it is not a node index
32
+ */
33
+ readonly target?: number | undefined;
17
34
  }
35
+ /**
36
+ * Check a start (or target) node index.
37
+ * @param g - The adjacency
38
+ * @param start - The node index
39
+ * @param what - What the index is, for the error message
40
+ * @throws RangeError when `start` is not a node index of `g`
41
+ */
42
+ export declare function checkStart(g: AdjacencyView, start: number, what?: string): void;
43
+ /**
44
+ * Check an optional target node index.
45
+ * @param g - The adjacency
46
+ * @param target - The option, or undefined
47
+ * @returns The target, or INVALID_INDEX for none
48
+ * @throws RangeError when `target` is set and is not a node index of `g`
49
+ */
50
+ export declare function checkTarget(g: AdjacencyView, target: number | undefined): number;
51
+ /**
52
+ * Check an `arcOrder` option: `arcCount` entries, and every row's slice a permutation of that row's
53
+ * arcs.
54
+ * @param g - The adjacency
55
+ * @param arcOrder - The option, or undefined
56
+ * @returns The order, or null for row order
57
+ * @throws RangeError when the order does not fit the adjacency
58
+ */
59
+ export declare function checkArcOrder(g: AdjacencyView, arcOrder: U32 | undefined): U32 | null;
18
60
  /**
19
61
  * Breadth-first search over out-neighbours. Takes any `AdjacencyView`, so `s.reverse()` gives an
20
62
  * in-neighbour BFS with no extra code.
@@ -25,4 +67,29 @@ export interface BfsOptions {
25
67
  * @public
26
68
  */
27
69
  export declare function breadthFirstSearch(g: AdjacencyView, start: number, options?: BfsOptions): BfsResult;
70
+ /** Options of {@link directionOptimizedBfs}. @public */
71
+ export interface DirectionOptimizedBfsOptions {
72
+ /**
73
+ * Switch from top-down to bottom-up once the frontier's out-arcs exceed the unvisited nodes'
74
+ * out-arcs divided by `alpha`. Default 15.
75
+ */
76
+ readonly alpha?: number | undefined;
77
+ /** Switch back to top-down once the frontier shrinks below `nodeCount / beta` nodes. Default 18. */
78
+ readonly beta?: number | undefined;
79
+ }
80
+ /**
81
+ * Direction-optimising breadth-first search (Beamer, Asanovic and Patterson, SC'12): a top-down
82
+ * step expands the frontier's out-arcs, a bottom-up step has every unvisited node look for a
83
+ * frontier node among its in-neighbours over `s.reverse()` (fetched only when a bottom-up step
84
+ * runs), and the search switches between the two
85
+ * by frontier size. Both steps give a node the LOWEST-index frontier node that reaches it as its
86
+ * parent, so the result does not depend on which steps ran: `depth` equals `breadthFirstSearch`'s,
87
+ * and `order` lists the visited nodes level by level, ascending within a level.
88
+ * @param s - The snapshot to traverse
89
+ * @param source - The node index to start from
90
+ * @param options - The switching thresholds
91
+ * @returns The visit order, the parent array, the depth array and the visited count
92
+ * @public
93
+ */
94
+ export declare function directionOptimizedBfs(s: GraphSnapshot, source: number, options?: DirectionOptimizedBfsOptions): BfsResult;
28
95
  //# sourceMappingURL=bfs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bfs.d.ts","sourceRoot":"","sources":["../../../src/indexed/bfs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAiB,KAAK,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAEpF,+EAA+E;AAC/E,MAAM,WAAW,SAAS;IACtB,oFAAoF;IACpF,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC;IACpB,sFAAsF;IACtF,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC;IACpB,mCAAmC;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CACjC;AAED,8CAA8C;AAC9C,MAAM,WAAW,UAAU;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,SAAS,CA2BvG"}
1
+ {"version":3,"file":"bfs.d.ts","sourceRoot":"","sources":["../../../src/indexed/bfs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAiB,KAAK,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAExG,+EAA+E;AAC/E,MAAM,WAAW,SAAS;IACtB,oFAAoF;IACpF,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC;IACpB,sFAAsF;IACtF,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC;IACpB,mCAAmC;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CACjC;AAED,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,GAAG,GAAG,SAAS,CAAC;CACvC;AAED,8CAA8C;AAC9C,MAAM,WAAW,UAAW,SAAQ,cAAc;IAC9C,4DAA4D;IAC5D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,SAAU,GAAG,IAAI,CAIhF;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAMhF;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,GAAG,SAAS,GAAG,GAAG,GAAG,IAAI,CA2BrF;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,SAAS,CAiCvG;AAED,wDAAwD;AACxD,MAAM,WAAW,4BAA4B;IACzC;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,oGAAoG;IACpG,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACjC,CAAC,EAAE,aAAa,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,4BAAiC,GAC3C,SAAS,CAkEX"}
@@ -1,4 +1,62 @@
1
1
  import { INVALID_INDEX } from "@graphty/graph-format";
2
+ /**
3
+ * Check a start (or target) node index.
4
+ * @param g - The adjacency
5
+ * @param start - The node index
6
+ * @param what - What the index is, for the error message
7
+ * @throws RangeError when `start` is not a node index of `g`
8
+ */
9
+ export function checkStart(g, start, what = "start") {
10
+ if (!Number.isInteger(start) || start < 0 || start >= g.nodeCount) {
11
+ throw new RangeError(`${what} node index ${String(start)} is out of range for ${String(g.nodeCount)} nodes`);
12
+ }
13
+ }
14
+ /**
15
+ * Check an optional target node index.
16
+ * @param g - The adjacency
17
+ * @param target - The option, or undefined
18
+ * @returns The target, or INVALID_INDEX for none
19
+ * @throws RangeError when `target` is set and is not a node index of `g`
20
+ */
21
+ export function checkTarget(g, target) {
22
+ if (target === undefined) {
23
+ return INVALID_INDEX;
24
+ }
25
+ checkStart(g, target, "target");
26
+ return target;
27
+ }
28
+ /**
29
+ * Check an `arcOrder` option: `arcCount` entries, and every row's slice a permutation of that row's
30
+ * arcs.
31
+ * @param g - The adjacency
32
+ * @param arcOrder - The option, or undefined
33
+ * @returns The order, or null for row order
34
+ * @throws RangeError when the order does not fit the adjacency
35
+ */
36
+ export function checkArcOrder(g, arcOrder) {
37
+ if (arcOrder === undefined) {
38
+ return null;
39
+ }
40
+ const { rowPtr, nodeCount } = g;
41
+ if (arcOrder.length !== g.arcCount) {
42
+ throw new RangeError(`arcOrder has ${String(arcOrder.length)} entries, expected ${String(g.arcCount)}`);
43
+ }
44
+ const seen = new Uint8Array(arcOrder.length);
45
+ for (let u = 0; u < nodeCount; u++) {
46
+ const begin = rowPtr[u];
47
+ const end = rowPtr[u + 1];
48
+ for (let a = begin; a < end; a++) {
49
+ if (arcOrder[a] < begin || arcOrder[a] >= end) {
50
+ throw new RangeError(`arcOrder[${String(a)}] = ${String(arcOrder[a])} is not an arc of node ${String(u)}`);
51
+ }
52
+ if (seen[arcOrder[a]] === 1) {
53
+ throw new RangeError(`arcOrder[${String(a)}] = ${String(arcOrder[a])} repeats an arc of node ${String(u)}`);
54
+ }
55
+ seen[arcOrder[a]] = 1;
56
+ }
57
+ }
58
+ return arcOrder;
59
+ }
2
60
  /**
3
61
  * Breadth-first search over out-neighbours. Takes any `AdjacencyView`, so `s.reverse()` gives an
4
62
  * in-neighbour BFS with no extra code.
@@ -9,24 +67,30 @@ import { INVALID_INDEX } from "@graphty/graph-format";
9
67
  * @public
10
68
  */
11
69
  export function breadthFirstSearch(g, start, options = {}) {
70
+ checkStart(g, start);
12
71
  const { nodeCount, rowPtr, colIdx } = g;
72
+ const arcOrder = checkArcOrder(g, options.arcOrder);
13
73
  const parent = new Uint32Array(nodeCount).fill(INVALID_INDEX);
14
74
  const depth = new Uint32Array(nodeCount).fill(INVALID_INDEX);
15
75
  const order = new Uint32Array(nodeCount);
16
76
  const maxDepth = options.maxDepth ?? INVALID_INDEX;
77
+ const target = checkTarget(g, options.target);
17
78
  let head = 0;
18
79
  let tail = 0;
19
80
  order[tail++] = start;
20
81
  depth[start] = 0;
21
82
  while (head < tail) {
22
83
  const u = order[head++];
84
+ if (u === target) {
85
+ break;
86
+ }
23
87
  const d = depth[u];
24
88
  if (d >= maxDepth) {
25
89
  continue;
26
90
  }
27
91
  const end = rowPtr[u + 1];
28
92
  for (let a = rowPtr[u]; a < end; a++) {
29
- const v = colIdx[a];
93
+ const v = colIdx[arcOrder === null ? a : arcOrder[a]];
30
94
  if (depth[v] === INVALID_INDEX) {
31
95
  depth[v] = d + 1;
32
96
  parent[v] = u;
@@ -36,4 +100,87 @@ export function breadthFirstSearch(g, start, options = {}) {
36
100
  }
37
101
  return { order: order.subarray(0, tail), parent, depth, visitedCount: tail };
38
102
  }
103
+ /**
104
+ * Direction-optimising breadth-first search (Beamer, Asanovic and Patterson, SC'12): a top-down
105
+ * step expands the frontier's out-arcs, a bottom-up step has every unvisited node look for a
106
+ * frontier node among its in-neighbours over `s.reverse()` (fetched only when a bottom-up step
107
+ * runs), and the search switches between the two
108
+ * by frontier size. Both steps give a node the LOWEST-index frontier node that reaches it as its
109
+ * parent, so the result does not depend on which steps ran: `depth` equals `breadthFirstSearch`'s,
110
+ * and `order` lists the visited nodes level by level, ascending within a level.
111
+ * @param s - The snapshot to traverse
112
+ * @param source - The node index to start from
113
+ * @param options - The switching thresholds
114
+ * @returns The visit order, the parent array, the depth array and the visited count
115
+ * @public
116
+ */
117
+ export function directionOptimizedBfs(s, source, options = {}) {
118
+ checkStart(s, source);
119
+ const { nodeCount, rowPtr, colIdx } = s;
120
+ const alpha = options.alpha ?? 15;
121
+ const beta = options.beta ?? 18;
122
+ let reverse = null;
123
+ const parent = new Uint32Array(nodeCount).fill(INVALID_INDEX);
124
+ const depth = new Uint32Array(nodeCount).fill(INVALID_INDEX);
125
+ // order[levelStart, tail) is the current frontier, sorted ascending.
126
+ const order = new Uint32Array(nodeCount);
127
+ order[0] = source;
128
+ depth[source] = 0;
129
+ let levelStart = 0;
130
+ let tail = 1;
131
+ let unexploredArcs = s.arcCount - (rowPtr[source + 1] - rowPtr[source]);
132
+ let bottomUp = false;
133
+ for (let d = 0; levelStart < tail; d++) {
134
+ const frontierSize = tail - levelStart;
135
+ if (bottomUp) {
136
+ bottomUp = frontierSize >= nodeCount / beta;
137
+ }
138
+ else {
139
+ let frontierArcs = 0;
140
+ for (let i = levelStart; i < tail; i++) {
141
+ frontierArcs += rowPtr[order[i] + 1] - rowPtr[order[i]];
142
+ }
143
+ bottomUp = frontierArcs > unexploredArcs / alpha;
144
+ }
145
+ const levelEnd = tail;
146
+ if (bottomUp) {
147
+ reverse ?? (reverse = s.reverse());
148
+ for (let v = 0; v < nodeCount; v++) {
149
+ if (depth[v] !== INVALID_INDEX) {
150
+ continue;
151
+ }
152
+ const end = reverse.rowPtr[v + 1];
153
+ for (let a = reverse.rowPtr[v]; a < end; a++) {
154
+ const u = reverse.colIdx[a];
155
+ if (depth[u] === d) {
156
+ parent[v] = u;
157
+ depth[v] = d + 1;
158
+ order[tail++] = v;
159
+ break;
160
+ }
161
+ }
162
+ }
163
+ }
164
+ else {
165
+ for (let i = levelStart; i < levelEnd; i++) {
166
+ const u = order[i];
167
+ const end = rowPtr[u + 1];
168
+ for (let a = rowPtr[u]; a < end; a++) {
169
+ const v = colIdx[a];
170
+ if (depth[v] === INVALID_INDEX) {
171
+ parent[v] = u;
172
+ depth[v] = d + 1;
173
+ order[tail++] = v;
174
+ }
175
+ }
176
+ }
177
+ order.subarray(levelEnd, tail).sort();
178
+ }
179
+ for (let i = levelEnd; i < tail; i++) {
180
+ unexploredArcs -= rowPtr[order[i] + 1] - rowPtr[order[i]];
181
+ }
182
+ levelStart = levelEnd;
183
+ }
184
+ return { order: order.subarray(0, tail), parent, depth, visitedCount: tail };
185
+ }
39
186
  //# sourceMappingURL=bfs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bfs.js","sourceRoot":"","sources":["../../../src/indexed/bfs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,aAAa,EAAY,MAAM,uBAAuB,CAAC;AAoBpF;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,CAAgB,EAAE,KAAa,EAAE,UAAsB,EAAE;IACxF,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,aAAa,CAAC;IACnD,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC;IACtB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjB,OAAO,IAAI,GAAG,IAAI,EAAE,CAAC;QACjB,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,CAAC,IAAI,QAAQ,EAAE,CAAC;YAChB,SAAS;QACb,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1B,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,aAAa,EAAE,CAAC;gBAC7B,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACjB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACd,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;YACtB,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;AACjF,CAAC"}
1
+ {"version":3,"file":"bfs.js","sourceRoot":"","sources":["../../../src/indexed/bfs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { type GraphSnapshot, type NodeMask } from "@graphty/graph-format";
2
+ /** Result of the index-based bipartiteness test. @public */
3
+ export interface BipartiteResult {
4
+ /** Whether the nodes split into two sides with no arc inside a side. */
5
+ readonly bipartite: boolean;
6
+ /**
7
+ * The two sides as one mask: a set bit puts the node on the second side, a clear bit on the
8
+ * first. The lowest-index node of every component is on the first side. Null when not bipartite.
9
+ */
10
+ readonly sides: NodeMask | null;
11
+ }
12
+ /** Options of {@link isBipartite}. @public */
13
+ export interface BipartiteOptions {
14
+ /**
15
+ * Which arcs of a directed snapshot to colour along. "both" (default) follows out- and in-arcs,
16
+ * which answers for the graph with direction ignored. "out" follows out-arcs only, as the legacy
17
+ * `bipartitePartition` does: roots are taken in index order and a node first reached through an
18
+ * in-arc is coloured as a new root, so the answer depends on node order. Ignored on an undirected
19
+ * snapshot.
20
+ */
21
+ readonly arcs?: "both" | "out" | undefined;
22
+ }
23
+ /**
24
+ * Two-colour the graph by BFS, one BFS per component in index order. A self-loop makes a graph
25
+ * non-bipartite; parallel arcs change nothing. Arc direction plays no part in bipartiteness, so on
26
+ * a directed snapshot every node is coloured against its in-neighbours (over `s.reverse()`) as well
27
+ * as its out-neighbours. Following out-arcs only -- as the legacy `bipartitePartition` does -- makes
28
+ * the answer depend on node order: with the single arc `a -> b`, a walk that starts at `b` never
29
+ * meets `a`, colours it as a new root and then finds the arc inside one side. `options.arcs: "out"`
30
+ * gives that legacy answer.
31
+ * @param s - The snapshot to test
32
+ * @param options - Which arcs to follow on a directed snapshot
33
+ * @returns Whether the graph is bipartite and, when it is, its two sides
34
+ * @public
35
+ */
36
+ export declare function isBipartite(s: GraphSnapshot, options?: BipartiteOptions): BipartiteResult;
37
+ //# sourceMappingURL=bipartite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bipartite.d.ts","sourceRoot":"","sources":["../../../src/indexed/bipartite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,aAAa,EAAqB,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjH,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC5B,wEAAwE;IACxE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CACnC;AAED,8CAA8C;AAC9C,MAAM,WAAW,gBAAgB;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;CAC9C;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,GAAE,gBAAqB,GAAG,eAAe,CAoC7F"}
@@ -0,0 +1,54 @@
1
+ import { makeMask, maskSet } from "@graphty/graph-format";
2
+ const UNSEEN = 2;
3
+ /**
4
+ * Two-colour the graph by BFS, one BFS per component in index order. A self-loop makes a graph
5
+ * non-bipartite; parallel arcs change nothing. Arc direction plays no part in bipartiteness, so on
6
+ * a directed snapshot every node is coloured against its in-neighbours (over `s.reverse()`) as well
7
+ * as its out-neighbours. Following out-arcs only -- as the legacy `bipartitePartition` does -- makes
8
+ * the answer depend on node order: with the single arc `a -> b`, a walk that starts at `b` never
9
+ * meets `a`, colours it as a new root and then finds the arc inside one side. `options.arcs: "out"`
10
+ * gives that legacy answer.
11
+ * @param s - The snapshot to test
12
+ * @param options - Which arcs to follow on a directed snapshot
13
+ * @returns Whether the graph is bipartite and, when it is, its two sides
14
+ * @public
15
+ */
16
+ export function isBipartite(s, options = {}) {
17
+ const { nodeCount } = s;
18
+ const views = s.directed && options.arcs !== "out" ? [s, s.reverse()] : [s];
19
+ const side = new Uint8Array(nodeCount).fill(UNSEEN);
20
+ const queue = new Uint32Array(nodeCount);
21
+ for (let r = 0; r < nodeCount; r++) {
22
+ if (side[r] !== UNSEEN) {
23
+ continue;
24
+ }
25
+ side[r] = 0;
26
+ let head = 0;
27
+ let tail = 0;
28
+ queue[tail++] = r;
29
+ while (head < tail) {
30
+ const u = queue[head++];
31
+ for (const { rowPtr, colIdx } of views) {
32
+ const end = rowPtr[u + 1];
33
+ for (let a = rowPtr[u]; a < end; a++) {
34
+ const v = colIdx[a];
35
+ if (side[v] === UNSEEN) {
36
+ side[v] = side[u] ^ 1;
37
+ queue[tail++] = v;
38
+ }
39
+ else if (side[v] === side[u]) {
40
+ return { bipartite: false, sides: null };
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
46
+ const sides = makeMask(nodeCount);
47
+ for (let i = 0; i < nodeCount; i++) {
48
+ if (side[i] === 1) {
49
+ maskSet(sides, i, true);
50
+ }
51
+ }
52
+ return { bipartite: true, sides };
53
+ }
54
+ //# sourceMappingURL=bipartite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bipartite.js","sourceRoot":"","sources":["../../../src/indexed/bipartite.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,QAAQ,EAAE,OAAO,EAAiB,MAAM,uBAAuB,CAAC;AAyBjH,MAAM,MAAM,GAAG,CAAC,CAAC;AAEjB;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CAAC,CAAgB,EAAE,UAA4B,EAAE;IACxE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;IACxB,MAAM,KAAK,GAAoB,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7F,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC,CAAC;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;YACrB,SAAS;QACb,CAAC;QACD,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACZ,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;QAClB,OAAO,IAAI,GAAG,IAAI,EAAE,CAAC;YACjB,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACxB,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;gBACrC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC1B,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;oBACnC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;oBACpB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;wBACrB,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;wBACtB,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;oBACtB,CAAC;yBAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC7B,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;oBAC7C,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5B,CAAC;IACL,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACtC,CAAC"}
@@ -0,0 +1,49 @@
1
+ import type { GraphSnapshot, NumericVector } from "@graphty/graph-format";
2
+ import type { ScoresResult } from "./betweenness.js";
3
+ /** Options of the index-based closeness centrality, matching the legacy `closenessCentrality`. @public */
4
+ export interface ClosenessOptions {
5
+ /**
6
+ * Scale by the fraction of other nodes reached (Wasserman and Faust), or with `harmonic` divide by
7
+ * `n - 1`. Default false.
8
+ */
9
+ readonly normalized?: boolean | undefined;
10
+ /** Sum `1 / distance` instead of taking `1 / sum(distance)`; better on disconnected graphs. Default false. */
11
+ readonly harmonic?: boolean | undefined;
12
+ /**
13
+ * Stop searching from nodes this far away or farther. A node past the cutoff is still counted when an edge
14
+ * reaches it from a node closer than the cutoff, as in the legacy functions. Default: every reachable node.
15
+ */
16
+ readonly cutoff?: number | undefined;
17
+ /**
18
+ * Measure distance by edge weight (Dijkstra) rather than by hops, as the legacy
19
+ * `weightedClosenessCentrality` does. Default false: weights are ignored, as the legacy
20
+ * `closenessCentrality` ignores them.
21
+ */
22
+ readonly weighted?: boolean | undefined;
23
+ /** Per-arc weight override, arcCount long, read when `weighted`; a facade passes the exact f64 weights. */
24
+ readonly weights?: NumericVector | undefined;
25
+ }
26
+ /**
27
+ * Closeness centrality of every node: `1 / sum(distance to each reached node)` by default, the legacy
28
+ * `closenessCentrality` (hops) and `weightedClosenessCentrality` (`weighted: true`) numbers. The weighted
29
+ * route reads the snapshot's f32 arc weights, so it matches legacy to f32 rounding; pass the f64 weights as
30
+ * `weights` for the exact legacy sums. As in legacy, a node's distance is final once it is searched from, so a
31
+ * negative weight gives the legacy (not the true shortest) distance and never loops. An unreached node adds
32
+ * nothing, and a node that reaches nothing scores 0.
33
+ * @param s - The snapshot
34
+ * @param options - Normalisation, harmonic form, cutoff and weights
35
+ * @returns One score per node index; `iterations` is the number of searches run
36
+ * @public
37
+ */
38
+ export declare function closenessCentrality(s: GraphSnapshot, options?: ClosenessOptions): ScoresResult;
39
+ /**
40
+ * Closeness centrality of one node, with one search rather than n.
41
+ * @param s - The snapshot
42
+ * @param node - The node index
43
+ * @param options - As {@link closenessCentrality}
44
+ * @returns The node's score
45
+ * @throws RangeError for a node index outside `[0, nodeCount)`
46
+ * @public
47
+ */
48
+ export declare function nodeClosenessCentrality(s: GraphSnapshot, node: number, options?: ClosenessOptions): number;
49
+ //# sourceMappingURL=closeness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"closeness.d.ts","sourceRoot":"","sources":["../../../src/indexed/closeness.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD,0GAA0G;AAC1G,MAAM,WAAW,gBAAgB;IAC7B;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1C,8GAA8G;IAC9G,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC,2GAA2G;IAC3G,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;CAChD;AAiGD;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,GAAE,gBAAqB,GAAG,YAAY,CAOlG;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAK9G"}