Comparison of non-trivial generation operations. See benchmarks below.
| Operation | jngen | tgen | Notes | Benchmark |
|---|---|---|---|---|
| Connected random graph | Same Prüfer tree + rejection edge add. Neither uniform over all connected labeled graphs. | 0.23x n=106, m=106 | ||
| Random graph with fixed n, m | Rejection sampling with constraint machinery. | (m=n) 0.47x n=106, m=106 (m=2n) 0.47x n=106, m=2×106 | ||
| Skewed / stretched connected graph | Same high-level algorithm: skewed spanning tree, then ancestor-biased extra edges. Extra edges reject duplicates; jngen resets an attempt counter on success and throws after MAX_ATTEMPTS=1000 consecutive failures, while tgen uses its unique generation framework. For large spread, tgen uses binary lifting; jngen uses trivial parent-by-parent lifting. | (m=n) 0.33x n=106, m=106, elongation=100, spread=2 (distinct worst) n=106, m=2n-3, elongation=100, spread=2 | ||
| Bipartite graph (random / complete) | tgen: Distinct edge-index sampling. jngen: Rejection sampling. Both support optional connected generation. jngen also supports allowMulti; tgen stores simple graphs only. | 0.29x n1=103, n2=103, m=5×105 | ||
| Directed random graph | tgen: Rejection with constraint machinery. jngen: Rejection sampling. | (directed) 0.43x n=106, m=106 (DAG) 0.57x n=106, m=106 | ||
| Directed acyclic random graph (DAG) | tgen: Randomized Kahn topological order, then rejection sampling. jngen: Rejection sampling + acyclic shuffle-orient. | 0.57x n=106, m=106 |
* Uniformity or complexity is undocumented and is inferred by code inspection.
| Operation | jngen | tgen | Notes | Benchmark |
|---|---|---|---|---|
| Random labeled tree | Prüfer sequence. | 0.84x n=106 | ||
| Skewed tree (wnext / Prim-like) | Uses parent(i) = wnext(i, elongation). | 0.68x n=106, elongation=100 | ||
| Random tree (Kruskal-like) | Kruskal-like edge add until connected. | 0.87x n=106 |
* Uniformity or complexity is undocumented and is inferred by code inspection.
| Operation | jngen | tgen | Notes | Benchmark |
|---|---|---|---|---|
| Distinct values in range | tgen: Fisher–Yates + forbidden-value map. jngen: Hash-set rejection. | 0.50x n=5×106, value_left=1, value_right=10×106 | ||
| Random integer list (duplicates allowed) | Independent uniform draws. | 0.67x n=5×106, value_left=1, value_right=10×106 | ||
| Uniform random permutation | — | 1.07x n=5×106 | ||
| Declarative constraints (palindrome, cycles) | No | Constraint-based uniform sampling. | — |
* Uniformity or complexity is undocumented and is inferred by code inspection.
| Operation | jngen | tgen | Notes | Benchmark |
|---|---|---|---|---|
| Partition into k parts (fast) | Same high-level approach: random delimiters, sort, gap recovery. jngen also sorts parts in non-increasing order and shuffles; tgen fast omits reordering. Not uniformly random; Optimized for speed. | 0.51x n=1018, k=3×106, part_left=0 | ||
| Uniform ordered partition into k parts (composition) | No | Stars-and-bars or DP in log space. Uniform over ordered compositions. | tgen: 822 ms n=5×107, k=10, part_left=0 | |
| Uniform ordered partition, variable number of parts | No | DP in log space. | tgen: 1054 ms n=4.8×106 | |
| Random integer with congruence constraints | No | — | — | |
| Partition array into k groups | Yes DocsUniform if unbounded max_sizeNon‑uniform otherwiseO(n) time if unbounded max_sizeO(n + k log k) time otherwise | — | 0.60x n=106, k=106 |
* Uniformity or complexity is undocumented and is inferred by code inspection.
| Operation | jngen | tgen | Notes | Benchmark |
|---|---|---|---|---|
| Random convex polygon | tgen: Valtr construction filling bounding box. jngen: Hull of 10n ellipse points, subsample n. Different shape distributions. Benchmark uses the same n and max for both (wide max so jngen hull subsampling succeeds at n=1e6). | 0.34x n=106, min=0, max=3×1010 | ||
| Points in general position (no three collinear) | tgen: Algebraic construction over F_p. jngen: Rejection until no collinearity. | (n=1800) <0.01x n=1800, min=0, max=3×106 (n=1e6) n=106, min=0, max=3×106 | ||
| Random simple polygon | No | Points + polygonization. | tgen: 1247 ms n=106, min=0, max=3×106 | |
| Simple polygon through given points | No | Randomized divide-and-conquer Hamiltonian path. | tgen: 1094 ms n=106 |
* Uniformity or complexity is undocumented and is inferred by code inspection.
| Operation | jngen | tgen | Notes | Benchmark |
|---|---|---|---|---|
| Regex / pattern strings | Same testlib-style regex syntax. tgen samples uniformly among matches (documented); jngen explicitly does not: e.g. Rnd.next("[1-9][0-9]{1,2}") does not yield uniform digit strings. Benchmark measures generation throughput at fixed pattern length, not distributional fairness. | 1.28x pattern=(([1-9][0-9]{3}|[A-F]{4})|(ab|cd){2}){r}, len=107 |
* Uniformity or complexity is undocumented and is inferred by code inspection.
| Operation | jngen | tgen | Notes | Benchmark |
|---|---|---|---|---|
| Polynomial hash collision strings (signed mod) | Deterministic collision construction, not random sampling. Both generate colliding strings for rolling hash. | — | ||
| Polynomial hash collision (unsigned / power-of-two mod) | No | Thue–Morse construction. | — | |
| std::unordered_set collision inputs | Overlap in purpose; Different APIs and compiler support. jngen: GCC 4.x only; Tuned load factor/reserve. tgen: GCC multiplier-based collision keys. | — | ||
| std::set collision strings | No | Distinct strings with equal std::set ordering keys. | — | |
| Max-flow worst case (Dinitz / Edmonds-Karp) | No | Zadeh network. | — | |
| Mo's algorithm worst-case queries | No | — | — | |
| SPFA TLE graph | No | Graph with n vertices and edges; Forces Ω(n²) relaxations. | — | |
| Stale-heap Dijkstra bug graph | No | Forces Ω(n²) without stale-heap skip. | — | |
| Non-strict relaxation Dijkstra bug graph | No | Forces Ω(2^{n/2}) with non-strict relaxation. | — | |
| MT19937 XOR-hash collision mask | No | Bitmask for int or long long outputs. | — | |
| Segment-tree-beats worst case | No | — | — | |
| Rotating calipers bug polygon | No | Fixed 6-vertex convex polygon. | — |
* Uniformity or complexity is undocumented and is inferred by code inspection.
| Operation | jngen | tgen | Notes | Benchmark |
|---|---|---|---|---|
| Distinct generation | No | Composable constraint machinery. | — | |
| Testlib integration | No | jngen is built on testlib. tgen is a standalone header with register_gen and its own constraint API. | — | |
| Built-in SVG visualization | No | jngen Drawer for points, segments, circles, polygons; Outputs SVG. | — | |
| Accelerated build guide | No | Compile jngen.h once into a static lib; Link with JNGEN_DECLARE_ONLY for faster rebuilds. | — |
| Operation | jngen | tgen |
|---|---|---|
| Random convex polygon | n=80, min=0, max=1000n=15000, min=0, max=3×109 | n=80, min=0, max=1000n=15000, min=0, max=3×109 |
| Points in general position (no three collinear) | n=2000, min=0, max=3×106 | n=2000, min=0, max=3×106 |
| Random simple polygon | No | n=80, min=0, max=1000 |
| Simple polygon through given points | No | 10×10 input grid, min=0, max=1000 |
* Uniformity or complexity is undocumented and is inferred by code inspection.
dae9a10, jngen 8d1e33bBar length is relative to the slower library per operation (jngen vs tgen). Ratio is colored by the faster library.
| Operation | Parameters | Comparison | Ratio (tgen/jngen) |
|---|---|---|---|
graph::get_connected (m=n)Docs | n=106, m=106 | 0.23x | |
graph::get_connected (m=2n)Docs | n=106, m=2×106 | 0.33x | |
graph::gen (m=n)Docs | n=106, m=106 | 0.47x | |
graph::gen (m=2n)Docs | n=106, m=2×106 | 0.47x | |
graph::gen_skewed (m=n)Docs | n=106, m=106, elongation=100, spread=2 | 0.33x | |
graph::gen_skewed (m=2n)Docs | n=106, m=2×106, elongation=100, spread=6 | 0.34x | |
graph::gen_skewed (distinct worst)Docs | n=106, m=2n-3, elongation=100, spread=2 | — | |
tree::genDocs | n=106 | 0.84x | |
tree::gen_skewedDocs | n=106, elongation=100 | 0.68x | |
tree::gen_kruskalDocs | n=106 | 0.87x | |
list<int>::gen (all_different)Docs | n=5×106, value_left=1, value_right=10×106 | 0.50x | |
list<int>::genDocs | n=5×106, value_left=1, value_right=10×106 | 0.67x | |
geometry::random_convex_polygonDocs | n=106, min=0, max=3×1010 | 0.34x | |
geometry::random_points_general_position (n=1800)Docs | n=1800, min=0, max=3×106 | <0.01x | |
geometry::random_points_general_position (n=1e6)Docs | n=106, min=0, max=3×106 | — | |
permutation::genDocs | n=5×106 | 1.07x | |
graph::gen_bipartiteDocs | n1=103, n2=103, m=5×105 | 0.29x | |
graph::gen (directed)Docs | n=106, m=106 | 0.43x | |
graph::get_acyclic (DAG)Docs | n=106, m=106 | 0.57x | |
str::genDocs | pattern=(([1-9][0-9]{3}|[A-F]{4})|(ab|cd){2}){r}, len=107 | 1.28x | |
math::gen_partition_fixed_size_fastDocs | n=1018, k=3×106, part_left=0 | 0.51x | |
math::partition_elementsDocs | n=106, k=106 | 0.60x |
| Operation | Parameters | tgen |
|---|---|---|
geometry::random_simple_polygonDocs | n=106, min=0, max=3×106 | 1247 ms |
geometry::random_simple_polygon_through_pointsDocs | n=106 | 1094 ms |
math::gen_partitionDocs | n=4.8×106 | 1054 ms |
math::gen_partition_fixed_sizeDocs | n=5×107, k=10, part_left=0 | 822 ms |