@graphty/graph-samples 0.0.1 → 0.1.1

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 (407) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +123 -0
  3. package/README.md +190 -1
  4. package/dist/chunks/build-DdCe60t3.js +47 -0
  5. package/dist/chunks/build-DdCe60t3.js.map +1 -0
  6. package/dist/chunks/meta-B6toBzaa.js +19 -0
  7. package/dist/chunks/meta-B6toBzaa.js.map +1 -0
  8. package/dist/chunks/meta-BM_YIhlA.js +28 -0
  9. package/dist/chunks/meta-BM_YIhlA.js.map +1 -0
  10. package/dist/chunks/meta-BMmtUpPx.js +30 -0
  11. package/dist/chunks/meta-BMmtUpPx.js.map +1 -0
  12. package/dist/chunks/meta-BXC7oi86.js +22 -0
  13. package/dist/chunks/meta-BXC7oi86.js.map +1 -0
  14. package/dist/chunks/meta-BaFPvhc1.js +19 -0
  15. package/dist/chunks/meta-BaFPvhc1.js.map +1 -0
  16. package/dist/chunks/meta-C58v1Oy0.js +28 -0
  17. package/dist/chunks/meta-C58v1Oy0.js.map +1 -0
  18. package/dist/chunks/meta-CQRXyexG.js +23 -0
  19. package/dist/chunks/meta-CQRXyexG.js.map +1 -0
  20. package/dist/chunks/meta-DrgM1eS0.js +23 -0
  21. package/dist/chunks/meta-DrgM1eS0.js.map +1 -0
  22. package/dist/chunks/meta-IhoaDXAV.js +19 -0
  23. package/dist/chunks/meta-IhoaDXAV.js.map +1 -0
  24. package/dist/chunks/meta-MQPbBUUB.js +29 -0
  25. package/dist/chunks/meta-MQPbBUUB.js.map +1 -0
  26. package/dist/chunks/meta-Qp4HNYAZ.js +24 -0
  27. package/dist/chunks/meta-Qp4HNYAZ.js.map +1 -0
  28. package/dist/chunks/meta-mns0uFIW.js +19 -0
  29. package/dist/chunks/meta-mns0uFIW.js.map +1 -0
  30. package/dist/datasets/celegans-neural.d.ts +1 -0
  31. package/dist/datasets/celegans-neural.js +7359 -0
  32. package/dist/datasets/celegans-neural.js.map +1 -0
  33. package/dist/datasets/contiguous-usa.d.ts +1 -0
  34. package/dist/datasets/contiguous-usa.js +501 -0
  35. package/dist/datasets/contiguous-usa.js.map +1 -0
  36. package/dist/datasets/davis-southern-women.d.ts +1 -0
  37. package/dist/datasets/davis-southern-women.js +235 -0
  38. package/dist/datasets/davis-southern-women.js.map +1 -0
  39. package/dist/datasets/dolphins.d.ts +1 -0
  40. package/dist/datasets/dolphins.js +406 -0
  41. package/dist/datasets/dolphins.js.map +1 -0
  42. package/dist/datasets/florentine-families.d.ts +1 -0
  43. package/dist/datasets/florentine-families.js +75 -0
  44. package/dist/datasets/florentine-families.js.map +1 -0
  45. package/dist/datasets/football.d.ts +1 -0
  46. package/dist/datasets/football.js +1508 -0
  47. package/dist/datasets/football.js.map +1 -0
  48. package/dist/datasets/karate.d.ts +1 -0
  49. package/dist/datasets/karate.js +295 -0
  50. package/dist/datasets/karate.js.map +1 -0
  51. package/dist/datasets/knuth-miles.d.ts +1 -0
  52. package/dist/datasets/knuth-miles.js +24933 -0
  53. package/dist/datasets/knuth-miles.js.map +1 -0
  54. package/dist/datasets/les-miserables.d.ts +1 -0
  55. package/dist/datasets/les-miserables.js +860 -0
  56. package/dist/datasets/les-miserables.js.map +1 -0
  57. package/dist/datasets/openflights.d.ts +1 -0
  58. package/dist/datasets/openflights.js +130277 -0
  59. package/dist/datasets/openflights.js.map +1 -0
  60. package/dist/datasets/political-blogs.d.ts +1 -0
  61. package/dist/datasets/political-blogs.js +42551 -0
  62. package/dist/datasets/political-blogs.js.map +1 -0
  63. package/dist/datasets/political-books.d.ts +1 -0
  64. package/dist/datasets/political-books.js +1124 -0
  65. package/dist/datasets/political-books.js.map +1 -0
  66. package/dist/generators.d.ts +1 -0
  67. package/dist/generators.js +4496 -0
  68. package/dist/generators.js.map +1 -0
  69. package/dist/graph-samples.d.ts +1 -0
  70. package/dist/graph-samples.js +142 -0
  71. package/dist/graph-samples.js.map +1 -0
  72. package/dist/src/datasets/build.d.ts +89 -0
  73. package/dist/src/datasets/build.d.ts.map +1 -0
  74. package/dist/src/datasets/build.js +53 -0
  75. package/dist/src/datasets/build.js.map +1 -0
  76. package/dist/src/datasets/catalog.d.ts +8 -0
  77. package/dist/src/datasets/catalog.d.ts.map +1 -0
  78. package/dist/src/datasets/catalog.js +34 -0
  79. package/dist/src/datasets/catalog.js.map +1 -0
  80. package/dist/src/datasets/celegans-neural/data.d.ts +3 -0
  81. package/dist/src/datasets/celegans-neural/data.d.ts.map +1 -0
  82. package/dist/src/datasets/celegans-neural/data.js +573 -0
  83. package/dist/src/datasets/celegans-neural/data.js.map +1 -0
  84. package/dist/src/datasets/celegans-neural/index.d.ts +11 -0
  85. package/dist/src/datasets/celegans-neural/index.d.ts.map +1 -0
  86. package/dist/src/datasets/celegans-neural/index.js +14 -0
  87. package/dist/src/datasets/celegans-neural/index.js.map +1 -0
  88. package/dist/src/datasets/celegans-neural/meta.d.ts +4 -0
  89. package/dist/src/datasets/celegans-neural/meta.d.ts.map +1 -0
  90. package/dist/src/datasets/celegans-neural/meta.js +21 -0
  91. package/dist/src/datasets/celegans-neural/meta.js.map +1 -0
  92. package/dist/src/datasets/contiguous-usa/data.d.ts +3 -0
  93. package/dist/src/datasets/contiguous-usa/data.d.ts.map +1 -0
  94. package/dist/src/datasets/contiguous-usa/data.js +162 -0
  95. package/dist/src/datasets/contiguous-usa/data.js.map +1 -0
  96. package/dist/src/datasets/contiguous-usa/index.d.ts +11 -0
  97. package/dist/src/datasets/contiguous-usa/index.d.ts.map +1 -0
  98. package/dist/src/datasets/contiguous-usa/index.js +14 -0
  99. package/dist/src/datasets/contiguous-usa/index.js.map +1 -0
  100. package/dist/src/datasets/contiguous-usa/meta.d.ts +4 -0
  101. package/dist/src/datasets/contiguous-usa/meta.d.ts.map +1 -0
  102. package/dist/src/datasets/contiguous-usa/meta.js +27 -0
  103. package/dist/src/datasets/contiguous-usa/meta.js.map +1 -0
  104. package/dist/src/datasets/davis-southern-women/data.d.ts +3 -0
  105. package/dist/src/datasets/davis-southern-women/data.d.ts.map +1 -0
  106. package/dist/src/datasets/davis-southern-women/data.js +57 -0
  107. package/dist/src/datasets/davis-southern-women/data.js.map +1 -0
  108. package/dist/src/datasets/davis-southern-women/index.d.ts +11 -0
  109. package/dist/src/datasets/davis-southern-women/index.d.ts.map +1 -0
  110. package/dist/src/datasets/davis-southern-women/index.js +14 -0
  111. package/dist/src/datasets/davis-southern-women/index.js.map +1 -0
  112. package/dist/src/datasets/davis-southern-women/meta.d.ts +4 -0
  113. package/dist/src/datasets/davis-southern-women/meta.d.ts.map +1 -0
  114. package/dist/src/datasets/davis-southern-women/meta.js +17 -0
  115. package/dist/src/datasets/davis-southern-women/meta.js.map +1 -0
  116. package/dist/src/datasets/dolphins/data.d.ts +3 -0
  117. package/dist/src/datasets/dolphins/data.d.ts.map +1 -0
  118. package/dist/src/datasets/dolphins/data.js +93 -0
  119. package/dist/src/datasets/dolphins/data.js.map +1 -0
  120. package/dist/src/datasets/dolphins/index.d.ts +11 -0
  121. package/dist/src/datasets/dolphins/index.d.ts.map +1 -0
  122. package/dist/src/datasets/dolphins/index.js +14 -0
  123. package/dist/src/datasets/dolphins/index.js.map +1 -0
  124. package/dist/src/datasets/dolphins/meta.d.ts +4 -0
  125. package/dist/src/datasets/dolphins/meta.d.ts.map +1 -0
  126. package/dist/src/datasets/dolphins/meta.js +17 -0
  127. package/dist/src/datasets/dolphins/meta.js.map +1 -0
  128. package/dist/src/datasets/florentine-families/data.d.ts +3 -0
  129. package/dist/src/datasets/florentine-families/data.d.ts.map +1 -0
  130. package/dist/src/datasets/florentine-families/data.js +31 -0
  131. package/dist/src/datasets/florentine-families/data.js.map +1 -0
  132. package/dist/src/datasets/florentine-families/index.d.ts +11 -0
  133. package/dist/src/datasets/florentine-families/index.d.ts.map +1 -0
  134. package/dist/src/datasets/florentine-families/index.js +14 -0
  135. package/dist/src/datasets/florentine-families/index.js.map +1 -0
  136. package/dist/src/datasets/florentine-families/meta.d.ts +4 -0
  137. package/dist/src/datasets/florentine-families/meta.d.ts.map +1 -0
  138. package/dist/src/datasets/florentine-families/meta.js +17 -0
  139. package/dist/src/datasets/florentine-families/meta.js.map +1 -0
  140. package/dist/src/datasets/football/data.d.ts +3 -0
  141. package/dist/src/datasets/football/data.d.ts.map +1 -0
  142. package/dist/src/datasets/football/data.js +210 -0
  143. package/dist/src/datasets/football/data.js.map +1 -0
  144. package/dist/src/datasets/football/index.d.ts +11 -0
  145. package/dist/src/datasets/football/index.d.ts.map +1 -0
  146. package/dist/src/datasets/football/index.js +14 -0
  147. package/dist/src/datasets/football/index.js.map +1 -0
  148. package/dist/src/datasets/football/meta.d.ts +4 -0
  149. package/dist/src/datasets/football/meta.d.ts.map +1 -0
  150. package/dist/src/datasets/football/meta.js +17 -0
  151. package/dist/src/datasets/football/meta.js.map +1 -0
  152. package/dist/src/datasets/hosted.d.ts +7 -0
  153. package/dist/src/datasets/hosted.d.ts.map +1 -0
  154. package/dist/src/datasets/hosted.js +80 -0
  155. package/dist/src/datasets/hosted.js.map +1 -0
  156. package/dist/src/datasets/karate/data.d.ts +3 -0
  157. package/dist/src/datasets/karate/data.d.ts.map +1 -0
  158. package/dist/src/datasets/karate/data.js +30 -0
  159. package/dist/src/datasets/karate/data.js.map +1 -0
  160. package/dist/src/datasets/karate/index.d.ts +11 -0
  161. package/dist/src/datasets/karate/index.d.ts.map +1 -0
  162. package/dist/src/datasets/karate/index.js +14 -0
  163. package/dist/src/datasets/karate/index.js.map +1 -0
  164. package/dist/src/datasets/karate/meta.d.ts +4 -0
  165. package/dist/src/datasets/karate/meta.d.ts.map +1 -0
  166. package/dist/src/datasets/karate/meta.js +22 -0
  167. package/dist/src/datasets/karate/meta.js.map +1 -0
  168. package/dist/src/datasets/knuth-miles/data.d.ts +3 -0
  169. package/dist/src/datasets/knuth-miles/data.d.ts.map +1 -0
  170. package/dist/src/datasets/knuth-miles/data.js +1203 -0
  171. package/dist/src/datasets/knuth-miles/data.js.map +1 -0
  172. package/dist/src/datasets/knuth-miles/index.d.ts +11 -0
  173. package/dist/src/datasets/knuth-miles/index.d.ts.map +1 -0
  174. package/dist/src/datasets/knuth-miles/index.js +14 -0
  175. package/dist/src/datasets/knuth-miles/index.js.map +1 -0
  176. package/dist/src/datasets/knuth-miles/meta.d.ts +4 -0
  177. package/dist/src/datasets/knuth-miles/meta.d.ts.map +1 -0
  178. package/dist/src/datasets/knuth-miles/meta.js +26 -0
  179. package/dist/src/datasets/knuth-miles/meta.js.map +1 -0
  180. package/dist/src/datasets/les-miserables/data.d.ts +3 -0
  181. package/dist/src/datasets/les-miserables/data.d.ts.map +1 -0
  182. package/dist/src/datasets/les-miserables/data.js +117 -0
  183. package/dist/src/datasets/les-miserables/data.js.map +1 -0
  184. package/dist/src/datasets/les-miserables/index.d.ts +11 -0
  185. package/dist/src/datasets/les-miserables/index.d.ts.map +1 -0
  186. package/dist/src/datasets/les-miserables/index.js +14 -0
  187. package/dist/src/datasets/les-miserables/index.js.map +1 -0
  188. package/dist/src/datasets/les-miserables/meta.d.ts +4 -0
  189. package/dist/src/datasets/les-miserables/meta.d.ts.map +1 -0
  190. package/dist/src/datasets/les-miserables/meta.js +21 -0
  191. package/dist/src/datasets/les-miserables/meta.js.map +1 -0
  192. package/dist/src/datasets/openflights/data.d.ts +3 -0
  193. package/dist/src/datasets/openflights/data.d.ts.map +1 -0
  194. package/dist/src/datasets/openflights/data.js +15457 -0
  195. package/dist/src/datasets/openflights/data.js.map +1 -0
  196. package/dist/src/datasets/openflights/index.d.ts +11 -0
  197. package/dist/src/datasets/openflights/index.d.ts.map +1 -0
  198. package/dist/src/datasets/openflights/index.js +14 -0
  199. package/dist/src/datasets/openflights/index.js.map +1 -0
  200. package/dist/src/datasets/openflights/meta.d.ts +4 -0
  201. package/dist/src/datasets/openflights/meta.d.ts.map +1 -0
  202. package/dist/src/datasets/openflights/meta.js +28 -0
  203. package/dist/src/datasets/openflights/meta.js.map +1 -0
  204. package/dist/src/datasets/political-blogs/data.d.ts +3 -0
  205. package/dist/src/datasets/political-blogs/data.d.ts.map +1 -0
  206. package/dist/src/datasets/political-blogs/data.js +4857 -0
  207. package/dist/src/datasets/political-blogs/data.js.map +1 -0
  208. package/dist/src/datasets/political-blogs/index.d.ts +11 -0
  209. package/dist/src/datasets/political-blogs/index.d.ts.map +1 -0
  210. package/dist/src/datasets/political-blogs/index.js +14 -0
  211. package/dist/src/datasets/political-blogs/index.js.map +1 -0
  212. package/dist/src/datasets/political-blogs/meta.d.ts +4 -0
  213. package/dist/src/datasets/political-blogs/meta.d.ts.map +1 -0
  214. package/dist/src/datasets/political-blogs/meta.js +26 -0
  215. package/dist/src/datasets/political-blogs/meta.js.map +1 -0
  216. package/dist/src/datasets/political-books/data.d.ts +3 -0
  217. package/dist/src/datasets/political-books/data.d.ts.map +1 -0
  218. package/dist/src/datasets/political-books/data.js +165 -0
  219. package/dist/src/datasets/political-books/data.js.map +1 -0
  220. package/dist/src/datasets/political-books/index.d.ts +11 -0
  221. package/dist/src/datasets/political-books/index.d.ts.map +1 -0
  222. package/dist/src/datasets/political-books/index.js +14 -0
  223. package/dist/src/datasets/political-books/index.js.map +1 -0
  224. package/dist/src/datasets/political-books/meta.d.ts +4 -0
  225. package/dist/src/datasets/political-books/meta.d.ts.map +1 -0
  226. package/dist/src/datasets/political-books/meta.js +20 -0
  227. package/dist/src/datasets/political-books/meta.js.map +1 -0
  228. package/dist/src/datasets/remote.d.ts +27 -0
  229. package/dist/src/datasets/remote.d.ts.map +1 -0
  230. package/dist/src/datasets/remote.js +30 -0
  231. package/dist/src/datasets/remote.js.map +1 -0
  232. package/dist/src/element.d.ts +20 -0
  233. package/dist/src/element.d.ts.map +1 -0
  234. package/dist/src/element.js +27 -0
  235. package/dist/src/element.js.map +1 -0
  236. package/dist/src/generators/bipartite.d.ts +51 -0
  237. package/dist/src/generators/bipartite.d.ts.map +1 -0
  238. package/dist/src/generators/bipartite.js +99 -0
  239. package/dist/src/generators/bipartite.js.map +1 -0
  240. package/dist/src/generators/block-model.d.ts +75 -0
  241. package/dist/src/generators/block-model.d.ts.map +1 -0
  242. package/dist/src/generators/block-model.js +116 -0
  243. package/dist/src/generators/block-model.js.map +1 -0
  244. package/dist/src/generators/classic.d.ts +208 -0
  245. package/dist/src/generators/classic.d.ts.map +1 -0
  246. package/dist/src/generators/classic.js +437 -0
  247. package/dist/src/generators/classic.js.map +1 -0
  248. package/dist/src/generators/degree-sequence.d.ts +273 -0
  249. package/dist/src/generators/degree-sequence.d.ts.map +1 -0
  250. package/dist/src/generators/degree-sequence.js +646 -0
  251. package/dist/src/generators/degree-sequence.js.map +1 -0
  252. package/dist/src/generators/directed.d.ts +141 -0
  253. package/dist/src/generators/directed.d.ts.map +1 -0
  254. package/dist/src/generators/directed.js +329 -0
  255. package/dist/src/generators/directed.js.map +1 -0
  256. package/dist/src/generators/erdos-renyi.d.ts +58 -0
  257. package/dist/src/generators/erdos-renyi.d.ts.map +1 -0
  258. package/dist/src/generators/erdos-renyi.js +154 -0
  259. package/dist/src/generators/erdos-renyi.js.map +1 -0
  260. package/dist/src/generators/flow.d.ts +153 -0
  261. package/dist/src/generators/flow.d.ts.map +1 -0
  262. package/dist/src/generators/flow.js +346 -0
  263. package/dist/src/generators/flow.js.map +1 -0
  264. package/dist/src/generators/geometric.d.ts +133 -0
  265. package/dist/src/generators/geometric.d.ts.map +1 -0
  266. package/dist/src/generators/geometric.js +495 -0
  267. package/dist/src/generators/geometric.js.map +1 -0
  268. package/dist/src/generators/growth.d.ts +187 -0
  269. package/dist/src/generators/growth.d.ts.map +1 -0
  270. package/dist/src/generators/growth.js +445 -0
  271. package/dist/src/generators/growth.js.map +1 -0
  272. package/dist/src/generators/hyperbolic.d.ts +84 -0
  273. package/dist/src/generators/hyperbolic.d.ts.map +1 -0
  274. package/dist/src/generators/hyperbolic.js +153 -0
  275. package/dist/src/generators/hyperbolic.js.map +1 -0
  276. package/dist/src/generators/index.d.ts +25 -0
  277. package/dist/src/generators/index.d.ts.map +1 -0
  278. package/dist/src/generators/index.js +24 -0
  279. package/dist/src/generators/index.js.map +1 -0
  280. package/dist/src/generators/lattices.d.ts +87 -0
  281. package/dist/src/generators/lattices.d.ts.map +1 -0
  282. package/dist/src/generators/lattices.js +237 -0
  283. package/dist/src/generators/lattices.js.map +1 -0
  284. package/dist/src/generators/lfr.d.ts +55 -0
  285. package/dist/src/generators/lfr.d.ts.map +1 -0
  286. package/dist/src/generators/lfr.js +178 -0
  287. package/dist/src/generators/lfr.js.map +1 -0
  288. package/dist/src/generators/named.d.ts +23 -0
  289. package/dist/src/generators/named.d.ts.map +1 -0
  290. package/dist/src/generators/named.js +191 -0
  291. package/dist/src/generators/named.js.map +1 -0
  292. package/dist/src/generators/preferential-attachment.d.ts +66 -0
  293. package/dist/src/generators/preferential-attachment.d.ts.map +1 -0
  294. package/dist/src/generators/preferential-attachment.js +157 -0
  295. package/dist/src/generators/preferential-attachment.js.map +1 -0
  296. package/dist/src/generators/trees-and-dags.d.ts +53 -0
  297. package/dist/src/generators/trees-and-dags.d.ts.map +1 -0
  298. package/dist/src/generators/trees-and-dags.js +108 -0
  299. package/dist/src/generators/trees-and-dags.js.map +1 -0
  300. package/dist/src/generators/util.d.ts +84 -0
  301. package/dist/src/generators/util.d.ts.map +1 -0
  302. package/dist/src/generators/util.js +138 -0
  303. package/dist/src/generators/util.js.map +1 -0
  304. package/dist/src/generators/variants.d.ts +85 -0
  305. package/dist/src/generators/variants.d.ts.map +1 -0
  306. package/dist/src/generators/variants.js +215 -0
  307. package/dist/src/generators/variants.js.map +1 -0
  308. package/dist/src/generators/weights.d.ts +65 -0
  309. package/dist/src/generators/weights.d.ts.map +1 -0
  310. package/dist/src/generators/weights.js +135 -0
  311. package/dist/src/generators/weights.js.map +1 -0
  312. package/dist/src/index.d.ts +12 -0
  313. package/dist/src/index.d.ts.map +1 -0
  314. package/dist/src/index.js +10 -0
  315. package/dist/src/index.js.map +1 -0
  316. package/dist/src/random/exp.d.ts +23 -0
  317. package/dist/src/random/exp.d.ts.map +1 -0
  318. package/dist/src/random/exp.js +101 -0
  319. package/dist/src/random/exp.js.map +1 -0
  320. package/dist/src/random/log.d.ts +19 -0
  321. package/dist/src/random/log.d.ts.map +1 -0
  322. package/dist/src/random/log.js +83 -0
  323. package/dist/src/random/log.js.map +1 -0
  324. package/dist/src/random/stream.d.ts +93 -0
  325. package/dist/src/random/stream.d.ts.map +1 -0
  326. package/dist/src/random/stream.js +154 -0
  327. package/dist/src/random/stream.js.map +1 -0
  328. package/dist/src/random/threefry.d.ts +19 -0
  329. package/dist/src/random/threefry.d.ts.map +1 -0
  330. package/dist/src/random/threefry.js +43 -0
  331. package/dist/src/random/threefry.js.map +1 -0
  332. package/dist/src/random/trig.d.ts +16 -0
  333. package/dist/src/random/trig.d.ts.map +1 -0
  334. package/dist/src/random/trig.js +78 -0
  335. package/dist/src/random/trig.js.map +1 -0
  336. package/dist/src/types.d.ts +28 -0
  337. package/dist/src/types.d.ts.map +1 -0
  338. package/dist/src/types.js +2 -0
  339. package/dist/src/types.js.map +1 -0
  340. package/package.json +102 -5
  341. package/src/datasets/build.ts +140 -0
  342. package/src/datasets/catalog.ts +35 -0
  343. package/src/datasets/celegans-neural/data.ts +575 -0
  344. package/src/datasets/celegans-neural/index.ts +17 -0
  345. package/src/datasets/celegans-neural/meta.ts +25 -0
  346. package/src/datasets/contiguous-usa/data.ts +164 -0
  347. package/src/datasets/contiguous-usa/index.ts +17 -0
  348. package/src/datasets/contiguous-usa/meta.ts +31 -0
  349. package/src/datasets/davis-southern-women/data.ts +59 -0
  350. package/src/datasets/davis-southern-women/index.ts +17 -0
  351. package/src/datasets/davis-southern-women/meta.ts +20 -0
  352. package/src/datasets/dolphins/data.ts +95 -0
  353. package/src/datasets/dolphins/index.ts +17 -0
  354. package/src/datasets/dolphins/meta.ts +21 -0
  355. package/src/datasets/florentine-families/data.ts +33 -0
  356. package/src/datasets/florentine-families/index.ts +17 -0
  357. package/src/datasets/florentine-families/meta.ts +20 -0
  358. package/src/datasets/football/data.ts +212 -0
  359. package/src/datasets/football/index.ts +17 -0
  360. package/src/datasets/football/meta.ts +20 -0
  361. package/src/datasets/hosted.ts +90 -0
  362. package/src/datasets/karate/data.ts +32 -0
  363. package/src/datasets/karate/index.ts +17 -0
  364. package/src/datasets/karate/meta.ts +25 -0
  365. package/src/datasets/knuth-miles/data.ts +1205 -0
  366. package/src/datasets/knuth-miles/index.ts +17 -0
  367. package/src/datasets/knuth-miles/meta.ts +29 -0
  368. package/src/datasets/les-miserables/data.ts +119 -0
  369. package/src/datasets/les-miserables/index.ts +17 -0
  370. package/src/datasets/les-miserables/meta.ts +24 -0
  371. package/src/datasets/openflights/data.ts +15459 -0
  372. package/src/datasets/openflights/index.ts +17 -0
  373. package/src/datasets/openflights/meta.ts +31 -0
  374. package/src/datasets/political-blogs/data.ts +4859 -0
  375. package/src/datasets/political-blogs/index.ts +17 -0
  376. package/src/datasets/political-blogs/meta.ts +30 -0
  377. package/src/datasets/political-books/data.ts +167 -0
  378. package/src/datasets/political-books/index.ts +17 -0
  379. package/src/datasets/political-books/meta.ts +23 -0
  380. package/src/datasets/remote.ts +42 -0
  381. package/src/element.ts +41 -0
  382. package/src/generators/bipartite.ts +127 -0
  383. package/src/generators/block-model.ts +160 -0
  384. package/src/generators/classic.ts +461 -0
  385. package/src/generators/degree-sequence.ts +807 -0
  386. package/src/generators/directed.ts +418 -0
  387. package/src/generators/erdos-renyi.ts +188 -0
  388. package/src/generators/flow.ts +443 -0
  389. package/src/generators/geometric.ts +591 -0
  390. package/src/generators/growth.ts +532 -0
  391. package/src/generators/hyperbolic.ts +193 -0
  392. package/src/generators/index.ts +133 -0
  393. package/src/generators/lattices.ts +290 -0
  394. package/src/generators/lfr.ts +227 -0
  395. package/src/generators/named.ts +198 -0
  396. package/src/generators/preferential-attachment.ts +188 -0
  397. package/src/generators/trees-and-dags.ts +139 -0
  398. package/src/generators/util.ts +167 -0
  399. package/src/generators/variants.ts +253 -0
  400. package/src/generators/weights.ts +177 -0
  401. package/src/index.ts +12 -0
  402. package/src/random/exp.ts +104 -0
  403. package/src/random/log.ts +86 -0
  404. package/src/random/stream.ts +169 -0
  405. package/src/random/threefry.ts +45 -0
  406. package/src/random/trig.ts +83 -0
  407. package/src/types.ts +28 -0
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Random trees and random directed acyclic graphs.
3
+ */
4
+
5
+ import { type U32 } from "@graphty/graph-format";
6
+
7
+ import { detLog } from "../random/log.js";
8
+ import { RandomStream, resolveSeed } from "../random/stream.js";
9
+ import { type SampleGraph } from "../types.js";
10
+ import { bernoulliSegment, binomialBuffer, checkInt, checkProbability, EdgeBuffer, toGraph } from "./util.js";
11
+ import { applyWeights, type WeightOptions } from "./weights.js";
12
+
13
+ /** Options of {@link randomTreeGraph}. */
14
+ export interface RandomTreeOptions extends WeightOptions {
15
+ /** The node count, >= 1. */
16
+ n: number;
17
+ /** The seed, an integer in [0, 2^53); default 0. */
18
+ seed?: number | undefined;
19
+ }
20
+
21
+ /**
22
+ * A uniformly random labelled tree: a uniformly random Pruefer sequence (H. Pruefer, Archiv der
23
+ * Mathematik und Physik 27, 142-144, 1918) of n - 2 draws nextBelow(n) from stream (seed,
24
+ * "prufer", 0), decoded in O(n). Edge k joins the k-th removed leaf to its neighbour; the last
25
+ * edge is (leaf, n - 1).
26
+ * @param options - n and seed
27
+ * @returns the undirected tree
28
+ */
29
+ export function randomTreeGraph(options: RandomTreeOptions): SampleGraph {
30
+ const { n } = options;
31
+ checkInt("n", n, 1);
32
+ const seed = resolveSeed(options.seed);
33
+ const out = new EdgeBuffer(n);
34
+ if (n === 1) {
35
+ return applyWeights(toGraph(1, out, false), options);
36
+ }
37
+ const stream = new RandomStream(seed, "prufer", 0);
38
+ const code = new Uint32Array(n - 2);
39
+ const degree = new Uint32Array(n).fill(1);
40
+ for (let i = 0; i < n - 2; i++) {
41
+ code[i] = stream.nextBelow(n);
42
+ degree[code[i]]++;
43
+ }
44
+ let ptr = 0;
45
+ while (degree[ptr] !== 1) {
46
+ ptr++;
47
+ }
48
+ let leaf = ptr;
49
+ for (let i = 0; i < n - 2; i++) {
50
+ const v = code[i];
51
+ out.push(leaf, v);
52
+ degree[v]--;
53
+ if (degree[v] === 1 && v < ptr) {
54
+ leaf = v;
55
+ } else {
56
+ ptr++;
57
+ while (degree[ptr] !== 1) {
58
+ ptr++;
59
+ }
60
+ leaf = ptr;
61
+ }
62
+ }
63
+ out.push(leaf, n - 1);
64
+ return applyWeights(toGraph(n, out, false), options);
65
+ }
66
+
67
+ /** Options of {@link randomDagGraph}. */
68
+ export interface RandomDagOptions extends WeightOptions {
69
+ /** The width of every layer, top to bottom; layer i holds the next `layers[i]` node indices. */
70
+ layers: readonly number[];
71
+ /** The probability of each arc from a node to a node of the next layer. */
72
+ p: number;
73
+ /** The seed, an integer in [0, 2^53); default 0. */
74
+ seed?: number | undefined;
75
+ }
76
+
77
+ /**
78
+ * Rows [start, end) of the layered DAG: node u of layer i < L - 1 draws from stream (seed,
79
+ * "layered-dag", u) and holds the arcs to the chosen nodes of layer i + 1, ascending.
80
+ * @param starts - starts[i] = first node of layer i; starts[L] = n
81
+ * @param layerOf - the layer of every node
82
+ * @param p - the probability
83
+ * @param seed - the seed
84
+ * @param start - the first row
85
+ * @param end - one past the last row
86
+ * @param out - receives the arcs
87
+ */
88
+ export function dagRows(
89
+ starts: readonly number[],
90
+ layerOf: U32,
91
+ p: number,
92
+ seed: number,
93
+ start: number,
94
+ end: number,
95
+ out: EdgeBuffer,
96
+ ): void {
97
+ const logQ = detLog(1 - p);
98
+ const stream = new RandomStream(seed, "layered-dag", 0);
99
+ const last = starts.length - 2;
100
+ for (let u = start; u < end; u++) {
101
+ const layer = layerOf[u];
102
+ if (layer < last) {
103
+ stream.reset(u);
104
+ bernoulliSegment(stream, p, logQ, u, starts[layer + 1], starts[layer + 2], out);
105
+ }
106
+ }
107
+ }
108
+
109
+ /**
110
+ * A random layered DAG: arcs only from layer i to layer i + 1, each independently with
111
+ * probability p, O(n + m). The standard input for layered (Sugiyama) drawing, topological sort
112
+ * and longest path. Arcs are listed by source node, targets ascending. Node column `layer` (u32).
113
+ * @param options - layers, p and seed
114
+ * @returns the directed graph
115
+ */
116
+ export function randomDagGraph(options: RandomDagOptions): SampleGraph {
117
+ const { layers, p } = options;
118
+ checkInt("layers.length", layers.length, 1);
119
+ checkProbability("p", p);
120
+ const seed = resolveSeed(options.seed);
121
+ const starts = [0];
122
+ let pairs = 0;
123
+ for (let i = 0; i < layers.length; i++) {
124
+ checkInt(`layers[${i}]`, layers[i], 0);
125
+ starts.push(starts[i] + layers[i]);
126
+ if (i > 0) {
127
+ pairs += layers[i - 1] * layers[i];
128
+ }
129
+ }
130
+ const n = starts[layers.length];
131
+ checkInt("the total size", n, 0);
132
+ const layerOf = new Uint32Array(n);
133
+ for (let i = 0; i < layers.length; i++) {
134
+ layerOf.fill(i, starts[i], starts[i + 1]);
135
+ }
136
+ const out = binomialBuffer(pairs, p);
137
+ dagRows(starts, layerOf, p, seed, 0, n, out);
138
+ return applyWeights(toGraph(n, out, true, { layer: layerOf }), options);
139
+ }
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Shared plumbing of the generators: argument checks, the growable edge buffer and the Bernoulli
3
+ * row sampler every G(n, p)-style generator is built on.
4
+ */
5
+
6
+ import { MAX_COUNT, type U32 } from "@graphty/graph-format";
7
+
8
+ import { type RandomStream } from "../random/stream.js";
9
+ import { type SampleGraph } from "../types.js";
10
+
11
+ /**
12
+ * Throw unless `value` is an integer in [min, max].
13
+ * @param name - the option name, for the message
14
+ * @param value - the value
15
+ * @param min - the smallest allowed value
16
+ * @param max - the largest allowed value
17
+ */
18
+ export function checkInt(name: string, value: number, min: number, max: number = MAX_COUNT): void {
19
+ if (!Number.isInteger(value) || value < min || value > max) {
20
+ throw new RangeError(`${name} must be an integer in [${min}, ${max}], got ${String(value)}`);
21
+ }
22
+ }
23
+
24
+ /**
25
+ * Throw unless `value` is a probability in [0, 1].
26
+ * @param name - the option name, for the message
27
+ * @param value - the value
28
+ */
29
+ export function checkProbability(name: string, value: number): void {
30
+ if (!(value >= 0 && value <= 1)) {
31
+ throw new RangeError(`${name} must be a probability in [0, 1], got ${String(value)}`);
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Throw unless `count` edges fit a graph-format snapshot.
37
+ * @param count - the edge count
38
+ */
39
+ export function checkEdgeCount(count: number): void {
40
+ if (count > MAX_COUNT) {
41
+ throw new RangeError(`the graph would have ${count} edges, above the limit of ${MAX_COUNT}`);
42
+ }
43
+ }
44
+
45
+ /** A growable pair of Uint32Array edge endpoint arrays. */
46
+ export class EdgeBuffer {
47
+ src: U32;
48
+ dst: U32;
49
+ length = 0;
50
+
51
+ /**
52
+ * An empty buffer.
53
+ * @param capacity - the initial capacity in edges
54
+ */
55
+ constructor(capacity: number) {
56
+ const size = Math.max(16, Math.min(capacity, MAX_COUNT));
57
+ this.src = new Uint32Array(size);
58
+ this.dst = new Uint32Array(size);
59
+ }
60
+
61
+ /**
62
+ * Append one edge.
63
+ * @param u - the source index
64
+ * @param v - the target index
65
+ */
66
+ push(u: number, v: number): void {
67
+ if (this.length === this.src.length) {
68
+ this.grow();
69
+ }
70
+ this.src[this.length] = u;
71
+ this.dst[this.length] = v;
72
+ this.length++;
73
+ }
74
+
75
+ /**
76
+ * The edges pushed so far as exactly sized arrays (copies when the buffer has slack).
77
+ * @returns the endpoint arrays
78
+ */
79
+ finish(): { src: U32; dst: U32 } {
80
+ if (this.length === this.src.length) {
81
+ return { src: this.src, dst: this.dst };
82
+ }
83
+ return { src: this.src.slice(0, this.length), dst: this.dst.slice(0, this.length) };
84
+ }
85
+
86
+ private grow(): void {
87
+ checkEdgeCount(this.length + 1);
88
+ const size = Math.min(this.src.length * 2, MAX_COUNT);
89
+ const src = new Uint32Array(size);
90
+ const dst = new Uint32Array(size);
91
+ src.set(this.src);
92
+ dst.set(this.dst);
93
+ this.src = src;
94
+ this.dst = dst;
95
+ }
96
+ }
97
+
98
+ /**
99
+ * A buffer sized for a binomial number of edges: the mean plus six standard deviations, so it
100
+ * almost never grows.
101
+ * @param pairs - the number of candidate pairs
102
+ * @param p - the edge probability
103
+ * @returns the buffer
104
+ */
105
+ export function binomialBuffer(pairs: number, p: number): EdgeBuffer {
106
+ const mean = pairs * p;
107
+ checkEdgeCount(mean);
108
+ return new EdgeBuffer(Math.ceil(mean + 6 * Math.sqrt(mean * (1 - p)) + 16));
109
+ }
110
+
111
+ /**
112
+ * Append (row, c) for every column c in [lo, hi) chosen independently with probability p, in
113
+ * ascending c, by geometric skipping (V. Batagelj and U. Brandes, "Efficient generation of large
114
+ * random networks", Phys. Rev. E 71, 036113, 2005): O(1 + selected) draws instead of hi - lo.
115
+ * p = 0 and p = 1 draw nothing.
116
+ * @param stream - the row's stream
117
+ * @param p - the probability
118
+ * @param logQ - detLog(1 - p)
119
+ * @param row - the row node, written as the source
120
+ * @param lo - the first candidate column
121
+ * @param hi - one past the last candidate column
122
+ * @param out - the buffer
123
+ */
124
+ export function bernoulliSegment(
125
+ stream: RandomStream,
126
+ p: number,
127
+ logQ: number,
128
+ row: number,
129
+ lo: number,
130
+ hi: number,
131
+ out: EdgeBuffer,
132
+ ): void {
133
+ if (p === 0 || lo >= hi) {
134
+ return;
135
+ }
136
+ if (p === 1) {
137
+ for (let c = lo; c < hi; c++) {
138
+ out.push(row, c);
139
+ }
140
+ return;
141
+ }
142
+ let c = lo + stream.nextSkip(logQ);
143
+ while (c < hi) {
144
+ out.push(row, c);
145
+ c += 1 + stream.nextSkip(logQ);
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Assemble an undirected or directed SampleGraph from a buffer.
151
+ * @param nodeCount - the node count
152
+ * @param edges - the edges
153
+ * @param directed - whether the graph is directed
154
+ * @param nodeColumns - ground-truth columns, if any
155
+ * @returns the graph
156
+ */
157
+ export function toGraph(
158
+ nodeCount: number,
159
+ edges: EdgeBuffer,
160
+ directed: boolean,
161
+ nodeColumns?: SampleGraph["nodeColumns"],
162
+ ): SampleGraph {
163
+ const { src, dst } = edges.finish();
164
+ return nodeColumns === undefined
165
+ ? { directed, nodeCount, src, dst }
166
+ : { directed, nodeCount, src, dst, nodeColumns };
167
+ }
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Structural variants for testing consumers: random multigraphs, a helper that adds self-loops,
3
+ * parallel and anti-parallel edges to any graph, and a pack of small (and a few huge) edge-case
4
+ * graphs that parsers, loaders and algorithms must survive.
5
+ */
6
+
7
+ import { RandomStream, resolveSeed } from "../random/stream.js";
8
+ import { type SampleGraph } from "../types.js";
9
+ import { checkEdgeCount, checkInt } from "./util.js";
10
+ import { applyWeights, type WeightOptions } from "./weights.js";
11
+
12
+ /** Options of {@link randomMultigraph}. */
13
+ export interface RandomMultigraphOptions extends WeightOptions {
14
+ /** The node count, >= 1 (>= 2 without self-loops). */
15
+ n: number;
16
+ /** The edge count, >= 0. */
17
+ m: number;
18
+ /** Whether the edges are directed; default false. */
19
+ directed?: boolean | undefined;
20
+ /** Whether an edge may join a node to itself; default true. */
21
+ selfLoops?: boolean | undefined;
22
+ /** The seed, an integer in [0, 2^53); default 0. */
23
+ seed?: number | undefined;
24
+ }
25
+
26
+ /**
27
+ * A random multigraph: m edges, each an independent uniform ordered pair (u, v) -- drawn with
28
+ * replacement, so parallel edges and (when allowed) self-loops are kept. Undirected, this is the
29
+ * "each endpoint uniform" model: a given self-loop is half as likely as a given pair u != v. Edge e
30
+ * draws u = nextBelow(n) and then v = nextBelow(n), or v = nextBelow(n - 1) shifted past u when
31
+ * self-loops are off, from the stream (seed, "multigraph", 0); one sequential stream, since two
32
+ * draws per edge are cheaper than a per-edge stream derivation. O(m).
33
+ * @param options - n, m, directed, selfLoops and seed
34
+ * @returns the multigraph
35
+ */
36
+ export function randomMultigraph(options: RandomMultigraphOptions): SampleGraph {
37
+ const { n, m } = options;
38
+ const loops = options.selfLoops ?? true;
39
+ checkInt("n", n, 1);
40
+ checkInt("m", m, 0);
41
+ if (!loops && n < 2) {
42
+ throw new RangeError(`selfLoops: false needs n >= 2, got ${n}`);
43
+ }
44
+ const stream = new RandomStream(resolveSeed(options.seed), "multigraph", 0);
45
+ const src = new Uint32Array(m);
46
+ const dst = new Uint32Array(m);
47
+ for (let e = 0; e < m; e++) {
48
+ const u = stream.nextBelow(n);
49
+ let v: number;
50
+ if (loops) {
51
+ v = stream.nextBelow(n);
52
+ } else {
53
+ v = stream.nextBelow(n - 1);
54
+ if (v >= u) {
55
+ v++;
56
+ }
57
+ }
58
+ src[e] = u;
59
+ dst[e] = v;
60
+ }
61
+ return applyWeights({ directed: options.directed ?? false, nodeCount: n, src, dst }, options);
62
+ }
63
+
64
+ /** Options of {@link addPathologicalEdges}. */
65
+ export interface PathologicalEdgeOptions {
66
+ /** How many self-loops to add at uniform nodes; default 0. */
67
+ selfLoops?: number | undefined;
68
+ /** How many copies of uniform existing edges to add; default 0. */
69
+ parallelEdges?: number | undefined;
70
+ /** How many reversed copies of uniform existing arcs to add (directed graphs only); default 0. */
71
+ antiParallelEdges?: number | undefined;
72
+ /** The seed, an integer in [0, 2^53); default 0. */
73
+ seed?: number | undefined;
74
+ }
75
+
76
+ /**
77
+ * A copy of `graph` with pathological edges appended after its own, in this order: `selfLoops`
78
+ * self-loops (v, v) at v = nextBelow(nodeCount); `parallelEdges` copies of edge e =
79
+ * nextBelow(original edge count); `antiParallelEdges` reversed copies (dst[e], src[e]) of
80
+ * e = nextBelow(original edge count). Copies are only ever of the original edges. Draws come from
81
+ * the stream (seed, "pathological", 0) in that order. A weighted graph's copies keep the copied
82
+ * edge's weight and a self-loop gets weight 1. `ids` and `nodeColumns` are shared, not copied.
83
+ * O(m + added).
84
+ * @param graph - the graph
85
+ * @param options - the counts and the seed
86
+ * @returns the new graph
87
+ */
88
+ export function addPathologicalEdges(graph: SampleGraph, options: PathologicalEdgeOptions): SampleGraph {
89
+ const loops = options.selfLoops ?? 0;
90
+ const parallel = options.parallelEdges ?? 0;
91
+ const anti = options.antiParallelEdges ?? 0;
92
+ checkInt("selfLoops", loops, 0);
93
+ checkInt("parallelEdges", parallel, 0);
94
+ checkInt("antiParallelEdges", anti, 0);
95
+ if (anti > 0 && !graph.directed) {
96
+ throw new RangeError("antiParallelEdges needs a directed graph");
97
+ }
98
+ const m = graph.src.length;
99
+ if (loops > 0 && graph.nodeCount === 0) {
100
+ throw new RangeError("selfLoops needs a graph with at least one node");
101
+ }
102
+ if (parallel + anti > 0 && m === 0) {
103
+ throw new RangeError("parallelEdges and antiParallelEdges need a graph with at least one edge");
104
+ }
105
+ const total = m + loops + parallel + anti;
106
+ checkEdgeCount(total);
107
+ const stream = new RandomStream(resolveSeed(options.seed), "pathological", 0);
108
+ const src = new Uint32Array(total);
109
+ const dst = new Uint32Array(total);
110
+ src.set(graph.src);
111
+ dst.set(graph.dst);
112
+ const weights = graph.weights === undefined ? undefined : new Float32Array(total);
113
+ weights?.set(graph.weights ?? []);
114
+ let e = m;
115
+ for (let i = 0; i < loops; i++, e++) {
116
+ const v = stream.nextBelow(graph.nodeCount);
117
+ src[e] = v;
118
+ dst[e] = v;
119
+ if (weights !== undefined) {
120
+ weights[e] = 1;
121
+ }
122
+ }
123
+ for (let i = 0; i < parallel + anti; i++, e++) {
124
+ const f = stream.nextBelow(m);
125
+ const reversed = i >= parallel;
126
+ src[e] = reversed ? graph.dst[f] : graph.src[f];
127
+ dst[e] = reversed ? graph.src[f] : graph.dst[f];
128
+ if (weights !== undefined) {
129
+ weights[e] = weights[f];
130
+ }
131
+ }
132
+ return { ...graph, src, dst, weights };
133
+ }
134
+
135
+ /** The names of the {@link edgeCaseGraph} cases. */
136
+ export const EDGE_CASE_NAMES = [
137
+ "empty",
138
+ "single-node",
139
+ "single-self-loop",
140
+ "isolated-nodes",
141
+ "disconnected",
142
+ "pathological-undirected",
143
+ "pathological-directed",
144
+ "zero-weights",
145
+ "negative-weights",
146
+ "negative-cycle",
147
+ "duplicate-heavy",
148
+ "max-node-index",
149
+ "star-100k",
150
+ "path-100k",
151
+ ] as const;
152
+
153
+ /** One of {@link EDGE_CASE_NAMES}. */
154
+ export type EdgeCaseName = (typeof EDGE_CASE_NAMES)[number];
155
+
156
+ /**
157
+ * A small graph from a flat edge list.
158
+ * @param directed - whether the edges are directed
159
+ * @param nodeCount - the node count
160
+ * @param edges - [u, v, u, v, ...], or [u, v, w, u, v, w, ...] when weighted
161
+ * @param weighted - whether every edge carries a weight
162
+ * @returns the graph
163
+ */
164
+ function build(directed: boolean, nodeCount: number, edges: readonly number[], weighted = false): SampleGraph {
165
+ const stride = weighted ? 3 : 2;
166
+ const m = edges.length / stride;
167
+ const src = new Uint32Array(m);
168
+ const dst = new Uint32Array(m);
169
+ const weights = new Float32Array(weighted ? m : 0);
170
+ for (let e = 0; e < m; e++) {
171
+ src[e] = edges[e * stride];
172
+ dst[e] = edges[e * stride + 1];
173
+ weights[e] = weighted ? edges[e * stride + 2] : 0;
174
+ }
175
+ return weighted ? { directed, nodeCount, src, dst, weights } : { directed, nodeCount, src, dst };
176
+ }
177
+
178
+ /**
179
+ * A graph whose edge e is end(e) for e < m.
180
+ * @param nodeCount - the node count
181
+ * @param m - the edge count
182
+ * @param end - maps e to [source, target]
183
+ * @returns the undirected graph
184
+ */
185
+ function generated(nodeCount: number, m: number, end: (e: number) => [number, number]): SampleGraph {
186
+ const src = new Uint32Array(m);
187
+ const dst = new Uint32Array(m);
188
+ for (let e = 0; e < m; e++) {
189
+ [src[e], dst[e]] = end(e);
190
+ }
191
+ return { directed: false, nodeCount, src, dst };
192
+ }
193
+
194
+ const CASES: Record<EdgeCaseName, () => SampleGraph> = {
195
+ empty: () => build(false, 0, []),
196
+ "single-node": () => build(false, 1, []),
197
+ "single-self-loop": () => build(false, 1, [0, 0]),
198
+ "isolated-nodes": () => build(false, 10, []),
199
+ // triangle 0-1-2, path 3-4-5, edge 6-7, isolated 8 and 9
200
+ disconnected: () => build(false, 10, [0, 1, 1, 2, 2, 0, 3, 4, 4, 5, 6, 7]),
201
+ // self-loop at 0; (1, 2) three times, once written (2, 1); weights 0, negative and fractional
202
+ "pathological-undirected": () =>
203
+ build(false, 4, [0, 0, 1, 1, 2, 0, 1, 2, -2, 2, 1, 0.5, 2, 3, 2.5, 3, 0, -1], true),
204
+ // self-loop at 0; parallel arcs 0 -> 1; the 2-cycle 1 <-> 2 (an anti-parallel pair, one arc
205
+ // of weight 0); the negative cycle 2 -> 3 -> 4 -> 2 of total weight -2, reachable from 0
206
+ "pathological-directed": () =>
207
+ build(true, 5, [0, 0, 1, 0, 1, 2, 0, 1, 3, 1, 2, 1, 2, 1, 0, 2, 3, -1, 3, 4, -2, 4, 2, 1, 1, 3, 0.5], true),
208
+ // a 4-cycle with the chord 0-2, every weight 0: ties everywhere for Dijkstra and MST
209
+ "zero-weights": () => build(false, 4, [0, 1, 0, 1, 2, 0, 2, 3, 0, 3, 0, 0, 0, 2, 0], true),
210
+ // a DAG with negative arcs and no negative cycle; distances from 0 are [0, 4, 1, 4, 3]
211
+ "negative-weights": () => build(true, 5, [0, 1, 4, 0, 2, 2, 1, 2, -3, 1, 3, 2, 2, 3, 3, 3, 4, -1, 2, 4, 5], true),
212
+ // 0 -> 1, then the cycle 1 -> 2 -> 3 -> 1 of total weight -1
213
+ "negative-cycle": () => build(true, 4, [0, 1, 1, 1, 2, -1, 2, 3, -1, 3, 1, 1], true),
214
+ // 1,000 copies of the edge (0, 1)
215
+ "duplicate-heavy": () => generated(2, 1000, () => [0, 1]),
216
+ // 2^20 nodes, edges only at the ends: sparse index handling and large-id output
217
+ "max-node-index": () => build(false, 2 ** 20, [0, 1, 2 ** 20 - 2, 2 ** 20 - 1, 0, 2 ** 20 - 1]),
218
+ // hub 0 with 100,000 leaves
219
+ "star-100k": () => generated(100_001, 100_000, (e) => [0, e + 1]),
220
+ // the path 0 - 1 - ... - 99,999
221
+ "path-100k": () => generated(100_000, 99_999, (e) => [e, e + 1]),
222
+ };
223
+
224
+ /**
225
+ * An edge-case graph for testing parsers, loaders and algorithms. Every case loads with
226
+ * graph-format's `fromEdgeArrays` default options, and each call returns fresh arrays.
227
+ *
228
+ * - `empty`: 0 nodes, 0 edges.
229
+ * - `single-node`: 1 node, no edges.
230
+ * - `single-self-loop`: 1 node with a self-loop.
231
+ * - `isolated-nodes`: 10 nodes, no edges.
232
+ * - `disconnected`: a triangle, a 3-node path, one edge and 2 isolated nodes (5 components).
233
+ * - `pathological-undirected`: a self-loop, a triple parallel edge (one written reversed), weights
234
+ * 0, negative and fractional.
235
+ * - `pathological-directed`: a self-loop, parallel arcs, an anti-parallel pair (a 2-cycle), a
236
+ * negative-weight cycle reachable from 0, zero and negative weights.
237
+ * - `zero-weights`: a 4-cycle plus a chord, all weights 0.
238
+ * - `negative-weights`: a DAG with negative weights and no negative cycle (Bellman-Ford, DAG
239
+ * shortest paths); distances from 0 are [0, 4, 1, 4, 3].
240
+ * - `negative-cycle`: a directed cycle of total weight -1 reachable from node 0.
241
+ * - `duplicate-heavy`: 1,000 copies of the edge (0, 1).
242
+ * - `max-node-index`: 2^20 nodes, 3 edges touching nodes 0, 1, 2^20 - 2 and 2^20 - 1.
243
+ * - `star-100k`: a hub with 100,000 leaves (degree extremes).
244
+ * - `path-100k`: a 100,000-node path (deep recursion, long diameters).
245
+ * @param name - the case
246
+ * @returns the graph
247
+ */
248
+ export function edgeCaseGraph(name: EdgeCaseName): SampleGraph {
249
+ if (!(EDGE_CASE_NAMES as readonly string[]).includes(name)) {
250
+ throw new RangeError(`unknown edge case "${name}"; expected one of ${EDGE_CASE_NAMES.join(", ")}`);
251
+ }
252
+ return CASES[name]();
253
+ }