summary.json

← Back to submission · View raw on GitHub

{
  "benchmark_id": "001_synthetic_mine_throughput",
  "scenarios": {
    "baseline": {
      "scenario_id": "baseline",
      "replications": 30,
      "shift_length_hours": 8.0,
      "total_tonnes_mean": 12546.666667,
      "total_tonnes_ci95_low": 12491.42646,
      "total_tonnes_ci95_high": 12601.906874,
      "tonnes_per_hour_mean": 1568.333333,
      "tonnes_per_hour_ci95_low": 1561.428307,
      "tonnes_per_hour_ci95_high": 1575.238359,
      "average_cycle_time_min": 29.660399,
      "truck_utilisation_mean": 0.994422,
      "loader_utilisation": {
        "L_N": 0.601581,
        "L_S": 0.803143
      },
      "crusher_utilisation": 0.911607,
      "average_loader_queue_time_min": 2.50709,
      "average_crusher_queue_time_min": 3.279038,
      "top_bottlenecks": [
        {
          "resource_id": "D_CRUSH",
          "resource_kind": "crusher",
          "utilisation": 0.911607,
          "avg_queue_wait_min": 3.279038,
          "score": 2.989194
        },
        {
          "resource_id": "L_S",
          "resource_kind": "loader",
          "utilisation": 0.803143,
          "avg_queue_wait_min": 2.449391,
          "score": 1.96721
        },
        {
          "resource_id": "L_N",
          "resource_kind": "loader",
          "utilisation": 0.601581,
          "avg_queue_wait_min": 2.618506,
          "score": 1.575243
        },
        {
          "resource_id": "E03_UP",
          "resource_kind": "edge",
          "utilisation": 0.052746,
          "avg_queue_wait_min": 10.890609,
          "score": 0.574431
        },
        {
          "resource_id": "E05_TO_CRUSH",
          "resource_kind": "edge",
          "utilisation": 0.420842,
          "avg_queue_wait_min": 0.150605,
          "score": 0.063381
        }
      ]
    },
    "trucks_4": {
      "scenario_id": "trucks_4",
      "replications": 30,
      "shift_length_hours": 8.0,
      "total_tonnes_mean": 7650.0,
      "total_tonnes_ci95_low": 7611.083146,
      "total_tonnes_ci95_high": 7688.916854,
      "tonnes_per_hour_mean": 956.25,
      "tonnes_per_hour_ci95_low": 951.385393,
      "tonnes_per_hour_ci95_high": 961.114607,
      "average_cycle_time_min": 24.418577,
      "truck_utilisation_mean": 0.996168,
      "loader_utilisation": {
        "L_N": 0.322521,
        "L_S": 0.516733
      },
      "crusher_utilisation": 0.556981,
      "average_loader_queue_time_min": 0.690894,
      "average_crusher_queue_time_min": 0.69713,
      "top_bottlenecks": [
        {
          "resource_id": "D_CRUSH",
          "resource_kind": "crusher",
          "utilisation": 0.556981,
          "avg_queue_wait_min": 0.69713,
          "score": 0.388288
        },
        {
          "resource_id": "L_S",
          "resource_kind": "loader",
          "utilisation": 0.516733,
          "avg_queue_wait_min": 0.710502,
          "score": 0.36714
        },
        {
          "resource_id": "L_N",
          "resource_kind": "loader",
          "utilisation": 0.322521,
          "avg_queue_wait_min": 0.640979,
          "score": 0.206729
        },
        {
          "resource_id": "E03_UP",
          "resource_kind": "edge",
          "utilisation": 0.026139,
          "avg_queue_wait_min": 4.467327,
          "score": 0.116773
        },
        {
          "resource_id": "E05_TO_CRUSH",
          "resource_kind": "edge",
          "utilisation": 0.255324,
          "avg_queue_wait_min": 0.102811,
          "score": 0.02625
        }
      ]
    },
    "trucks_12": {
      "scenario_id": "trucks_12",
      "replications": 30,
      "shift_length_hours": 8.0,
      "total_tonnes_mean": 12906.666667,
      "total_tonnes_ci95_low": 12826.440013,
      "total_tonnes_ci95_high": 12986.89332,
      "tonnes_per_hour_mean": 1613.333333,
      "tonnes_per_hour_ci95_low": 1603.305002,
      "tonnes_per_hour_ci95_high": 1623.361665,
      "average_cycle_time_min": 42.683402,
      "truck_utilisation_mean": 0.98791,
      "loader_utilisation": {
        "L_N": 0.640663,
        "L_S": 0.844934
      },
      "crusher_utilisation": 0.937067,
      "average_loader_queue_time_min": 3.473894,
      "average_crusher_queue_time_min": 14.234655,
      "top_bottlenecks": [
        {
          "resource_id": "D_CRUSH",
          "resource_kind": "crusher",
          "utilisation": 0.937067,
          "avg_queue_wait_min": 14.234655,
          "score": 13.338819
        },
        {
          "resource_id": "L_S",
          "resource_kind": "loader",
          "utilisation": 0.844934,
          "avg_queue_wait_min": 3.711354,
          "score": 3.135851
        },
        {
          "resource_id": "L_N",
          "resource_kind": "loader",
          "utilisation": 0.640663,
          "avg_queue_wait_min": 3.030277,
          "score": 1.941386
        },
        {
          "resource_id": "E03_UP",
          "resource_kind": "edge",
          "utilisation": 0.078432,
          "avg_queue_wait_min": 16.896822,
          "score": 1.325246
        },
        {
          "resource_id": "E05_TO_CRUSH",
          "resource_kind": "edge",
          "utilisation": 0.445851,
          "avg_queue_wait_min": 0.164807,
          "score": 0.073479
        }
      ]
    },
    "ramp_upgrade": {
      "scenario_id": "ramp_upgrade",
      "replications": 30,
      "shift_length_hours": 8.0,
      "total_tonnes_mean": 12606.666667,
      "total_tonnes_ci95_low": 12545.479796,
      "total_tonnes_ci95_high": 12667.853538,
      "tonnes_per_hour_mean": 1575.833333,
      "tonnes_per_hour_ci95_low": 1568.184974,
      "tonnes_per_hour_ci95_high": 1583.481692,
      "average_cycle_time_min": 29.546462,
      "truck_utilisation_mean": 0.994723,
      "loader_utilisation": {
        "L_N": 0.603468,
        "L_S": 0.807299
      },
      "crusher_utilisation": 0.915834,
      "average_loader_queue_time_min": 2.721649,
      "average_crusher_queue_time_min": 3.297463,
      "top_bottlenecks": [
        {
          "resource_id": "D_CRUSH",
          "resource_kind": "crusher",
          "utilisation": 0.915834,
          "avg_queue_wait_min": 3.297463,
          "score": 3.019929
        },
        {
          "resource_id": "L_S",
          "resource_kind": "loader",
          "utilisation": 0.807299,
          "avg_queue_wait_min": 2.810961,
          "score": 2.269286
        },
        {
          "resource_id": "L_N",
          "resource_kind": "loader",
          "utilisation": 0.603468,
          "avg_queue_wait_min": 2.54961,
          "score": 1.538608
        },
        {
          "resource_id": "E09_TO_LOAD_S",
          "resource_kind": "edge",
          "utilisation": 0.364576,
          "avg_queue_wait_min": 0.61218,
          "score": 0.223186
        },
        {
          "resource_id": "E05_TO_CRUSH",
          "resource_kind": "edge",
          "utilisation": 0.421397,
          "avg_queue_wait_min": 0.149839,
          "score": 0.063142
        }
      ]
    },
    "crusher_slowdown": {
      "scenario_id": "crusher_slowdown",
      "replications": 30,
      "shift_length_hours": 8.0,
      "total_tonnes_mean": 6513.333333,
      "total_tonnes_ci95_low": 6456.37896,
      "total_tonnes_ci95_high": 6570.287707,
      "tonnes_per_hour_mean": 814.166667,
      "tonnes_per_hour_ci95_low": 807.04737,
      "tonnes_per_hour_ci95_high": 821.285963,
      "average_cycle_time_min": 55.488254,
      "truck_utilisation_mean": 0.973473,
      "loader_utilisation": {
        "L_N": 0.329364,
        "L_S": 0.445261
      },
      "crusher_utilisation": 0.947676,
      "average_loader_queue_time_min": 0.641623,
      "average_crusher_queue_time_min": 26.566543,
      "top_bottlenecks": [
        {
          "resource_id": "D_CRUSH",
          "resource_kind": "crusher",
          "utilisation": 0.947676,
          "avg_queue_wait_min": 26.566543,
          "score": 25.176473
        },
        {
          "resource_id": "E03_UP",
          "resource_kind": "edge",
          "utilisation": 0.052746,
          "avg_queue_wait_min": 10.890609,
          "score": 0.574431
        },
        {
          "resource_id": "L_S",
          "resource_kind": "loader",
          "utilisation": 0.445261,
          "avg_queue_wait_min": 0.931278,
          "score": 0.414662
        },
        {
          "resource_id": "E05_TO_CRUSH",
          "resource_kind": "edge",
          "utilisation": 0.231771,
          "avg_queue_wait_min": 0.139459,
          "score": 0.032323
        },
        {
          "resource_id": "L_N",
          "resource_kind": "loader",
          "utilisation": 0.329364,
          "avg_queue_wait_min": 0.080543,
          "score": 0.026528
        }
      ]
    },
    "ramp_closed": {
      "scenario_id": "ramp_closed",
      "replications": 30,
      "shift_length_hours": 8.0,
      "total_tonnes_mean": 12363.333333,
      "total_tonnes_ci95_low": 12297.930568,
      "total_tonnes_ci95_high": 12428.736099,
      "tonnes_per_hour_mean": 1545.416667,
      "tonnes_per_hour_ci95_low": 1537.241321,
      "tonnes_per_hour_ci95_high": 1553.592012,
      "average_cycle_time_min": 30.108704,
      "truck_utilisation_mean": 0.994325,
      "loader_utilisation": {
        "L_N": 0.658173,
        "L_S": 0.744467
      },
      "crusher_utilisation": 0.898253,
      "average_loader_queue_time_min": 3.176232,
      "average_crusher_queue_time_min": 3.207245,
      "top_bottlenecks": [
        {
          "resource_id": "L_N",
          "resource_kind": "loader",
          "utilisation": 0.658173,
          "avg_queue_wait_min": 4.879233,
          "score": 3.21138
        },
        {
          "resource_id": "D_CRUSH",
          "resource_kind": "crusher",
          "utilisation": 0.898253,
          "avg_queue_wait_min": 3.207245,
          "score": 2.880916
        },
        {
          "resource_id": "L_S",
          "resource_kind": "loader",
          "utilisation": 0.744467,
          "avg_queue_wait_min": 2.125733,
          "score": 1.582538
        },
        {
          "resource_id": "E07_TO_LOAD_N",
          "resource_kind": "edge",
          "utilisation": 0.210064,
          "avg_queue_wait_min": 1.073342,
          "score": 0.225471
        },
        {
          "resource_id": "E05_TO_CRUSH",
          "resource_kind": "edge",
          "utilisation": 0.415261,
          "avg_queue_wait_min": 0.161427,
          "score": 0.067034
        }
      ]
    },
    "trucks_12_ramp_upgrade": {
      "scenario_id": "trucks_12_ramp_upgrade",
      "replications": 30,
      "shift_length_hours": 8.0,
      "total_tonnes_mean": 12953.333333,
      "total_tonnes_ci95_low": 12869.702929,
      "total_tonnes_ci95_high": 13036.963738,
      "tonnes_per_hour_mean": 1619.166667,
      "tonnes_per_hour_ci95_low": 1608.712866,
      "tonnes_per_hour_ci95_high": 1629.620467,
      "average_cycle_time_min": 42.541378,
      "truck_utilisation_mean": 0.988183,
      "loader_utilisation": {
        "L_N": 0.640686,
        "L_S": 0.849761
      },
      "crusher_utilisation": 0.940564,
      "average_loader_queue_time_min": 3.963752,
      "average_crusher_queue_time_min": 14.296978,
      "top_bottlenecks": [
        {
          "resource_id": "D_CRUSH",
          "resource_kind": "crusher",
          "utilisation": 0.940564,
          "avg_queue_wait_min": 14.296978,
          "score": 13.447226
        },
        {
          "resource_id": "L_S",
          "resource_kind": "loader",
          "utilisation": 0.849761,
          "avg_queue_wait_min": 4.401933,
          "score": 3.740592
        },
        {
          "resource_id": "L_N",
          "resource_kind": "loader",
          "utilisation": 0.640686,
          "avg_queue_wait_min": 3.125669,
          "score": 2.002573
        },
        {
          "resource_id": "E09_TO_LOAD_S",
          "resource_kind": "edge",
          "utilisation": 0.381888,
          "avg_queue_wait_min": 1.381388,
          "score": 0.527536
        },
        {
          "resource_id": "E05_TO_CRUSH",
          "resource_kind": "edge",
          "utilisation": 0.446615,
          "avg_queue_wait_min": 0.162179,
          "score": 0.072432
        }
      ]
    }
  },
  "key_assumptions": [
    "Time horizon: a hard cut at t=480 min via env.run(until=480). Only end_dump events that close strictly before 480 credit tonnes; loads or dumps still in progress at the cut are discarded (operator-facing 'tonnes closed at shift end').",
    "Routing: static shortest-time per scenario via Dijkstra on free-flow edge times (distance_m / (max_speed_kph*1000/60)). Recomputed only when a scenario closes or upgrades edges; a truck commits to its path at dispatch and does not re-plan mid-leg.",
    "Capacity-1 directed edges are modelled as independent SimPy Resources, mirroring edges.csv literally: the 8 single-lane segments are E03_UP/DOWN (ramp), E05_TO/FROM_CRUSH (crusher approach), E07_TO/FROM_LOAD_N and E09_TO/FROM_LOAD_S (pit-face roads).",
    "Each physical direction is a separate resource: E03_UP and E03_DOWN are two capacity-1 lanes, so opposing trucks do not contend for one shared lane (no head-on blocking is modelled).",
    "Travel-time noise: an independent per-edge-traversal lognormal multiplier with mean 1 and cv=0.10 (sigma^2 = ln(1+cv^2), mu = -sigma^2/2). Empty trucks use empty_speed_factor=1.00, loaded trucks loaded_speed_factor=0.85.",
    "Loading and dumping times are drawn from normal_truncated(mean, sd) floored at max(0.1, sample) so durations are strictly positive without biasing the mean. Parameters: L_N 6.5/1.2, L_S 4.5/1.0, D_CRUSH 3.5/0.8 min (crusher_slowdown raises D_CRUSH to 7.0/1.5).",
    "Dispatch: each empty truck is sent to argmin(travel_to_loader + queue_len * mean_load_time + own_mean_load), where queue_len counts trucks in service plus waiting. Ties break by lower loader_id. The route is static; the loader choice is dynamic.",
    "Initial conditions: all trucks released simultaneously at t=0 from PARK; no warmup, staged ramp-up, or shift-handover modelling.",
    "Throughput accounting: tonnes are credited at end_dump (not arrive or start_dump). Every completed dump credits exactly the truck payload (homogeneous 100 t fleet).",
    "Scope: only ore haulage to the primary crusher is simulated (LOAD_N/LOAD_S -> CRUSH). WASTE and MAINT remain in the graph for completeness but carry no truck traffic and are excluded from routing and dispatch.",
    "Reproducibility: per-replication seed = base_random_seed (12345) + replication_index, with independent numpy SeedSequence streams per stochastic source, so each replication is independently reproducible and the full run is deterministic.",
    "Uncertainty: 95% confidence intervals are Student-t with n-1 = 29 degrees of freedom over 30 replications per scenario."
  ],
  "model_limitations": [
    "No truck breakdowns, refuelling, or maintenance windows: truck availability is held at 1.00 for the whole 480-min shift, so the model estimates an upper-bound, fully-available throughput.",
    "Separate ramp directions: E03_UP and E03_DOWN are two independent single-lane resources. If the real ramp is one shared physical lane, true congestion (head-on / passing constraints) would be worse than modelled.",
    "Static routing: trucks commit to their shortest-time path at dispatch and never divert, even if a capacity-1 edge develops a queue. A real dispatcher could re-route through the bypass, so modelled queueing on single-lane edges is an upper bound.",
    "Boundary under-count: productive time and tonnes accrue only on completed phases. A load/dump/leg straddling t=480 contributes nothing, slightly under-counting both utilisation and the final cycle.",
    "Crusher never blocks downstream: D_CRUSH has no stockpile back-pressure, full-bin signal, or scheduled maintenance. Real surge-pile limits are not represented.",
    "Single homogeneous payload: every dump is exactly 100 t. Heterogeneous trucks, ore blending, and grade-dependent processing are not modelled.",
    "Free-flow (capacity 999) edges have effectively unlimited capacity: trucks do not interact on multi-lane haul roads, so headway and following-distance effects are ignored.",
    "No warmup trimming: the shift starts empty (all trucks at PARK, all queues empty). The empty-system bias is small because the fleet reaches steady state within a few cycles, but it is not zero.",
    "Deterministic speeds aside from edge noise: max-speeds and per-truck speed factors are fixed. Only the per-edge lognormal multiplier (cv=0.10) introduces travel variability \u2014 weather, dust, and visibility are not modelled.",
    "Node coordinates from nodes.csv are used for visualisation only; haul-road bends and grade are not propagated into travel time beyond the given distance_m and max_speed_kph."
  ],
  "additional_scenarios_proposed": [
    "trucks_12_ramp_upgrade (included here as the 7th scenario): combines a 12-truck fleet with the ramp upgrade to test whether the two investments are complementary, substitutive, or independent. Because the loaded legs to the crusher never use the ramp, the upgrade adds little on top of the fleet increase \u2014 the pair is close to non-interacting.",
    "Crusher reliability: inject random short outages on D_CRUSH (e.g. 5 min every 60 min) to size the surge-pile buffer and quantify the cost of unplanned crusher downtime, since the crusher is the binding constraint.",
    "Dynamic re-routing: re-plan when a queue at a capacity-1 edge exceeds a threshold (e.g. 2 waiting trucks). Quantifies the upside available from a smarter dispatcher over the static-routing baseline.",
    "Crusher service-time upgrade: cut mean dump time from 3.5 to 2.5 min and re-run trucks_12 to confirm the crusher is the true ceiling and value a faster tip.",
    "Heterogeneous fleet: replace some 100 t trucks with 150 t trucks to trade cycle count for per-cycle payload and find the mix that maximises tonnes given the crusher constraint.",
    "Mid-shift loader outage: take L_N or L_S offline for 30 min mid-shift to size the single-loader fall-back tonnes and inform redundancy planning."
  ]
}