Synthetic Datasets
FHOPS ships with a small library of synthetic scenarios that mirror the structure of our teaching
and benchmarking datasets. Each bundle is a self-contained directory under
examples/synthetic/ with a scenario.yaml and the CSV tables that back it. The bundles are
generated by fhops.scenario.synthetic.generate_random_dataset() so they follow the same data
contract validation as user-supplied scenarios.
Reference bundles
Three ready-to-use bundles are versioned with the project. The table below summarises their scale;
see examples/synthetic/metadata.yaml for the full metadata (random seeds, blackout windows, and
shift calendars).
Bundle |
Blocks |
Machines |
Landings |
Days |
Shifts/day |
Seed / Notes |
|---|---|---|---|---|---|---|
|
4 |
2 |
1 |
6 |
1 |
Seed |
|
8 |
4 |
2 |
12 |
1 |
Seed |
|
16 |
6 |
3 |
18 |
2 |
Seed |
The example README (examples/synthetic/README.md) gives a short overview and links back to the
metadata file if you need exact counts or blackout windows for reproducibility.
Block enrichment, crews, and blackouts
Each bundle ships with richer signals to support evaluation/benchmarking:
blocks.csvnow containsterrainandprescriptioncolumns sampled from tier-aware pools (e.g.,gentle/mixedfor the small instance,steep/snowfor the large one).machines.csvadds acrewcolumn; the generatedcrew_assignments.csvtable records the crew → machine mapping with capability notes so validators and scenario loaders can reconstruct assignments.Crew capabilities are sampled from the
capability_poolwhile respecting the tier-specific span (single-skill crews insmall, multi-skill teams inlarge).Blackout windows are produced with tier defaults: zero-probability for
smallbundles, short gaps formedium, and multi-day outages forlarge. Metadata captures the sampled windows so smoke tests can diff future changes.Weighted terrain/prescription distributions and blackout bias windows can be overridden via
SyntheticDatasetConfig(seeterrain_weights/prescription_weightsandblackout_biases) to concentrate sampling on seasonal or topographical hotspots. Harvest-system mixes are also recorded when bundled systems are supplied.
If you regenerate the library, the metadata YAML under each tier (and the aggregate metadata file in
examples/synthetic/) records the terrain/prescription mix, crew capabilities, blackout windows,
and the seed that produced the dataset.
CLI walkthrough
Use the bundles anywhere a normal scenario is accepted. Typical entry points:
Validate the data contract:
fhops validate examples/synthetic/medium/scenario.yaml
Run the simulated annealing baseline and capture the schedule:
fhops solve-heur examples/synthetic/medium/scenario.yaml --out /tmp/medium_sa.csv --seed 99
Generate shift/day summaries with KPI exports:
fhops eval-playback examples/synthetic/medium/scenario.yaml \\ --assignments /tmp/medium_sa.csv \\ --shift-out /tmp/medium_shift.csv \\ --day-out /tmp/medium_day.csv \\ --summary-md /tmp/medium_playback.md
Benchmark solver presets across the reference datasets:
fhops bench suite --scenario examples/synthetic/large/scenario.yaml \\ --operator-preset explore \\ --out-dir tmp/bench_synth_large
Generate a fresh bundle (preview or write to disk):
fhops synth generate tmp/synth_medium_custom --tier medium --seed 321 --blocks 10:14 --preview
Drop
--preview(and optionally add--overwrite) to write the generated CSV/YAML bundle. The command accepts YAML/TOML configs via--configwhen you need full control over theSyntheticDatasetConfigfields.Common flags you can mix in:
--machines 6:8/--landings 2/--days 10:14to resample sizes.--shifts-per-day 2to simulate multi-shift calendars.--machine-daily-hours 20when you want the generatedmachines.csvto reflect partial-day availability (default is 24, matching the data-contract baseline).
Note
When you write directly to
examples/synthetic/<tier>the CLI automatically refreshes the aggregateexamples/synthetic/metadata.yamlso documentation and automation stay in sync.Create several bundles via a batch plan:
fhops synth batch docs/examples/synthetic_batch_plan.yaml --overwrite
The plan file can be YAML/TOML/JSON and contains a list of entries, each mirroring the options accepted by
fhops synth generate(tier,seed,config, overrides, etc.). This is handy when preparing datasets for experiments or CI warmups. Seedocs/examples/synthetic_batch_plan.yaml(and the referencedsynthetic_batch_custom.yaml) for a ready-to-run example.
These commands reuse the same CLI surfaces already documented in Evaluation Workflows and CLI Reference, but the synthetic bundles keep the inputs lightweight enough for quick iteration and teaching exercises.
The loader automatically ingests crew_assignments.csv when present, so downstream analytics can
group KPIs by crew. Pair the bundle metadata with playback exports to slice utilisation or downtime
by terrain/prescription class.
Regenerating bundles
The generator can be scripted to refresh or extend the library. Seeds are recorded in
metadata.yaml so you can rebuild a bundle exactly:
from pathlib import Path
from fhops.scenario.synthetic import SyntheticDatasetConfig, generate_random_dataset
config = SyntheticDatasetConfig(
name="synthetic-medium",
tier="medium",
num_blocks=(8, 10),
num_days=12,
num_machines=4,
num_landings=2,
shifts_per_day=1,
shift_hours=(9.5, 10.5),
terrain_pool=["rolling", "mixed", "steep"],
crew_pool=["crew-alpha", "crew-beta", "crew-gamma"],
capability_pool=["harvester", "forwarder", "processor"],
crew_capability_span=(1, 2),
)
bundle = generate_random_dataset(config, seed=202)
bundle.write(Path("examples/synthetic/medium"))
You can customise the config ranges (blocks, production rates, blackout probabilities, and role
assignments) or pass a systems dictionary to incorporate predefined harvest system templates via
generate_random_dataset(..., systems=default_system_registry()).
For small teaching examples, the deterministic helper fhops.scenario.synthetic.generate_basic()
creates a scenario with a single landing and no randomisation; for system-aware datasets use
fhops.scenario.synthetic.generate_with_systems().
Where to go next
tests/test_synthetic_dataset.pyillustrates the expected invariants and is a good starting point if you extend the generator.The benchmarking how-to (Benchmarking Harness) explains how to wire new scenarios into the benchmarking harness once you are happy with the dataset characteristics.