{
"cells": [
{
"cell_type": "markdown",
"id": "3a9d633b",
"metadata": {},
"source": [
"# Operator/Benchmark Sweep\n",
"\n",
"Run the benchmark suite with multiple operator presets and compare objective/runtime metrics."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "fccaeabc",
"metadata": {
"execution": {
"iopub.execute_input": "2026-10-05T12:57:25.656827Z",
"iopub.status.busy": "2026-10-05T12:57:25.656665Z",
"iopub.status.idle": "2026-10-05T12:57:38.357540Z",
"shell.execute_reply": "2026-10-05T12:57:38.356692Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"
FHOPS Benchmark Summary \n",
"┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━┓\n",
"┃ scenario ┃ solver ┃ preset_label ┃ objective ┃ runtime_s ┃ assignments ┃\n",
"┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━┩\n",
"│ user-1 │ sa │ default │ -285097.033 │ 4.20 │ 272 │\n",
"│ user-1 │ sa │ explore │ -275097.033 │ 4.10 │ 272 │\n",
"│ user-1 │ sa │ stabilise │ -283097.033 │ 3.60 │ 272 │\n",
"└──────────┴────────┴──────────────┴─────────────┴───────────┴─────────────┘\n",
"\n"
],
"text/plain": [
"\u001b[3m FHOPS Benchmark Summary \u001b[0m\n",
"┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━┓\n",
"┃\u001b[1m \u001b[0m\u001b[1mscenario\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1msolver\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mpreset_label\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mobjective \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mruntime_s\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1massignments\u001b[0m\u001b[1m \u001b[0m┃\n",
"┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━┩\n",
"│ user-1 │ sa │ default │ -285097.033 │ 4.20 │ 272 │\n",
"│ user-1 │ sa │ explore │ -275097.033 │ 4.10 │ 272 │\n",
"│ user-1 │ sa │ stabilise │ -283097.033 │ 3.60 │ 272 │\n",
"└──────────┴────────┴──────────────┴─────────────┴───────────┴─────────────┘\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" scenario | \n",
" scenario_path | \n",
" solver | \n",
" objective | \n",
" runtime_s | \n",
" assignments | \n",
" kpi_total_production | \n",
" kpi_completed_blocks | \n",
" kpi_staged_production | \n",
" kpi_remaining_work_total | \n",
" ... | \n",
" machine_costs_summary | \n",
" scenario_key | \n",
" objective_vs_mip_gap | \n",
" objective_vs_mip_ratio | \n",
" solver_category | \n",
" best_heuristic_solver | \n",
" best_heuristic_objective | \n",
" best_heuristic_runtime_s | \n",
" objective_gap_vs_best_heuristic | \n",
" runtime_ratio_vs_best_heuristic | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" user-1 | \n",
" /home/runner/work/fhops/fhops/examples/synthet... | \n",
" sa | \n",
" -285097.033 | \n",
" 4.196794 | \n",
" 272 | \n",
" 0.0 | \n",
" 0.0 | \n",
" 97.033 | \n",
" 97.033 | \n",
" ... | \n",
" forwarder: own=32.64763186221744, op=79.202981... | \n",
" user-1 | \n",
" <NA> | \n",
" <NA> | \n",
" heuristic | \n",
" sa | \n",
" -275097.033 | \n",
" 4.104256 | \n",
" 10000.0 | \n",
" 1.022547 | \n",
"
\n",
" \n",
" | 1 | \n",
" user-1 | \n",
" /home/runner/work/fhops/fhops/examples/synthet... | \n",
" sa | \n",
" -275097.033 | \n",
" 4.104256 | \n",
" 272 | \n",
" 0.0 | \n",
" 0.0 | \n",
" 97.033 | \n",
" 97.033 | \n",
" ... | \n",
" forwarder: own=32.64763186221744, op=79.202981... | \n",
" user-1 | \n",
" <NA> | \n",
" <NA> | \n",
" heuristic | \n",
" sa | \n",
" -275097.033 | \n",
" 4.104256 | \n",
" 0.0 | \n",
" 1.000000 | \n",
"
\n",
" \n",
" | 2 | \n",
" user-1 | \n",
" /home/runner/work/fhops/fhops/examples/synthet... | \n",
" sa | \n",
" -283097.033 | \n",
" 3.603955 | \n",
" 272 | \n",
" 0.0 | \n",
" 0.0 | \n",
" 97.033 | \n",
" 97.033 | \n",
" ... | \n",
" forwarder: own=32.64763186221744, op=79.202981... | \n",
" user-1 | \n",
" <NA> | \n",
" <NA> | \n",
" heuristic | \n",
" sa | \n",
" -275097.033 | \n",
" 4.104256 | \n",
" 8000.0 | \n",
" 0.878102 | \n",
"
\n",
" \n",
"
\n",
"
3 rows × 43 columns
\n",
"
"
],
"text/plain": [
" scenario scenario_path solver \\\n",
"0 user-1 /home/runner/work/fhops/fhops/examples/synthet... sa \n",
"1 user-1 /home/runner/work/fhops/fhops/examples/synthet... sa \n",
"2 user-1 /home/runner/work/fhops/fhops/examples/synthet... sa \n",
"\n",
" objective runtime_s assignments kpi_total_production \\\n",
"0 -285097.033 4.196794 272 0.0 \n",
"1 -275097.033 4.104256 272 0.0 \n",
"2 -283097.033 3.603955 272 0.0 \n",
"\n",
" kpi_completed_blocks kpi_staged_production kpi_remaining_work_total ... \\\n",
"0 0.0 97.033 97.033 ... \n",
"1 0.0 97.033 97.033 ... \n",
"2 0.0 97.033 97.033 ... \n",
"\n",
" machine_costs_summary scenario_key \\\n",
"0 forwarder: own=32.64763186221744, op=79.202981... user-1 \n",
"1 forwarder: own=32.64763186221744, op=79.202981... user-1 \n",
"2 forwarder: own=32.64763186221744, op=79.202981... user-1 \n",
"\n",
" objective_vs_mip_gap objective_vs_mip_ratio solver_category \\\n",
"0 heuristic \n",
"1 heuristic \n",
"2 heuristic \n",
"\n",
" best_heuristic_solver best_heuristic_objective best_heuristic_runtime_s \\\n",
"0 sa -275097.033 4.104256 \n",
"1 sa -275097.033 4.104256 \n",
"2 sa -275097.033 4.104256 \n",
"\n",
" objective_gap_vs_best_heuristic runtime_ratio_vs_best_heuristic \n",
"0 10000.0 1.022547 \n",
"1 0.0 1.000000 \n",
"2 8000.0 0.878102 \n",
"\n",
"[3 rows x 43 columns]"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import sys\n",
"from pathlib import Path\n",
"\n",
"PROJECT_ROOT = Path.cwd().resolve()\n",
"while PROJECT_ROOT != PROJECT_ROOT.parent and not (PROJECT_ROOT / \"pyproject.toml\").exists():\n",
" PROJECT_ROOT = PROJECT_ROOT.parent\n",
"if not (PROJECT_ROOT / \"pyproject.toml\").exists():\n",
" raise RuntimeError(\n",
" \"Notebook must be executed within a FHOPS checkout (pyproject.toml not found).\"\n",
" )\n",
"if str(PROJECT_ROOT) not in sys.path:\n",
" sys.path.insert(0, str(PROJECT_ROOT))\n",
"\n",
"\n",
"from fhops.cli.benchmarks import run_benchmark_suite\n",
"\n",
"BENCH_DIR = PROJECT_ROOT / \"docs/examples/analytics/data/operator_sweep\"\n",
"summary = run_benchmark_suite(\n",
" [PROJECT_ROOT / \"examples/synthetic/medium/scenario.yaml\"],\n",
" BENCH_DIR,\n",
" time_limit=5,\n",
" sa_iters=150,\n",
" include_mip=False,\n",
" preset_comparisons=[\"explore\", \"stabilise\"],\n",
")\n",
"summary"
]
},
{
"cell_type": "markdown",
"id": "acc185b5",
"metadata": {},
"source": [
"## Objective Comparison"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "081fe895",
"metadata": {
"execution": {
"iopub.execute_input": "2026-10-05T12:57:38.358891Z",
"iopub.status.busy": "2026-10-05T12:57:38.358742Z",
"iopub.status.idle": "2026-10-05T12:57:38.365198Z",
"shell.execute_reply": "2026-10-05T12:57:38.364489Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" objective | \n",
"
\n",
" \n",
" | preset_label | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" | default | \n",
" -285097.033 | \n",
"
\n",
" \n",
" | explore | \n",
" -275097.033 | \n",
"
\n",
" \n",
" | stabilise | \n",
" -283097.033 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" objective\n",
"preset_label \n",
"default -285097.033\n",
"explore -275097.033\n",
"stabilise -283097.033"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"objective_pivot = summary.pivot_table(index=\"preset_label\", values=\"objective\")\n",
"objective_pivot"
]
},
{
"cell_type": "markdown",
"id": "de60cddd",
"metadata": {},
"source": [
"## Runtime Comparison"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "31b27eec",
"metadata": {
"execution": {
"iopub.execute_input": "2026-10-05T12:57:38.366439Z",
"iopub.status.busy": "2026-10-05T12:57:38.366319Z",
"iopub.status.idle": "2026-10-05T12:57:38.372666Z",
"shell.execute_reply": "2026-10-05T12:57:38.371890Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" runtime_s | \n",
"
\n",
" \n",
" | preset_label | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" | default | \n",
" 4.196794 | \n",
"
\n",
" \n",
" | explore | \n",
" 4.104256 | \n",
"
\n",
" \n",
" | stabilise | \n",
" 3.603955 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" runtime_s\n",
"preset_label \n",
"default 4.196794\n",
"explore 4.104256\n",
"stabilise 3.603955"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"runtime_pivot = summary.pivot_table(index=\"preset_label\", values=\"runtime_s\")\n",
"runtime_pivot"
]
}
],
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.16"
}
},
"nbformat": 4,
"nbformat_minor": 5
}