@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,227 @@
1
+ /**
2
+ * The LFR community-detection benchmark: power-law degrees, power-law community sizes and a
3
+ * mixing parameter, with the planted communities as ground truth.
4
+ */
5
+
6
+ import { RandomStream, resolveSeed } from "../random/stream.js";
7
+ import { type SampleGraph } from "../types.js";
8
+ import { makeSumEven, pairStubs, powerLawSampler, shuffle, stubList } from "./degree-sequence.js";
9
+ import { checkInt, checkProbability, EdgeBuffer, toGraph } from "./util.js";
10
+ import { applyWeights, type WeightOptions } from "./weights.js";
11
+
12
+ /** The largest LFR graph. */
13
+ const MAX_LFR_NODES = 1_000_000;
14
+
15
+ /** Options of {@link lfrGraph}. */
16
+ export interface LfrOptions extends WeightOptions {
17
+ /** The node count, in [1, 1,000,000]. */
18
+ n: number;
19
+ /** The smallest degree, >= 1. */
20
+ minDegree: number;
21
+ /** The largest degree, in [minDegree, n - 1]. */
22
+ maxDegree: number;
23
+ /** The degree power-law exponent (tau1), a finite number >= 0, typically 2 to 3. */
24
+ degreeExponent: number;
25
+ /** The smallest community, >= 1. */
26
+ minCommunity: number;
27
+ /** The largest community, in [minCommunity, n]. */
28
+ maxCommunity: number;
29
+ /** The community-size power-law exponent (tau2), a finite number >= 0, typically 1 to 2. */
30
+ communityExponent: number;
31
+ /** The mixing parameter mu in [0, 1]: the share of each node's edges that leave its community. */
32
+ mixing: number;
33
+ /** The seed, an integer in [0, 2^53); default 0. */
34
+ seed?: number | undefined;
35
+ }
36
+
37
+ /**
38
+ * Community sizes from the power law on [min, max] summing to exactly n: draw sizes from stream
39
+ * (seed, "lfr-sizes", 0) until their sum reaches n; if k sizes of at least `min` no longer fit n,
40
+ * drop the last draw and grow sizes from the last one backwards (each up to max) to close the gap,
41
+ * otherwise shrink them from the last one backwards (each down to min) to remove the excess.
42
+ * @param n - the node count
43
+ * @param min - the smallest size
44
+ * @param max - the largest size
45
+ * @param sample - the power-law sampler
46
+ * @param seed - the seed
47
+ * @returns the sizes
48
+ */
49
+ function communitySizes(
50
+ n: number,
51
+ min: number,
52
+ max: number,
53
+ sample: (stream: RandomStream) => number,
54
+ seed: number,
55
+ ): number[] {
56
+ if (Math.ceil(n / max) * min > n) {
57
+ throw new RangeError(`there is no partition of ${n} nodes into communities of ${min} to ${max} nodes`);
58
+ }
59
+ const stream = new RandomStream(seed, "lfr-sizes", 0);
60
+ const sizes: number[] = [];
61
+ let excess = -n;
62
+ while (excess < 0) {
63
+ const s = sample(stream);
64
+ sizes.push(s);
65
+ excess += s;
66
+ }
67
+ if (sizes.length * min > n) {
68
+ excess -= sizes[sizes.length - 1];
69
+ sizes.pop();
70
+ }
71
+ // the feasibility check above guarantees these loops close the gap exactly
72
+ for (let i = sizes.length - 1; i >= 0 && excess !== 0; i--) {
73
+ const change = excess > 0 ? -Math.min(excess, sizes[i] - min) : Math.min(-excess, max - sizes[i]);
74
+ sizes[i] += change;
75
+ excess += change;
76
+ }
77
+ return sizes;
78
+ }
79
+
80
+ /**
81
+ * Assign every node a community larger than its internal degree: nodes by internal degree
82
+ * descending (ties by index), each to a uniform choice (nextBelow of stream (seed, "lfr-assign", 0))
83
+ * among the communities with room whose size exceeds its internal degree. The communities that fit
84
+ * only grow as the internal degree falls, so this fails exactly when no assignment exists.
85
+ * @param internal - the internal degree of every node
86
+ * @param sizes - the community sizes (summing to the node count)
87
+ * @param seed - the seed
88
+ * @returns the community of every node
89
+ */
90
+ function assignCommunities(internal: Uint32Array, sizes: readonly number[], seed: number): Uint32Array<ArrayBuffer> {
91
+ const n = internal.length;
92
+ const nodes = Uint32Array.from({ length: n }, (_, i) => i).sort((a, b) => internal[b] - internal[a] || a - b);
93
+ const bySize = Uint32Array.from(sizes, (_, i) => i).sort((a, b) => sizes[b] - sizes[a] || a - b);
94
+ const room = sizes.slice();
95
+ const open: number[] = [];
96
+ const community = new Uint32Array(n);
97
+ const stream = new RandomStream(seed, "lfr-assign", 0);
98
+ let next = 0;
99
+ for (const node of nodes) {
100
+ while (next < bySize.length && sizes[bySize[next]] > internal[node]) {
101
+ open.push(bySize[next++]);
102
+ }
103
+ if (open.length === 0) {
104
+ throw new RangeError(
105
+ `could not assign communities: node ${node} needs a community of more than ${internal[node]} nodes; ` +
106
+ `raise maxCommunity or mixing, or lower maxDegree`,
107
+ );
108
+ }
109
+ const j = stream.nextBelow(open.length);
110
+ const c = open[j];
111
+ community[node] = c;
112
+ if (--room[c] === 0) {
113
+ open[j] = open[open.length - 1];
114
+ open.pop();
115
+ }
116
+ }
117
+ return community;
118
+ }
119
+
120
+ /**
121
+ * The LFR benchmark (A. Lancichinetti, S. Fortunato and F. Radicchi, "Benchmark graphs for testing
122
+ * community detection algorithms", Phys. Rev. E 78, 046110, 2008,
123
+ * doi:10.1103/PhysRevE.78.046110), built with configuration models:
124
+ *
125
+ * 1. Degrees: node i's degree is the i-th power-law draw on [minDegree, maxDegree] from stream
126
+ * (seed, "lfr-degrees", 0); an odd sum is fixed on the last node as in powerLawDegreeSequence.
127
+ * 2. Community sizes: power law on [minCommunity, maxCommunity] summing to exactly n (stream
128
+ * "lfr-sizes"); community ids are the draw order.
129
+ * 3. Internal degree round((1 - mu) d); assignment of nodes to communities larger than their
130
+ * internal degree (stream "lfr-assign"); a RangeError when none exists.
131
+ * 4. Inside each community c, ascending: when its internal degrees sum to an odd number the member
132
+ * with the largest (lowest index on ties) moves one stub to the outside; then a configuration
133
+ * model on the members' ascending stub list shuffled with stream (seed, "lfr-internal", c).
134
+ * 5. Outside: a configuration model on the remaining degrees d - internal, stream
135
+ * (seed, "lfr-external", 0).
136
+ *
137
+ * Self-loops and repeated pairs are erased, and so are external pairs that land inside one
138
+ * community, so degrees and the mixing come out approximate: the mean degree drops by up to about
139
+ * 10% (repeated pairs inside small communities), and the measured mixing lands within about 0.02 of
140
+ * mu for thousands of nodes. No edge switching repairs this. Edges: every community's internal
141
+ * edges (communities ascending, pair order), then the external edges. Node column `community` (u32).
142
+ * O(n log n + m); n at most 1,000,000.
143
+ * @param options - n, degree and community power laws, mixing and seed
144
+ * @returns the undirected graph
145
+ */
146
+ export function lfrGraph(options: LfrOptions): SampleGraph {
147
+ const { n, minDegree, maxDegree, minCommunity, maxCommunity, mixing } = options;
148
+ const seed = resolveSeed(options.seed);
149
+ checkInt("n", n, 1, MAX_LFR_NODES);
150
+ checkInt("maxDegree", maxDegree, 1, n - 1);
151
+ checkProbability("mixing", mixing);
152
+ checkInt("maxCommunity", maxCommunity, 1, n);
153
+ const degreeOf = powerLawSampler(
154
+ ["degreeExponent", "minDegree", "maxDegree"],
155
+ options.degreeExponent,
156
+ minDegree,
157
+ maxDegree,
158
+ );
159
+ const sizeOf = powerLawSampler(
160
+ ["communityExponent", "minCommunity", "maxCommunity"],
161
+ options.communityExponent,
162
+ minCommunity,
163
+ maxCommunity,
164
+ );
165
+
166
+ const degree = new Uint32Array(n);
167
+ const degreeStream = new RandomStream(seed, "lfr-degrees", 0);
168
+ for (let i = 0; i < n; i++) {
169
+ degree[i] = degreeOf(degreeStream);
170
+ }
171
+ makeSumEven(degree, minDegree, maxDegree);
172
+ const sizes = communitySizes(n, minCommunity, maxCommunity, sizeOf, seed);
173
+ const internal = Uint32Array.from(degree, (d) => Math.round((1 - mixing) * d));
174
+ const community = assignCommunities(internal, sizes, seed);
175
+
176
+ // members of every community, ascending, by a counting sort
177
+ const start = new Uint32Array(sizes.length + 1);
178
+ for (let c = 0; c < sizes.length; c++) {
179
+ start[c + 1] = start[c] + sizes[c];
180
+ }
181
+ const fill = start.slice(0, sizes.length);
182
+ const members = new Uint32Array(n);
183
+ for (let i = 0; i < n; i++) {
184
+ members[fill[community[i]]++] = i;
185
+ }
186
+
187
+ let total = 0;
188
+ for (const d of degree) {
189
+ total += d;
190
+ }
191
+ const out = new EdgeBuffer(total / 2);
192
+ const stream = new RandomStream(seed, "lfr-internal", 0);
193
+ for (let c = 0; c < sizes.length; c++) {
194
+ const group = members.subarray(start[c], start[c + 1]);
195
+ const k = Uint32Array.from(group, (i) => internal[i]);
196
+ let sum = 0;
197
+ let largest = 0;
198
+ for (let j = 0; j < k.length; j++) {
199
+ sum += k[j];
200
+ if (k[j] > k[largest]) {
201
+ largest = j;
202
+ }
203
+ }
204
+ if (sum % 2 === 1) {
205
+ k[largest]--;
206
+ internal[group[largest]]--;
207
+ sum--;
208
+ }
209
+ const stubs = stubList(k, sum);
210
+ for (let j = 0; j < stubs.length; j++) {
211
+ stubs[j] = group[stubs[j]];
212
+ }
213
+ stream.reset(c);
214
+ shuffle(stubs, stream);
215
+ pairStubs(n, stubs, false, false, out);
216
+ }
217
+
218
+ const external = Uint32Array.from(degree, (d, i) => d - internal[i]);
219
+ let externalTotal = 0;
220
+ for (const d of external) {
221
+ externalTotal += d;
222
+ }
223
+ const stubs = stubList(external, externalTotal);
224
+ shuffle(stubs, new RandomStream(seed, "lfr-external", 0));
225
+ pairStubs(n, stubs, false, false, out, community);
226
+ return applyWeights(toGraph(n, out, false, { community }), options);
227
+ }
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Named small graphs with well-known invariants: the teaching graphs and the platonic solids.
3
+ * The edge lists (node order and edge order) are those of networkx 3.1's `small.py`
4
+ * (A. Hagberg, D. Schult, P. Swart, "Exploring network structure, dynamics, and function using
5
+ * NetworkX", SciPy 2008; BSD-3-Clause), which in turn follow the literature (Krackhardt 1990,
6
+ * Frucht 1939, Tutte 1946, Hoffman and Singleton 1960, Sedgewick 1990). They are mathematical facts;
7
+ * the ordering is frozen like any other generator's. The Petersen graph is `petersenGraph()`.
8
+ */
9
+
10
+ import { type SampleGraph } from "../types.js";
11
+ import { applyWeights, type WeightOptions } from "./weights.js";
12
+
13
+ /** The name of every graph {@link namedGraph} knows. */
14
+ export const NAMED_GRAPH_NAMES = [
15
+ "bull",
16
+ "chvatal",
17
+ "cubical",
18
+ "desargues",
19
+ "diamond",
20
+ "dodecahedral",
21
+ "frucht",
22
+ "heawood",
23
+ "hoffman-singleton",
24
+ "house",
25
+ "house-x",
26
+ "icosahedral",
27
+ "krackhardt-kite",
28
+ "moebius-kantor",
29
+ "octahedral",
30
+ "pappus",
31
+ "sedgewick-maze",
32
+ "tetrahedral",
33
+ "truncated-cube",
34
+ "truncated-tetrahedron",
35
+ "tutte",
36
+ ] as const;
37
+
38
+ /** A name {@link namedGraph} accepts. */
39
+ export type NamedGraphName = (typeof NAMED_GRAPH_NAMES)[number];
40
+
41
+ /** Node count and flat edge list [u0, v0, u1, v1, ...] of every named graph. */
42
+ const GRAPHS: Readonly<Record<NamedGraphName, readonly [number, readonly number[]]>> = {
43
+ // a triangle with two pendant horns; 5 nodes, 5 edges
44
+ bull: [5, [0, 1, 0, 2, 1, 2, 1, 3, 2, 4]],
45
+ // the smallest triangle-free 4-regular 4-chromatic graph; 12 nodes, 24 edges
46
+ chvatal: [
47
+ 12,
48
+ [
49
+ 0, 1, 0, 4, 0, 6, 0, 9, 1, 2, 1, 5, 1, 7, 2, 3, 2, 6, 2, 8, 3, 4, 3, 7, 3, 9, 4, 5, 4, 8, 5, 10, 5, 11, 6,
50
+ 10, 6, 11, 7, 8, 7, 11, 8, 10, 9, 10, 9, 11,
51
+ ],
52
+ ],
53
+ // the cube's skeleton (Q_3); 8 nodes, 12 edges, planar
54
+ cubical: [8, [0, 1, 0, 3, 0, 4, 1, 2, 1, 7, 2, 3, 2, 6, 3, 5, 4, 5, 4, 7, 5, 6, 6, 7]],
55
+ // the Desargues graph, 3-regular, distance-transitive; 20 nodes, 30 edges
56
+ desargues: [
57
+ 20,
58
+ [
59
+ 0, 1, 0, 19, 0, 5, 1, 2, 1, 16, 2, 3, 2, 11, 3, 4, 3, 14, 4, 5, 4, 9, 5, 6, 6, 7, 6, 15, 7, 8, 7, 18, 8, 9,
60
+ 8, 13, 9, 10, 10, 11, 10, 19, 11, 12, 12, 13, 12, 17, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19,
61
+ ],
62
+ ],
63
+ // K_4 minus one edge; 4 nodes, 5 edges
64
+ diamond: [4, [0, 1, 0, 2, 1, 2, 1, 3, 2, 3]],
65
+ // the dodecahedron's skeleton; 20 nodes, 30 edges, planar, 3-regular
66
+ dodecahedral: [
67
+ 20,
68
+ [
69
+ 0, 1, 0, 19, 0, 10, 1, 2, 1, 8, 2, 3, 2, 6, 3, 4, 3, 19, 4, 5, 4, 17, 5, 6, 5, 15, 6, 7, 7, 8, 7, 14, 8, 9,
70
+ 9, 10, 9, 13, 10, 11, 11, 12, 11, 18, 12, 13, 12, 16, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19,
71
+ ],
72
+ ],
73
+ // 3-regular with no non-trivial automorphism; 12 nodes, 18 edges
74
+ frucht: [
75
+ 12,
76
+ [
77
+ 0, 1, 0, 6, 0, 7, 1, 2, 1, 7, 2, 3, 2, 8, 3, 4, 3, 9, 4, 5, 4, 9, 5, 6, 5, 10, 6, 10, 7, 11, 8, 11, 8, 9,
78
+ 10, 11,
79
+ ],
80
+ ],
81
+ // the (3,6)-cage, the Fano plane's incidence graph; 14 nodes, 21 edges
82
+ heawood: [
83
+ 14,
84
+ [
85
+ 0, 1, 0, 13, 0, 5, 1, 2, 1, 10, 2, 3, 2, 7, 3, 4, 3, 12, 4, 5, 4, 9, 5, 6, 6, 7, 6, 11, 7, 8, 8, 9, 8, 13,
86
+ 9, 10, 10, 11, 11, 12, 12, 13,
87
+ ],
88
+ ],
89
+ // the (7,5)-cage, a Moore graph; 50 nodes, 175 edges
90
+ "hoffman-singleton": [
91
+ 50,
92
+ [
93
+ 0, 1, 0, 2, 0, 3, 0, 6, 0, 7, 0, 8, 0, 9, 1, 17, 1, 12, 1, 26, 1, 27, 1, 28, 1, 29, 2, 10, 2, 11, 2, 13, 2,
94
+ 14, 2, 15, 2, 16, 3, 4, 3, 5, 3, 30, 3, 35, 3, 40, 3, 45, 4, 11, 4, 17, 4, 34, 4, 39, 4, 44, 4, 49, 5, 12,
95
+ 5, 10, 5, 33, 5, 38, 5, 43, 5, 48, 6, 22, 6, 18, 6, 31, 6, 39, 6, 43, 6, 47, 7, 34, 7, 23, 7, 19, 7, 37, 7,
96
+ 41, 7, 48, 8, 33, 8, 36, 8, 24, 8, 20, 8, 42, 8, 49, 9, 32, 9, 38, 9, 44, 9, 25, 9, 21, 9, 46, 10, 17, 10,
97
+ 18, 10, 19, 10, 20, 10, 21, 11, 12, 11, 32, 11, 37, 11, 42, 11, 47, 12, 31, 12, 36, 12, 41, 12, 46, 13, 30,
98
+ 13, 26, 13, 22, 13, 36, 13, 44, 13, 48, 14, 31, 14, 27, 14, 23, 14, 38, 14, 40, 14, 49, 15, 34, 15, 35, 15,
99
+ 28, 15, 24, 15, 43, 15, 46, 16, 33, 16, 39, 16, 41, 16, 45, 16, 29, 16, 25, 17, 22, 17, 23, 17, 24, 17, 25,
100
+ 18, 32, 18, 26, 18, 35, 18, 41, 18, 49, 19, 30, 19, 27, 19, 39, 19, 42, 19, 46, 20, 31, 20, 37, 20, 28, 20,
101
+ 44, 20, 45, 21, 34, 21, 36, 21, 40, 21, 47, 21, 29, 22, 33, 22, 37, 22, 40, 22, 46, 23, 32, 23, 36, 23, 43,
102
+ 23, 45, 24, 30, 24, 38, 24, 41, 24, 47, 25, 31, 25, 35, 25, 42, 25, 48, 26, 34, 26, 38, 26, 42, 26, 45, 27,
103
+ 33, 27, 35, 27, 44, 27, 47, 28, 32, 28, 39, 28, 40, 28, 48, 29, 30, 29, 37, 29, 43, 29, 49, 30, 31, 30, 32,
104
+ 31, 34, 32, 33, 33, 34, 35, 36, 35, 37, 36, 39, 37, 38, 38, 39, 40, 41, 40, 42, 41, 44, 42, 43, 43, 44, 45,
105
+ 46, 45, 47, 46, 49, 47, 48, 48, 49,
106
+ ],
107
+ ],
108
+ // a square with a triangular roof; 5 nodes, 6 edges
109
+ house: [5, [0, 1, 0, 2, 1, 3, 2, 3, 2, 4, 3, 4]],
110
+ // the house with both diagonals of the square; 5 nodes, 8 edges
111
+ "house-x": [5, [0, 1, 0, 2, 0, 3, 1, 3, 1, 2, 2, 3, 2, 4, 3, 4]],
112
+ // the icosahedron's skeleton; 12 nodes, 30 edges, planar, 5-regular
113
+ icosahedral: [
114
+ 12,
115
+ [
116
+ 0, 1, 0, 5, 0, 7, 0, 8, 0, 11, 1, 2, 1, 5, 1, 6, 1, 8, 2, 3, 2, 6, 2, 8, 2, 9, 3, 4, 3, 6, 3, 9, 3, 10, 4,
117
+ 5, 4, 6, 4, 10, 4, 11, 5, 6, 5, 11, 7, 8, 7, 9, 7, 10, 7, 11, 8, 9, 9, 10, 10, 11,
118
+ ],
119
+ ],
120
+ // Krackhardt's kite: degree, betweenness and closeness each crown a different node; 10 nodes, 18 edges
121
+ "krackhardt-kite": [
122
+ 10,
123
+ [0, 1, 0, 2, 0, 3, 0, 5, 1, 3, 1, 4, 1, 6, 2, 3, 2, 5, 3, 4, 3, 5, 3, 6, 4, 6, 5, 6, 5, 7, 6, 7, 7, 8, 8, 9],
124
+ ],
125
+ // the Moebius-Kantor graph, the generalized Petersen graph GP(8, 3); 16 nodes, 24 edges
126
+ "moebius-kantor": [
127
+ 16,
128
+ [
129
+ 0, 1, 0, 15, 0, 5, 1, 2, 1, 12, 2, 3, 2, 7, 3, 4, 3, 14, 4, 5, 4, 9, 5, 6, 6, 7, 6, 11, 7, 8, 8, 9, 8, 13,
130
+ 9, 10, 10, 11, 10, 15, 11, 12, 12, 13, 13, 14, 14, 15,
131
+ ],
132
+ ],
133
+ // the octahedron's skeleton, K_{2,2,2}; 6 nodes, 12 edges
134
+ octahedral: [6, [0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 1, 3, 1, 5, 2, 4, 2, 5, 3, 4, 3, 5, 4, 5]],
135
+ // the Pappus graph, 3-regular, bipartite, distance-regular; 18 nodes, 27 edges
136
+ pappus: [
137
+ 18,
138
+ [
139
+ 0, 1, 0, 17, 0, 5, 1, 2, 1, 8, 2, 3, 2, 13, 3, 4, 3, 10, 4, 5, 4, 15, 5, 6, 6, 7, 6, 11, 7, 8, 7, 14, 8, 9,
140
+ 9, 10, 9, 16, 10, 11, 11, 12, 12, 13, 12, 17, 13, 14, 14, 15, 15, 16, 16, 17,
141
+ ],
142
+ ],
143
+ // the small maze of Sedgewick's Algorithms in C (DFS teaching); 8 nodes, 10 edges
144
+ "sedgewick-maze": [8, [0, 2, 0, 7, 0, 5, 1, 7, 2, 6, 3, 4, 3, 5, 4, 5, 4, 7, 4, 6]],
145
+ // the tetrahedron's skeleton, K_4; 4 nodes, 6 edges
146
+ tetrahedral: [4, [0, 1, 0, 2, 0, 3, 1, 2, 1, 3, 2, 3]],
147
+ // the truncated cube's skeleton; 24 nodes, 36 edges, planar
148
+ "truncated-cube": [
149
+ 24,
150
+ [
151
+ 0, 1, 0, 2, 0, 4, 1, 11, 1, 14, 2, 3, 2, 4, 3, 6, 3, 8, 4, 5, 5, 16, 5, 18, 6, 7, 6, 8, 7, 10, 7, 12, 8, 9,
152
+ 9, 17, 9, 20, 10, 11, 10, 12, 11, 14, 12, 13, 13, 21, 13, 22, 14, 15, 15, 19, 15, 23, 16, 17, 16, 18, 17,
153
+ 20, 18, 19, 19, 23, 20, 21, 21, 22, 22, 23,
154
+ ],
155
+ ],
156
+ // the truncated tetrahedron's skeleton; 12 nodes, 18 edges, planar
157
+ "truncated-tetrahedron": [
158
+ 12,
159
+ [
160
+ 0, 1, 0, 2, 0, 9, 1, 2, 1, 6, 2, 3, 3, 4, 3, 11, 4, 5, 4, 11, 5, 6, 5, 7, 6, 7, 7, 8, 8, 9, 8, 10, 9, 10,
161
+ 10, 11,
162
+ ],
163
+ ],
164
+ // Tutte's graph: 3-regular, 3-connected, planar and not Hamiltonian; 46 nodes, 69 edges
165
+ tutte: [
166
+ 46,
167
+ [
168
+ 0, 1, 0, 2, 0, 3, 1, 4, 1, 26, 2, 10, 2, 11, 3, 18, 3, 19, 4, 5, 4, 33, 5, 6, 5, 29, 6, 7, 6, 27, 7, 8, 7,
169
+ 14, 8, 9, 8, 38, 9, 10, 9, 37, 10, 39, 11, 12, 11, 39, 12, 13, 12, 35, 13, 14, 13, 15, 14, 34, 15, 16, 15,
170
+ 22, 16, 17, 16, 44, 17, 18, 17, 43, 18, 45, 19, 20, 19, 45, 20, 21, 20, 41, 21, 22, 21, 23, 22, 40, 23, 24,
171
+ 23, 27, 24, 25, 24, 32, 25, 26, 25, 31, 26, 33, 27, 28, 28, 29, 28, 32, 29, 30, 30, 31, 30, 33, 31, 32, 34,
172
+ 35, 34, 38, 35, 36, 36, 37, 36, 39, 37, 38, 40, 41, 40, 44, 41, 42, 42, 43, 42, 45, 43, 44,
173
+ ],
174
+ ],
175
+ };
176
+
177
+ /**
178
+ * A named small graph (see {@link NAMED_GRAPH_NAMES}): an undirected simple graph with networkx's
179
+ * node and edge order.
180
+ * @param name - the graph's name
181
+ * @param options - the common weight options
182
+ * @returns the graph
183
+ */
184
+ export function namedGraph(name: NamedGraphName, options: WeightOptions = {}): SampleGraph {
185
+ const entry = Object.prototype.hasOwnProperty.call(GRAPHS, name) ? GRAPHS[name] : undefined;
186
+ if (entry === undefined) {
187
+ throw new RangeError(`unknown named graph "${name}"; see NAMED_GRAPH_NAMES`);
188
+ }
189
+ const [nodeCount, flat] = entry;
190
+ const m = flat.length / 2;
191
+ const src = new Uint32Array(m);
192
+ const dst = new Uint32Array(m);
193
+ for (let e = 0; e < m; e++) {
194
+ src[e] = flat[2 * e];
195
+ dst[e] = flat[2 * e + 1];
196
+ }
197
+ return applyWeights({ directed: false, nodeCount, src, dst }, options);
198
+ }
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Growth models: Barabasi-Albert preferential attachment with the Holme-Kim triad-formation step,
3
+ * and the Watts-Strogatz small world.
4
+ */
5
+
6
+ import { RandomStream, resolveSeed } from "../random/stream.js";
7
+ import { type SampleGraph } from "../types.js";
8
+ import { checkEdgeCount, checkInt, checkProbability, EdgeBuffer, toGraph } from "./util.js";
9
+ import { applyWeights, type WeightOptions } from "./weights.js";
10
+
11
+ /** Options of {@link barabasiAlbertGraph}. */
12
+ export interface BarabasiAlbertOptions extends WeightOptions {
13
+ /** The node count, > m. */
14
+ n: number;
15
+ /** The number of edges each new node brings, >= 1. */
16
+ m: number;
17
+ /**
18
+ * Holme-Kim: after each preferential edge, the probability that the next of the node's m edges
19
+ * closes a triangle with a neighbour of that edge's target instead. 0 (the default) is plain
20
+ * Barabasi-Albert.
21
+ */
22
+ triadProbability?: number | undefined;
23
+ /** The seed, an integer in [0, 2^53); default 0. */
24
+ seed?: number | undefined;
25
+ }
26
+
27
+ /**
28
+ * Barabasi-Albert preferential attachment (A.-L. Barabasi and R. Albert, "Emergence of scaling in
29
+ * random networks", Science 286, 509-512, 1999), optionally with triad formation (P. Holme and
30
+ * B. J. Kim, "Growing scale-free networks with tunable clustering", Phys. Rev. E 65, 026107, 2002),
31
+ * in O(n m) with the repeated-endpoint list of Batagelj and Brandes (2005).
32
+ *
33
+ * The algorithm is networkx's `powerlaw_cluster_graph`, which is `barabasi_albert_graph` when the
34
+ * triad probability is 0: start from m isolated nodes 0 .. m - 1 whose repeated list holds each
35
+ * once; each new node s = m .. n - 1 draws m distinct targets uniformly from the repeated list
36
+ * (in draw order), then adds m edges (s, t): the first to the first target; each further one, with
37
+ * probability `triadProbability`, to a uniformly chosen neighbour of the previous target that s is
38
+ * not yet joined to, otherwise to the next unused target. Every endpoint is appended to the
39
+ * repeated list, s itself m times. All draws come from the single stream (seed,
40
+ * "barabasi-albert", 0): the process is sequential. Edges are listed by new node, in the order
41
+ * added. (n - m) m edges, no self-loops, no repeats.
42
+ * @param options - n, m, triadProbability and seed
43
+ * @returns the undirected graph
44
+ */
45
+ export function barabasiAlbertGraph(options: BarabasiAlbertOptions): SampleGraph {
46
+ const { n, m } = options;
47
+ const triad = options.triadProbability ?? 0;
48
+ checkInt("m", m, 1);
49
+ checkInt("n", n, m + 1);
50
+ checkProbability("triadProbability", triad);
51
+ const seed = resolveSeed(options.seed);
52
+ const edgeCount = (n - m) * m;
53
+ checkEdgeCount(edgeCount);
54
+ const stream = new RandomStream(seed, "barabasi-albert", 0);
55
+ const out = new EdgeBuffer(edgeCount);
56
+ const repeated = new Uint32Array(m + 2 * edgeCount);
57
+ let length = 0;
58
+ for (let i = 0; i < m; i++) {
59
+ repeated[length++] = i;
60
+ }
61
+ // neighbour lists, only for the triad step
62
+ // ponytail: number[][] per node; a CSR-like growable adjacency if HK at 1M+ nodes matters
63
+ const adjacency: number[][] | null = triad > 0 ? Array.from({ length: n }, () => []) : null;
64
+ const targets = new Array<number>(m);
65
+ const link = (s: number, t: number): void => {
66
+ out.push(s, t);
67
+ repeated[length++] = t;
68
+ if (adjacency !== null) {
69
+ adjacency[s].push(t);
70
+ adjacency[t].push(s);
71
+ }
72
+ };
73
+ for (let s = m; s < n; s++) {
74
+ // m distinct targets from the repeated list, in draw order
75
+ let found = 0;
76
+ while (found < m) {
77
+ const t = repeated[stream.nextBelow(length)];
78
+ let fresh = true;
79
+ for (let i = 0; i < found; i++) {
80
+ fresh &&= targets[i] !== t;
81
+ }
82
+ if (fresh) {
83
+ targets[found++] = t;
84
+ }
85
+ }
86
+ let next = 0;
87
+ let target = targets[next++];
88
+ link(s, target);
89
+ for (let count = 1; count < m; count++) {
90
+ if (adjacency !== null && stream.nextFloat() < triad) {
91
+ const mine = adjacency[s];
92
+ const candidates = adjacency[target].filter((x) => x !== s && !mine.includes(x));
93
+ if (candidates.length > 0) {
94
+ link(s, candidates[stream.nextBelow(candidates.length)]);
95
+ continue;
96
+ }
97
+ }
98
+ // the next unused target (a triad step may already have joined s to it)
99
+ do {
100
+ target = targets[next++];
101
+ } while (adjacency !== null && adjacency[s].includes(target) && next < m);
102
+ if (adjacency !== null && adjacency[s].includes(target)) {
103
+ // every planned target is taken: fall back to a fresh preferential draw
104
+ do {
105
+ target = repeated[stream.nextBelow(length)];
106
+ } while (target === s || adjacency[s].includes(target));
107
+ }
108
+ link(s, target);
109
+ }
110
+ for (let i = 0; i < m; i++) {
111
+ repeated[length++] = s;
112
+ }
113
+ }
114
+ return applyWeights(toGraph(n, out, false), options);
115
+ }
116
+
117
+ /** Options of {@link wattsStrogatzGraph}. */
118
+ export interface WattsStrogatzOptions extends WeightOptions {
119
+ /** The node count, > k. */
120
+ n: number;
121
+ /** Each node's ring neighbours before rewiring, even, >= 2. */
122
+ k: number;
123
+ /** The rewiring probability of each edge, in [0, 1]. */
124
+ beta: number;
125
+ /** The seed, an integer in [0, 2^53); default 0. */
126
+ seed?: number | undefined;
127
+ }
128
+
129
+ /**
130
+ * The Watts-Strogatz small world (D. J. Watts and S. H. Strogatz, "Collective dynamics of
131
+ * 'small-world' networks", Nature 393, 440-442, 1998), as networkx's `watts_strogatz_graph`
132
+ * builds it, in O(n k).
133
+ *
134
+ * Start from the ring lattice: edge slot u k/2 + (j - 1) holds (u, (u + j) mod n) for j = 1 .. k/2.
135
+ * Then for j = 1 .. k/2 and u = 0 .. n - 1 in that order: draw a float; if it is below beta and u is
136
+ * not already joined to every other node, redraw w = nextBelow(n) until w is neither u nor a
137
+ * neighbour of u, and rewire the slot to (u, w). All draws come from the single stream (seed,
138
+ * "watts-strogatz", 0). Edges are listed in slot order.
139
+ * @param options - n, k, beta and seed
140
+ * @returns the undirected graph
141
+ */
142
+ export function wattsStrogatzGraph(options: WattsStrogatzOptions): SampleGraph {
143
+ const { n, k, beta } = options;
144
+ checkInt("k", k, 2);
145
+ if (k % 2 !== 0) {
146
+ throw new RangeError(`k must be even, got ${k}`);
147
+ }
148
+ checkInt("n", n, k + 1);
149
+ checkProbability("beta", beta);
150
+ const seed = resolveSeed(options.seed);
151
+ const half = k / 2;
152
+ const m = n * half;
153
+ checkEdgeCount(m);
154
+ const src = new Uint32Array(m);
155
+ const dst = new Uint32Array(m);
156
+ const degree = new Uint32Array(n).fill(k);
157
+ // ponytail: a Set of u * n + v keys, fine to a few million edges; a hashed typed table beyond
158
+ const edges = new Set<number>();
159
+ const key = (a: number, b: number): number => (a < b ? a * n + b : b * n + a);
160
+ for (let u = 0; u < n; u++) {
161
+ for (let j = 1; j <= half; j++) {
162
+ const v = (u + j) % n;
163
+ src[u * half + j - 1] = u;
164
+ dst[u * half + j - 1] = v;
165
+ edges.add(key(u, v));
166
+ }
167
+ }
168
+ const stream = new RandomStream(seed, "watts-strogatz", 0);
169
+ for (let j = 1; j <= half; j++) {
170
+ for (let u = 0; u < n; u++) {
171
+ if (stream.nextFloat() >= beta || degree[u] >= n - 1) {
172
+ continue;
173
+ }
174
+ let w = stream.nextBelow(n);
175
+ while (w === u || edges.has(key(u, w))) {
176
+ w = stream.nextBelow(n);
177
+ }
178
+ const slot = u * half + j - 1;
179
+ const v = dst[slot];
180
+ edges.delete(key(u, v));
181
+ edges.add(key(u, w));
182
+ degree[v]--;
183
+ degree[w]++;
184
+ dst[slot] = w;
185
+ }
186
+ }
187
+ return applyWeights({ directed: false, nodeCount: n, src, dst }, options);
188
+ }