@graphty/algorithms 1.2.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/README.md +375 -276
  2. package/dist/algorithms.d.ts +42 -2
  3. package/dist/algorithms.js +11402 -2
  4. package/dist/algorithms.js.map +1 -1
  5. package/dist/src/algorithms/centrality/betweenness.d.ts +14 -0
  6. package/dist/src/algorithms/centrality/betweenness.d.ts.map +1 -1
  7. package/dist/src/algorithms/centrality/betweenness.js +144 -169
  8. package/dist/src/algorithms/centrality/betweenness.js.map +1 -1
  9. package/dist/src/algorithms/centrality/closeness.d.ts +35 -1
  10. package/dist/src/algorithms/centrality/closeness.d.ts.map +1 -1
  11. package/dist/src/algorithms/centrality/closeness.js +70 -149
  12. package/dist/src/algorithms/centrality/closeness.js.map +1 -1
  13. package/dist/src/algorithms/centrality/degree.d.ts +7 -0
  14. package/dist/src/algorithms/centrality/degree.d.ts.map +1 -1
  15. package/dist/src/algorithms/centrality/degree.js +12 -9
  16. package/dist/src/algorithms/centrality/degree.js.map +1 -1
  17. package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts +57 -0
  18. package/dist/src/algorithms/centrality/delta-pagerank-simple.d.ts.map +1 -0
  19. package/dist/src/algorithms/centrality/delta-pagerank-simple.js +304 -0
  20. package/dist/src/algorithms/centrality/delta-pagerank-simple.js.map +1 -0
  21. package/dist/src/algorithms/centrality/delta-pagerank.d.ts +106 -0
  22. package/dist/src/algorithms/centrality/delta-pagerank.d.ts.map +1 -0
  23. package/dist/src/algorithms/centrality/delta-pagerank.js +320 -0
  24. package/dist/src/algorithms/centrality/delta-pagerank.js.map +1 -0
  25. package/dist/src/algorithms/centrality/eigenvector.d.ts +10 -3
  26. package/dist/src/algorithms/centrality/eigenvector.d.ts.map +1 -1
  27. package/dist/src/algorithms/centrality/eigenvector.js +11 -4
  28. package/dist/src/algorithms/centrality/eigenvector.js.map +1 -1
  29. package/dist/src/algorithms/centrality/hits.d.ts +10 -3
  30. package/dist/src/algorithms/centrality/hits.d.ts.map +1 -1
  31. package/dist/src/algorithms/centrality/hits.js +11 -4
  32. package/dist/src/algorithms/centrality/hits.js.map +1 -1
  33. package/dist/src/algorithms/centrality/index.d.ts +3 -1
  34. package/dist/src/algorithms/centrality/index.d.ts.map +1 -1
  35. package/dist/src/algorithms/centrality/index.js +2 -1
  36. package/dist/src/algorithms/centrality/index.js.map +1 -1
  37. package/dist/src/algorithms/centrality/katz.d.ts +10 -3
  38. package/dist/src/algorithms/centrality/katz.d.ts.map +1 -1
  39. package/dist/src/algorithms/centrality/katz.js +13 -8
  40. package/dist/src/algorithms/centrality/katz.js.map +1 -1
  41. package/dist/src/algorithms/centrality/pagerank.d.ts +31 -0
  42. package/dist/src/algorithms/centrality/pagerank.d.ts.map +1 -1
  43. package/dist/src/algorithms/centrality/pagerank.js +61 -1
  44. package/dist/src/algorithms/centrality/pagerank.js.map +1 -1
  45. package/dist/src/algorithms/community/girvan-newman.d.ts +2 -3
  46. package/dist/src/algorithms/community/girvan-newman.d.ts.map +1 -1
  47. package/dist/src/algorithms/community/girvan-newman.js +67 -57
  48. package/dist/src/algorithms/community/girvan-newman.js.map +1 -1
  49. package/dist/src/algorithms/community/index.d.ts +2 -0
  50. package/dist/src/algorithms/community/index.d.ts.map +1 -1
  51. package/dist/src/algorithms/community/index.js.map +1 -1
  52. package/dist/src/algorithms/community/label-propagation.d.ts +11 -4
  53. package/dist/src/algorithms/community/label-propagation.d.ts.map +1 -1
  54. package/dist/src/algorithms/community/label-propagation.js +60 -38
  55. package/dist/src/algorithms/community/label-propagation.js.map +1 -1
  56. package/dist/src/algorithms/community/leiden.d.ts +3 -3
  57. package/dist/src/algorithms/community/leiden.d.ts.map +1 -1
  58. package/dist/src/algorithms/community/leiden.js +70 -44
  59. package/dist/src/algorithms/community/leiden.js.map +1 -1
  60. package/dist/src/algorithms/community/louvain-optimized.d.ts +149 -0
  61. package/dist/src/algorithms/community/louvain-optimized.d.ts.map +1 -0
  62. package/dist/src/algorithms/community/louvain-optimized.js +338 -0
  63. package/dist/src/algorithms/community/louvain-optimized.js.map +1 -0
  64. package/dist/src/algorithms/community/louvain.d.ts +2 -3
  65. package/dist/src/algorithms/community/louvain.d.ts.map +1 -1
  66. package/dist/src/algorithms/community/louvain.js +35 -81
  67. package/dist/src/algorithms/community/louvain.js.map +1 -1
  68. package/dist/src/algorithms/community/modularity-utils.d.ts +55 -0
  69. package/dist/src/algorithms/community/modularity-utils.d.ts.map +1 -0
  70. package/dist/src/algorithms/community/modularity-utils.js +108 -0
  71. package/dist/src/algorithms/community/modularity-utils.js.map +1 -0
  72. package/dist/src/algorithms/components/connected.d.ts +23 -0
  73. package/dist/src/algorithms/components/connected.d.ts.map +1 -1
  74. package/dist/src/algorithms/components/connected.js +29 -3
  75. package/dist/src/algorithms/components/connected.js.map +1 -1
  76. package/dist/src/algorithms/matching/bipartite.d.ts +10 -0
  77. package/dist/src/algorithms/matching/bipartite.d.ts.map +1 -1
  78. package/dist/src/algorithms/matching/bipartite.js +18 -40
  79. package/dist/src/algorithms/matching/bipartite.js.map +1 -1
  80. package/dist/src/algorithms/matching/index.d.ts.map +1 -1
  81. package/dist/src/algorithms/matching/index.js.map +1 -1
  82. package/dist/src/algorithms/matching/isomorphism.d.ts +8 -0
  83. package/dist/src/algorithms/matching/isomorphism.d.ts.map +1 -1
  84. package/dist/src/algorithms/matching/isomorphism.js +36 -2
  85. package/dist/src/algorithms/matching/isomorphism.js.map +1 -1
  86. package/dist/src/algorithms/mst/index.d.ts.map +1 -1
  87. package/dist/src/algorithms/mst/index.js.map +1 -1
  88. package/dist/src/algorithms/mst/kruskal.d.ts +14 -0
  89. package/dist/src/algorithms/mst/kruskal.d.ts.map +1 -1
  90. package/dist/src/algorithms/mst/kruskal.js +17 -3
  91. package/dist/src/algorithms/mst/kruskal.js.map +1 -1
  92. package/dist/src/algorithms/mst/prim.d.ts +9 -0
  93. package/dist/src/algorithms/mst/prim.d.ts.map +1 -1
  94. package/dist/src/algorithms/mst/prim.js +9 -0
  95. package/dist/src/algorithms/mst/prim.js.map +1 -1
  96. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts +10 -0
  97. package/dist/src/algorithms/shortest-path/bellman-ford.d.ts.map +1 -1
  98. package/dist/src/algorithms/shortest-path/bellman-ford.js +11 -12
  99. package/dist/src/algorithms/shortest-path/bellman-ford.js.map +1 -1
  100. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts +44 -0
  101. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.d.ts.map +1 -0
  102. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js +195 -0
  103. package/dist/src/algorithms/shortest-path/bidirectional-dijkstra.js.map +1 -0
  104. package/dist/src/algorithms/shortest-path/dijkstra.d.ts +20 -2
  105. package/dist/src/algorithms/shortest-path/dijkstra.d.ts.map +1 -1
  106. package/dist/src/algorithms/shortest-path/dijkstra.js +30 -14
  107. package/dist/src/algorithms/shortest-path/dijkstra.js.map +1 -1
  108. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts +17 -0
  109. package/dist/src/algorithms/shortest-path/floyd-warshall.d.ts.map +1 -1
  110. package/dist/src/algorithms/shortest-path/floyd-warshall.js +17 -0
  111. package/dist/src/algorithms/shortest-path/floyd-warshall.js.map +1 -1
  112. package/dist/src/algorithms/shortest-path/index.d.ts.map +1 -1
  113. package/dist/src/algorithms/shortest-path/index.js.map +1 -1
  114. package/dist/src/algorithms/traversal/bfs-unified.d.ts +42 -0
  115. package/dist/src/algorithms/traversal/bfs-unified.d.ts.map +1 -0
  116. package/dist/src/algorithms/traversal/bfs-unified.js +370 -0
  117. package/dist/src/algorithms/traversal/bfs-unified.js.map +1 -0
  118. package/dist/src/algorithms/traversal/bfs-variants.d.ts +77 -0
  119. package/dist/src/algorithms/traversal/bfs-variants.d.ts.map +1 -0
  120. package/dist/src/algorithms/traversal/bfs-variants.js +402 -0
  121. package/dist/src/algorithms/traversal/bfs-variants.js.map +1 -0
  122. package/dist/src/algorithms/traversal/bfs.d.ts +4 -18
  123. package/dist/src/algorithms/traversal/bfs.d.ts.map +1 -1
  124. package/dist/src/algorithms/traversal/bfs.js +5 -182
  125. package/dist/src/algorithms/traversal/bfs.js.map +1 -1
  126. package/dist/src/algorithms/traversal/dfs.d.ts +10 -0
  127. package/dist/src/algorithms/traversal/dfs.d.ts.map +1 -1
  128. package/dist/src/algorithms/traversal/dfs.js +48 -0
  129. package/dist/src/algorithms/traversal/dfs.js.map +1 -1
  130. package/dist/src/algorithms/traversal/index.d.ts.map +1 -1
  131. package/dist/src/algorithms/traversal/index.js.map +1 -1
  132. package/dist/src/benchmark-all-algorithms.d.ts +25 -0
  133. package/dist/src/benchmark-all-algorithms.d.ts.map +1 -0
  134. package/dist/src/benchmark-all-algorithms.js +491 -0
  135. package/dist/src/benchmark-all-algorithms.js.map +1 -0
  136. package/dist/src/clustering/hierarchical.d.ts +23 -15
  137. package/dist/src/clustering/hierarchical.d.ts.map +1 -1
  138. package/dist/src/clustering/hierarchical.js +226 -224
  139. package/dist/src/clustering/hierarchical.js.map +1 -1
  140. package/dist/src/clustering/index.d.ts +4 -2
  141. package/dist/src/clustering/index.d.ts.map +1 -1
  142. package/dist/src/clustering/index.js +2 -2
  143. package/dist/src/clustering/index.js.map +1 -1
  144. package/dist/src/clustering/k-core.d.ts +17 -19
  145. package/dist/src/clustering/k-core.d.ts.map +1 -1
  146. package/dist/src/clustering/k-core.js +68 -30
  147. package/dist/src/clustering/k-core.js.map +1 -1
  148. package/dist/src/clustering/mcl.d.ts +6 -0
  149. package/dist/src/clustering/mcl.d.ts.map +1 -1
  150. package/dist/src/clustering/mcl.js +34 -3
  151. package/dist/src/clustering/mcl.js.map +1 -1
  152. package/dist/src/clustering/spectral.d.ts +11 -0
  153. package/dist/src/clustering/spectral.d.ts.map +1 -1
  154. package/dist/src/clustering/spectral.js +99 -47
  155. package/dist/src/clustering/spectral.js.map +1 -1
  156. package/dist/src/core/graph.d.ts +45 -0
  157. package/dist/src/core/graph.d.ts.map +1 -1
  158. package/dist/src/core/graph.js +49 -5
  159. package/dist/src/core/graph.js.map +1 -1
  160. package/dist/src/data-structures/index.d.ts.map +1 -1
  161. package/dist/src/data-structures/index.js.map +1 -1
  162. package/dist/src/data-structures/priority-queue.d.ts +18 -1
  163. package/dist/src/data-structures/priority-queue.d.ts.map +1 -1
  164. package/dist/src/data-structures/priority-queue.js +26 -5
  165. package/dist/src/data-structures/priority-queue.js.map +1 -1
  166. package/dist/src/data-structures/union-find.d.ts +21 -0
  167. package/dist/src/data-structures/union-find.d.ts.map +1 -1
  168. package/dist/src/data-structures/union-find.js +21 -0
  169. package/dist/src/data-structures/union-find.js.map +1 -1
  170. package/dist/src/flow/ford-fulkerson.d.ts +20 -12
  171. package/dist/src/flow/ford-fulkerson.d.ts.map +1 -1
  172. package/dist/src/flow/ford-fulkerson.js +170 -217
  173. package/dist/src/flow/ford-fulkerson.js.map +1 -1
  174. package/dist/src/flow/min-cut.d.ts +6 -8
  175. package/dist/src/flow/min-cut.d.ts.map +1 -1
  176. package/dist/src/flow/min-cut.js +34 -12
  177. package/dist/src/flow/min-cut.js.map +1 -1
  178. package/dist/src/index.d.ts +3 -1
  179. package/dist/src/index.d.ts.map +1 -1
  180. package/dist/src/index.js +6 -1
  181. package/dist/src/index.js.map +1 -1
  182. package/dist/src/link-prediction/adamic-adar.d.ts +26 -0
  183. package/dist/src/link-prediction/adamic-adar.d.ts.map +1 -1
  184. package/dist/src/link-prediction/adamic-adar.js +47 -30
  185. package/dist/src/link-prediction/adamic-adar.js.map +1 -1
  186. package/dist/src/link-prediction/common-neighbors.d.ts +21 -0
  187. package/dist/src/link-prediction/common-neighbors.d.ts.map +1 -1
  188. package/dist/src/link-prediction/common-neighbors.js +31 -14
  189. package/dist/src/link-prediction/common-neighbors.js.map +1 -1
  190. package/dist/src/link-prediction/index.d.ts.map +1 -1
  191. package/dist/src/optimized/bit-packed.d.ts +193 -0
  192. package/dist/src/optimized/bit-packed.d.ts.map +1 -0
  193. package/dist/src/optimized/bit-packed.js +342 -0
  194. package/dist/src/optimized/bit-packed.js.map +1 -0
  195. package/dist/src/optimized/csr-graph.d.ts +149 -0
  196. package/dist/src/optimized/csr-graph.d.ts.map +1 -0
  197. package/dist/src/optimized/csr-graph.js +404 -0
  198. package/dist/src/optimized/csr-graph.js.map +1 -0
  199. package/dist/src/optimized/direction-optimized-bfs.d.ts +95 -0
  200. package/dist/src/optimized/direction-optimized-bfs.d.ts.map +1 -0
  201. package/dist/src/optimized/direction-optimized-bfs.js +242 -0
  202. package/dist/src/optimized/direction-optimized-bfs.js.map +1 -0
  203. package/dist/src/optimized/graph-adapter.d.ts +111 -0
  204. package/dist/src/optimized/graph-adapter.d.ts.map +1 -0
  205. package/dist/src/optimized/graph-adapter.js +194 -0
  206. package/dist/src/optimized/graph-adapter.js.map +1 -0
  207. package/dist/src/optimized/index.d.ts +14 -0
  208. package/dist/src/optimized/index.d.ts.map +1 -0
  209. package/dist/src/optimized/index.js +30 -0
  210. package/dist/src/optimized/index.js.map +1 -0
  211. package/dist/src/pathfinding/astar.d.ts +25 -9
  212. package/dist/src/pathfinding/astar.d.ts.map +1 -1
  213. package/dist/src/pathfinding/astar.js +25 -10
  214. package/dist/src/pathfinding/astar.js.map +1 -1
  215. package/dist/src/pathfinding/utils.d.ts +15 -6
  216. package/dist/src/pathfinding/utils.d.ts.map +1 -1
  217. package/dist/src/pathfinding/utils.js +19 -7
  218. package/dist/src/pathfinding/utils.js.map +1 -1
  219. package/dist/src/research/grsbm.d.ts +0 -1
  220. package/dist/src/research/grsbm.d.ts.map +1 -1
  221. package/dist/src/research/grsbm.js +28 -23
  222. package/dist/src/research/grsbm.js.map +1 -1
  223. package/dist/src/research/index.d.ts.map +1 -1
  224. package/dist/src/research/index.js.map +1 -1
  225. package/dist/src/research/sync.d.ts +0 -1
  226. package/dist/src/research/sync.d.ts.map +1 -1
  227. package/dist/src/research/sync.js +31 -36
  228. package/dist/src/research/sync.js.map +1 -1
  229. package/dist/src/research/terahac.d.ts +2 -1
  230. package/dist/src/research/terahac.d.ts.map +1 -1
  231. package/dist/src/research/terahac.js +39 -7
  232. package/dist/src/research/terahac.js.map +1 -1
  233. package/dist/src/types/index.d.ts +8 -0
  234. package/dist/src/types/index.d.ts.map +1 -1
  235. package/dist/src/utils/algorithm-utilities.d.ts +2 -0
  236. package/dist/src/utils/algorithm-utilities.d.ts.map +1 -0
  237. package/dist/src/utils/algorithm-utilities.js +2 -0
  238. package/dist/src/utils/algorithm-utilities.js.map +1 -0
  239. package/dist/src/utils/graph-converters.d.ts +110 -0
  240. package/dist/src/utils/graph-converters.d.ts.map +1 -0
  241. package/dist/src/utils/graph-converters.js +227 -0
  242. package/dist/src/utils/graph-converters.js.map +1 -0
  243. package/dist/src/utils/graph-utilities.d.ts +62 -0
  244. package/dist/src/utils/graph-utilities.d.ts.map +1 -0
  245. package/dist/src/utils/graph-utilities.js +148 -0
  246. package/dist/src/utils/graph-utilities.js.map +1 -0
  247. package/dist/src/utils/index.d.ts +5 -0
  248. package/dist/src/utils/index.d.ts.map +1 -0
  249. package/dist/src/utils/index.js +5 -0
  250. package/dist/src/utils/index.js.map +1 -0
  251. package/dist/src/utils/math-utilities.d.ts +63 -0
  252. package/dist/src/utils/math-utilities.d.ts.map +1 -0
  253. package/dist/src/utils/math-utilities.js +132 -0
  254. package/dist/src/utils/math-utilities.js.map +1 -0
  255. package/dist/src/utils/matrix-utilities.d.ts +2 -0
  256. package/dist/src/utils/matrix-utilities.d.ts.map +1 -0
  257. package/dist/src/utils/matrix-utilities.js +2 -0
  258. package/dist/src/utils/matrix-utilities.js.map +1 -0
  259. package/dist/src/utils/optimization-helpers.d.ts +42 -0
  260. package/dist/src/utils/optimization-helpers.d.ts.map +1 -0
  261. package/dist/src/utils/optimization-helpers.js +59 -0
  262. package/dist/src/utils/optimization-helpers.js.map +1 -0
  263. package/dist/src/utils/priorityQueue.d.ts +24 -0
  264. package/dist/src/utils/priorityQueue.d.ts.map +1 -1
  265. package/dist/src/utils/priorityQueue.js +34 -4
  266. package/dist/src/utils/priorityQueue.js.map +1 -1
  267. package/package.json +58 -39
  268. package/src/algorithms/centrality/betweenness.ts +185 -200
  269. package/src/algorithms/centrality/closeness.ts +93 -194
  270. package/src/algorithms/centrality/degree.ts +18 -22
  271. package/src/algorithms/centrality/delta-pagerank-simple.ts +374 -0
  272. package/src/algorithms/centrality/delta-pagerank.ts +458 -0
  273. package/src/algorithms/centrality/eigenvector.ts +14 -15
  274. package/src/algorithms/centrality/hits.ts +17 -17
  275. package/src/algorithms/centrality/index.ts +20 -13
  276. package/src/algorithms/centrality/katz.ts +17 -25
  277. package/src/algorithms/centrality/pagerank.ts +91 -16
  278. package/src/algorithms/community/girvan-newman.ts +90 -86
  279. package/src/algorithms/community/index.ts +6 -5
  280. package/src/algorithms/community/label-propagation.ts +69 -48
  281. package/src/algorithms/community/leiden.ts +88 -65
  282. package/src/algorithms/community/louvain-optimized.ts +474 -0
  283. package/src/algorithms/community/louvain.ts +52 -122
  284. package/src/algorithms/community/modularity-utils.ts +134 -0
  285. package/src/algorithms/components/connected.ts +40 -17
  286. package/src/algorithms/matching/bipartite.ts +24 -53
  287. package/src/algorithms/matching/index.ts +4 -4
  288. package/src/algorithms/matching/isomorphism.ts +53 -23
  289. package/src/algorithms/mst/index.ts +3 -4
  290. package/src/algorithms/mst/kruskal.ts +21 -6
  291. package/src/algorithms/mst/prim.ts +13 -4
  292. package/src/algorithms/shortest-path/bellman-ford.ts +16 -28
  293. package/src/algorithms/shortest-path/bidirectional-dijkstra.ts +248 -0
  294. package/src/algorithms/shortest-path/dijkstra.ts +38 -30
  295. package/src/algorithms/shortest-path/floyd-warshall.ts +21 -4
  296. package/src/algorithms/shortest-path/index.ts +5 -5
  297. package/src/algorithms/traversal/bfs-unified.ts +437 -0
  298. package/src/algorithms/traversal/bfs-variants.ts +520 -0
  299. package/src/algorithms/traversal/bfs.ts +5 -229
  300. package/src/algorithms/traversal/dfs.ts +61 -42
  301. package/src/algorithms/traversal/index.ts +3 -3
  302. package/src/benchmark-all-algorithms.ts +580 -0
  303. package/src/clustering/hierarchical.ts +268 -272
  304. package/src/clustering/index.ts +8 -6
  305. package/src/clustering/k-core.ts +93 -61
  306. package/src/clustering/mcl.ts +53 -23
  307. package/src/clustering/spectral.ts +130 -72
  308. package/src/core/graph.ts +58 -18
  309. package/src/data-structures/index.ts +2 -2
  310. package/src/data-structures/priority-queue.ts +36 -11
  311. package/src/data-structures/union-find.ts +22 -1
  312. package/src/flow/ford-fulkerson.ts +221 -262
  313. package/src/flow/min-cut.ts +59 -51
  314. package/src/index.ts +9 -2
  315. package/src/link-prediction/adamic-adar.ts +75 -74
  316. package/src/link-prediction/common-neighbors.ts +49 -49
  317. package/src/link-prediction/index.ts +1 -1
  318. package/src/optimized/bit-packed.ts +390 -0
  319. package/src/optimized/csr-graph.ts +518 -0
  320. package/src/optimized/direction-optimized-bfs.ts +310 -0
  321. package/src/optimized/graph-adapter.ts +248 -0
  322. package/src/optimized/index.ts +34 -0
  323. package/src/pathfinding/astar.ts +40 -25
  324. package/src/pathfinding/utils.ts +20 -13
  325. package/src/research/grsbm.ts +36 -39
  326. package/src/research/index.ts +4 -4
  327. package/src/research/sync.ts +41 -54
  328. package/src/research/terahac.ts +63 -21
  329. package/src/types/index.ts +8 -0
  330. package/src/utils/algorithm-utilities.ts +2 -0
  331. package/src/utils/graph-converters.ts +269 -0
  332. package/src/utils/graph-utilities.ts +173 -0
  333. package/src/utils/index.ts +4 -0
  334. package/src/utils/math-utilities.ts +149 -0
  335. package/src/utils/matrix-utilities.ts +2 -0
  336. package/src/utils/optimization-helpers.ts +87 -0
  337. package/src/utils/priorityQueue.ts +40 -6
@@ -1,3 +1,7 @@
1
+ import { bfsAugmentingPath } from "../algorithms/traversal/bfs-variants.js";
2
+ import type { Graph } from "../core/graph.js";
3
+ import { graphToMap } from "../utils/graph-converters.js";
4
+
1
5
  /**
2
6
  * Ford-Fulkerson Algorithm for Maximum Flow
3
7
  *
@@ -20,228 +24,15 @@ export interface FlowNetwork {
20
24
  export interface MaxFlowResult {
21
25
  maxFlow: number;
22
26
  flowGraph: Map<string, Map<string, number>>;
23
- minCut?: {source: Set<string>, sink: Set<string>, edges: [string, string][]};
24
- }
25
-
26
- /**
27
- * Ford-Fulkerson algorithm using DFS for finding augmenting paths
28
- *
29
- * @param graph - Adjacency list representation with capacities
30
- * @param source - Source node
31
- * @param sink - Sink node
32
- * @returns Maximum flow value and flow graph
33
- *
34
- * Time Complexity: O(E * f) where f is the maximum flow
35
- * Space Complexity: O(V + E)
36
- */
37
- export function fordFulkerson(
38
- graph: Map<string, Map<string, number>>,
39
- source: string,
40
- sink: string,
41
- ): MaxFlowResult {
42
- if (!graph.has(source) || !graph.has(sink)) {
43
- return {maxFlow: 0, flowGraph: new Map()};
44
- }
45
-
46
- // Create residual graph
47
- const residualGraph = createResidualGraph(graph);
48
- const flowGraph = new Map<string, Map<string, number>>();
49
-
50
- // Initialize flow graph
51
- for (const [u, neighbors] of graph) {
52
- flowGraph.set(u, new Map());
53
- for (const v of neighbors.keys()) {
54
- const uFlowNeighbors = flowGraph.get(u);
55
- if (uFlowNeighbors) {
56
- uFlowNeighbors.set(v, 0);
57
- }
58
- }
59
- }
60
-
61
- let maxFlow = 0;
62
- let path = findAugmentingPath(residualGraph, source, sink);
63
-
64
- while (path !== null) {
65
- // Find minimum capacity along the path
66
- let pathFlow = Infinity;
67
- for (let i = 0; i < path.length - 1; i++) {
68
- const u = path[i];
69
- const v = path[i + 1];
70
- if (!u || !v) {
71
- continue;
72
- }
73
-
74
- const uEdges = residualGraph.get(u);
75
- if (!uEdges) {
76
- continue;
77
- }
78
-
79
- const capacity = uEdges.get(v);
80
- if (capacity !== undefined) {
81
- pathFlow = Math.min(pathFlow, capacity);
82
- }
83
- }
84
-
85
- // Update residual capacities
86
- for (let i = 0; i < path.length - 1; i++) {
87
- const u = path[i];
88
- const v = path[i + 1];
89
- if (!u || !v) {
90
- continue;
91
- }
92
-
93
- // Update residual graph
94
- const uEdges = residualGraph.get(u);
95
- if (uEdges) {
96
- const currentCapacity = uEdges.get(v);
97
- if (currentCapacity !== undefined) {
98
- uEdges.set(v, currentCapacity - pathFlow);
99
- }
100
- }
101
-
102
- // Add reverse edge
103
- if (!residualGraph.has(v)) {
104
- residualGraph.set(v, new Map());
105
- }
106
-
107
- const vEdges = residualGraph.get(v);
108
- if (vEdges) {
109
- vEdges.set(u, (vEdges.get(u) ?? 0) + pathFlow);
110
- }
111
-
112
- // Update flow graph
113
- if (graph.get(u)?.has(v)) {
114
- const uFlowEdges = flowGraph.get(u);
115
- if (uFlowEdges) {
116
- const currentFlow = uFlowEdges.get(v) ?? 0;
117
- uFlowEdges.set(v, currentFlow + pathFlow);
118
- }
119
- } else if (graph.get(v)?.has(u)) {
120
- // This is a reverse flow
121
- const vFlowEdges = flowGraph.get(v);
122
- if (vFlowEdges) {
123
- const currentFlow = vFlowEdges.get(u) ?? 0;
124
- vFlowEdges.set(u, currentFlow - pathFlow);
125
- }
126
- }
127
- }
128
-
129
- maxFlow += pathFlow;
130
- path = findAugmentingPath(residualGraph, source, sink);
131
- }
132
-
133
- // Find minimum cut
134
- const minCut = findMinCut(residualGraph, source);
135
-
136
- return {maxFlow, flowGraph, minCut};
137
- }
138
-
139
- /**
140
- * Edmonds-Karp algorithm (Ford-Fulkerson with BFS)
141
- * More efficient implementation with better time complexity
142
- *
143
- * Time Complexity: O(V * E²)
144
- */
145
- export function edmondsKarp(
146
- graph: Map<string, Map<string, number>>,
147
- source: string,
148
- sink: string,
149
- ): MaxFlowResult {
150
- if (!graph.has(source) || !graph.has(sink)) {
151
- return {maxFlow: 0, flowGraph: new Map()};
152
- }
153
-
154
- const residualGraph = createResidualGraph(graph);
155
- const flowGraph = new Map<string, Map<string, number>>();
156
-
157
- // Initialize flow graph
158
- for (const [u, neighbors] of graph) {
159
- flowGraph.set(u, new Map());
160
- for (const v of neighbors.keys()) {
161
- const uFlowNeighbors = flowGraph.get(u);
162
- if (uFlowNeighbors) {
163
- uFlowNeighbors.set(v, 0);
164
- }
165
- }
166
- }
167
-
168
- let maxFlow = 0;
169
- let path = findAugmentingPathBFS(residualGraph, source, sink);
170
-
171
- while (path !== null) {
172
- let pathFlow = Infinity;
173
- for (let i = 0; i < path.length - 1; i++) {
174
- const u = path[i];
175
- const v = path[i + 1];
176
- if (!u || !v) {
177
- continue;
178
- }
179
-
180
- const uEdges = residualGraph.get(u);
181
- if (!uEdges) {
182
- continue;
183
- }
184
-
185
- const capacity = uEdges.get(v);
186
- if (capacity !== undefined) {
187
- pathFlow = Math.min(pathFlow, capacity);
188
- }
189
- }
190
-
191
- for (let i = 0; i < path.length - 1; i++) {
192
- const u = path[i];
193
- const v = path[i + 1];
194
- if (!u || !v) {
195
- continue;
196
- }
197
-
198
- const uEdges = residualGraph.get(u);
199
- if (uEdges) {
200
- const currentCapacity = uEdges.get(v);
201
- if (currentCapacity !== undefined) {
202
- uEdges.set(v, currentCapacity - pathFlow);
203
- }
204
- }
205
-
206
- if (!residualGraph.has(v)) {
207
- residualGraph.set(v, new Map());
208
- }
209
-
210
- const vEdges = residualGraph.get(v);
211
- if (vEdges) {
212
- vEdges.set(u, (vEdges.get(u) ?? 0) + pathFlow);
213
- }
214
-
215
- if (graph.get(u)?.has(v)) {
216
- const uFlowEdges = flowGraph.get(u);
217
- if (uFlowEdges) {
218
- const currentFlow = uFlowEdges.get(v) ?? 0;
219
- uFlowEdges.set(v, currentFlow + pathFlow);
220
- }
221
- } else if (graph.get(v)?.has(u)) {
222
- const vFlowEdges = flowGraph.get(v);
223
- if (vFlowEdges) {
224
- const currentFlow = vFlowEdges.get(u) ?? 0;
225
- vFlowEdges.set(u, currentFlow - pathFlow);
226
- }
227
- }
228
- }
229
-
230
- maxFlow += pathFlow;
231
- path = findAugmentingPathBFS(residualGraph, source, sink);
232
- }
233
-
234
- const minCut = findMinCut(residualGraph, source);
235
-
236
- return {maxFlow, flowGraph, minCut};
27
+ minCut?: { source: Set<string>; sink: Set<string>; edges: [string, string][] };
237
28
  }
238
29
 
239
30
  /**
240
31
  * Create residual graph from original graph
32
+ * @param graph - The original graph with capacity values
33
+ * @returns A residual graph initialized with the original capacities
241
34
  */
242
- function createResidualGraph(
243
- graph: Map<string, Map<string, number>>,
244
- ): Map<string, Map<string, number>> {
35
+ function createResidualGraph(graph: Map<string, Map<string, number>>): Map<string, Map<string, number>> {
245
36
  const residual = new Map<string, Map<string, number>>();
246
37
 
247
38
  for (const [u, neighbors] of graph) {
@@ -259,8 +50,12 @@ function createResidualGraph(
259
50
 
260
51
  /**
261
52
  * Find augmenting path using DFS
53
+ * @param residualGraph - The residual graph with remaining capacities
54
+ * @param source - The source node
55
+ * @param sink - The sink node
56
+ * @returns An array of nodes forming the path, or null if no path exists
262
57
  */
263
- function findAugmentingPath(
58
+ function findAugmentingPathDFS(
264
59
  residualGraph: Map<string, Map<string, number>>,
265
60
  source: string,
266
61
  sink: string,
@@ -300,64 +95,74 @@ function findAugmentingPath(
300
95
  }
301
96
 
302
97
  /**
303
- * Find augmenting path using BFS (for Edmonds-Karp)
98
+ * Update flow along an augmenting path
99
+ * @param residualGraph - The residual graph to update
100
+ * @param flowGraph - The flow graph to update with new flow values
101
+ * @param originalGraph - The original graph for edge direction reference
102
+ * @param path - The augmenting path to update flow along
103
+ * @param pathFlow - The amount of flow to push through the path
304
104
  */
305
- function findAugmentingPathBFS(
105
+ function updateFlow(
306
106
  residualGraph: Map<string, Map<string, number>>,
307
- source: string,
308
- sink: string,
309
- ): string[] | null {
310
- const parent = new Map<string, string>();
311
- const visited = new Set<string>();
312
- const queue: string[] = [source];
313
- visited.add(source);
314
-
315
- while (queue.length > 0) {
316
- const current = queue.shift();
317
- if (!current) {
107
+ flowGraph: Map<string, Map<string, number>>,
108
+ originalGraph: Map<string, Map<string, number>>,
109
+ path: string[],
110
+ pathFlow: number,
111
+ ): void {
112
+ for (let i = 0; i < path.length - 1; i++) {
113
+ const u = path[i];
114
+ const v = path[i + 1];
115
+ if (!u || !v) {
318
116
  continue;
319
117
  }
320
118
 
321
- const neighbors = residualGraph.get(current);
322
- if (neighbors) {
323
- for (const [neighbor, capacity] of neighbors) {
324
- if (!visited.has(neighbor) && capacity > 0) {
325
- visited.add(neighbor);
326
- parent.set(neighbor, current);
327
-
328
- if (neighbor === sink) {
329
- // Reconstruct path
330
- const path: string[] = [];
331
- let node = sink;
332
- while (node !== source) {
333
- path.unshift(node);
334
- const parentNode = parent.get(node);
335
- if (!parentNode) {
336
- break;
337
- }
338
-
339
- node = parentNode;
340
- }
341
- path.unshift(source);
342
- return path;
343
- }
119
+ // Update residual graph
120
+ const uEdges = residualGraph.get(u);
121
+ if (uEdges) {
122
+ const currentCapacity = uEdges.get(v);
123
+ if (currentCapacity !== undefined) {
124
+ uEdges.set(v, currentCapacity - pathFlow);
125
+ }
126
+ }
344
127
 
345
- queue.push(neighbor);
346
- }
128
+ // Add reverse edge
129
+ if (!residualGraph.has(v)) {
130
+ residualGraph.set(v, new Map());
131
+ }
132
+
133
+ const vEdges = residualGraph.get(v);
134
+ if (vEdges) {
135
+ vEdges.set(u, (vEdges.get(u) ?? 0) + pathFlow);
136
+ }
137
+
138
+ // Update flow graph
139
+ if (originalGraph.get(u)?.has(v)) {
140
+ const uFlowEdges = flowGraph.get(u);
141
+ if (uFlowEdges) {
142
+ const currentFlow = uFlowEdges.get(v) ?? 0;
143
+ uFlowEdges.set(v, currentFlow + pathFlow);
144
+ }
145
+ } else if (originalGraph.get(v)?.has(u)) {
146
+ // This is a reverse flow
147
+ const vFlowEdges = flowGraph.get(v);
148
+ if (vFlowEdges) {
149
+ const currentFlow = vFlowEdges.get(u) ?? 0;
150
+ vFlowEdges.set(u, currentFlow - pathFlow);
347
151
  }
348
152
  }
349
153
  }
350
-
351
- return null;
352
154
  }
353
155
 
354
156
  /**
355
157
  * Find minimum cut from source side
158
+ * @param residualGraph - The residual graph after max flow computation
159
+ * @param source - The source node
160
+ * @returns The minimum cut partition with source and sink sets and cut edges
356
161
  */
357
162
  function findMinCut(
358
163
  residualGraph: Map<string, Map<string, number>>,
359
164
  source: string,
360
- ): {source: Set<string>, sink: Set<string>, edges: [string, string][]} {
165
+ ): { source: Set<string>; sink: Set<string>; edges: [string, string][] } {
361
166
  // Find all reachable nodes from source in residual graph
362
167
  const sourceSet = new Set<string>();
363
168
  const queue = [source];
@@ -402,17 +207,136 @@ function findMinCut(
402
207
  }
403
208
  }
404
209
 
405
- return {source: sourceSet, sink: sinkSet, edges: cutEdges};
210
+ return { source: sourceSet, sink: sinkSet, edges: cutEdges };
211
+ }
212
+
213
+ /**
214
+ * Core max flow algorithm implementation
215
+ * @param graph - The graph with capacity values
216
+ * @param source - The source node
217
+ * @param sink - The sink node
218
+ * @param findPath - Function to find an augmenting path in the residual graph
219
+ * @returns The maximum flow result including flow value, flow graph, and minimum cut
220
+ */
221
+ function maxFlowCore(
222
+ graph: Map<string, Map<string, number>>,
223
+ source: string,
224
+ sink: string,
225
+ findPath: (
226
+ residual: Map<string, Map<string, number>>,
227
+ src: string,
228
+ snk: string,
229
+ ) => { path: string[]; pathCapacity: number } | null,
230
+ ): MaxFlowResult {
231
+ if (!graph.has(source) || !graph.has(sink)) {
232
+ return { maxFlow: 0, flowGraph: new Map() };
233
+ }
234
+
235
+ // Create residual graph
236
+ const residualGraph = createResidualGraph(graph);
237
+ const flowGraph = new Map<string, Map<string, number>>();
238
+
239
+ // Initialize flow graph
240
+ for (const [u, neighbors] of graph) {
241
+ flowGraph.set(u, new Map());
242
+ for (const v of neighbors.keys()) {
243
+ const uFlowNeighbors = flowGraph.get(u);
244
+ if (uFlowNeighbors) {
245
+ uFlowNeighbors.set(v, 0);
246
+ }
247
+ }
248
+ }
249
+
250
+ let maxFlow = 0;
251
+ let pathResult = findPath(residualGraph, source, sink);
252
+
253
+ while (pathResult !== null) {
254
+ const { path, pathCapacity } = pathResult;
255
+
256
+ // Update flow
257
+ updateFlow(residualGraph, flowGraph, graph, path, pathCapacity);
258
+ maxFlow += pathCapacity;
259
+
260
+ // Find next path
261
+ pathResult = findPath(residualGraph, source, sink);
262
+ }
263
+
264
+ // Find minimum cut
265
+ const minCut = findMinCut(residualGraph, source);
266
+
267
+ return { maxFlow, flowGraph, minCut };
268
+ }
269
+
270
+ /**
271
+ * Internal implementation of Ford-Fulkerson algorithm using DFS
272
+ * @param graph - The graph with capacity values
273
+ * @param source - The source node
274
+ * @param sink - The sink node
275
+ * @returns The maximum flow result
276
+ */
277
+ function fordFulkersonImpl(graph: Map<string, Map<string, number>>, source: string, sink: string): MaxFlowResult {
278
+ // Adapter function for DFS path finding
279
+ const findPathDFS = (
280
+ residual: Map<string, Map<string, number>>,
281
+ src: string,
282
+ snk: string,
283
+ ): { path: string[]; pathCapacity: number } | null => {
284
+ const path = findAugmentingPathDFS(residual, src, snk);
285
+ if (!path) {
286
+ return null;
287
+ }
288
+
289
+ // Calculate path capacity
290
+ let pathCapacity = Infinity;
291
+ for (let i = 0; i < path.length - 1; i++) {
292
+ const u = path[i];
293
+ const v = path[i + 1];
294
+ if (u && v) {
295
+ const capacity = residual.get(u)?.get(v);
296
+ if (capacity !== undefined) {
297
+ pathCapacity = Math.min(pathCapacity, capacity);
298
+ }
299
+ }
300
+ }
301
+
302
+ return { path, pathCapacity };
303
+ };
304
+
305
+ return maxFlowCore(graph, source, sink, findPathDFS);
306
+ }
307
+
308
+ /**
309
+ * Internal implementation of Edmonds-Karp algorithm
310
+ * @param graph - The graph with capacity values
311
+ * @param source - The source node
312
+ * @param sink - The sink node
313
+ * @returns The maximum flow result
314
+ */
315
+ function edmondsKarpImpl(graph: Map<string, Map<string, number>>, source: string, sink: string): MaxFlowResult {
316
+ // Use BFS variant for path finding
317
+ const findPathBFS = (
318
+ residual: Map<string, Map<string, number>>,
319
+ src: string,
320
+ snk: string,
321
+ ): { path: string[]; pathCapacity: number } | null => {
322
+ return bfsAugmentingPath(residual, src, snk);
323
+ };
324
+
325
+ return maxFlowCore(graph, source, sink, findPathBFS);
406
326
  }
407
327
 
408
328
  /**
409
329
  * Utility function to create a flow network for bipartite matching
330
+ * @param leftNodes - Array of left partition node identifiers
331
+ * @param rightNodes - Array of right partition node identifiers
332
+ * @param edges - Array of edges connecting left nodes to right nodes
333
+ * @returns The flow network graph with source and sink nodes
410
334
  */
411
335
  export function createBipartiteFlowNetwork(
412
336
  leftNodes: string[],
413
337
  rightNodes: string[],
414
338
  edges: [string, string][],
415
- ): {graph: Map<string, Map<string, number>>, source: string, sink: string} {
339
+ ): { graph: Map<string, Map<string, number>>; source: string; sink: string } {
416
340
  const graph = new Map<string, Map<string, number>>();
417
341
  const source = "__source__";
418
342
  const sink = "__sink__";
@@ -454,6 +378,41 @@ export function createBipartiteFlowNetwork(
454
378
 
455
379
  graph.set(sink, new Map());
456
380
 
457
- return {graph, source, sink};
381
+ return { graph, source, sink };
382
+ }
383
+
384
+ /**
385
+ * Ford-Fulkerson algorithm using DFS for finding augmenting paths
386
+ * @param graph - Adjacency list representation with capacities - accepts Graph class or Map
387
+ * @param source - Source node
388
+ * @param sink - Sink node
389
+ * @returns Maximum flow value and flow graph
390
+ *
391
+ * Time Complexity: O(E * f) where f is the maximum flow
392
+ * Space Complexity: O(V + E)
393
+ */
394
+ export function fordFulkerson(graph: Graph, source: string, sink: string): MaxFlowResult {
395
+ // Convert Graph to Map representation
396
+ const graphMap = graphToMap(graph);
397
+ return fordFulkersonImpl(graphMap, source, sink);
458
398
  }
459
399
 
400
+ /**
401
+ * Edmonds-Karp algorithm (Ford-Fulkerson with BFS)
402
+ * More efficient implementation with better time complexity
403
+ * @param graph - Adjacency list representation with capacities - accepts Graph class or Map
404
+ * @param source - Source node
405
+ * @param sink - Sink node
406
+ * @returns Maximum flow value and flow graph
407
+ *
408
+ * Time Complexity: O(V * E²)
409
+ */
410
+ export function edmondsKarp(
411
+ graph: Graph | Map<string, Map<string, number>>,
412
+ source: string,
413
+ sink: string,
414
+ ): MaxFlowResult {
415
+ // Convert Graph to Map representation if needed
416
+ const graphMap = graph instanceof Map ? graph : graphToMap(graph);
417
+ return edmondsKarpImpl(graphMap, source, sink);
418
+ }