Spaces:
Sleeping
Sleeping
Commit ·
64a5cd1
1
Parent(s): 4fc9bec
Add easy/medium/hard task scenarios and programmatic grader
Browse files- grader.py +24 -0
- tasks/easy.yaml +62 -0
- tasks/hard.yaml +65 -0
- tasks/medium.yaml +96 -0
grader.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Programmatic grader. Returns a single 0.0–1.0 score for an episode."""
|
| 2 |
+
|
| 3 |
+
from __future__ import annotations
|
| 4 |
+
|
| 5 |
+
from typing import Optional
|
| 6 |
+
|
| 7 |
+
from models import Reward
|
| 8 |
+
from reward import calculate_episode_reward
|
| 9 |
+
from simulation import DispatchSimulation
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def grade_simulation(sim: DispatchSimulation) -> Reward:
|
| 13 |
+
"""Compute the final Reward from a (finished or in-progress) simulation."""
|
| 14 |
+
return calculate_episode_reward(
|
| 15 |
+
sim.completed_calls,
|
| 16 |
+
sim.timed_out_calls,
|
| 17 |
+
sim.total_calls(),
|
| 18 |
+
sim.dispatches,
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def grade_score(sim: DispatchSimulation) -> float:
|
| 23 |
+
"""Convenience: just the scalar 0.0–1.0 score."""
|
| 24 |
+
return grade_simulation(sim).total
|
tasks/easy.yaml
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: easy
|
| 2 |
+
description: >
|
| 3 |
+
Routine urban shift. Five calls over 30 minutes, four units, one well-equipped
|
| 4 |
+
hospital. Callers report accurately. Optimal play scores ~0.85+.
|
| 5 |
+
|
| 6 |
+
grid_size: 10.0
|
| 7 |
+
caller_inaccuracy: 0.0
|
| 8 |
+
|
| 9 |
+
world_config:
|
| 10 |
+
grid_size_km: 10.0
|
| 11 |
+
time_limit_minutes: 30
|
| 12 |
+
step_duration_minutes: 1
|
| 13 |
+
call_timeout_minutes: 20
|
| 14 |
+
max_wait_step_minutes: 5
|
| 15 |
+
|
| 16 |
+
units:
|
| 17 |
+
- unit_id: "ALS-1"
|
| 18 |
+
unit_type: "als_ambulance"
|
| 19 |
+
position: {x: 3.0, y: 7.0}
|
| 20 |
+
base_position: {x: 3.0, y: 7.0}
|
| 21 |
+
status: "available"
|
| 22 |
+
speed_kmh: 60.0
|
| 23 |
+
capabilities: ["cardiac_arrest", "trauma", "stroke", "breathing_difficulty", "minor_injury"]
|
| 24 |
+
- unit_id: "BLS-1"
|
| 25 |
+
unit_type: "bls_ambulance"
|
| 26 |
+
position: {x: 7.0, y: 3.0}
|
| 27 |
+
base_position: {x: 7.0, y: 3.0}
|
| 28 |
+
status: "available"
|
| 29 |
+
speed_kmh: 55.0
|
| 30 |
+
capabilities: ["trauma", "breathing_difficulty", "minor_injury"]
|
| 31 |
+
- unit_id: "FIRE-1"
|
| 32 |
+
unit_type: "fire_engine"
|
| 33 |
+
position: {x: 5.0, y: 5.0}
|
| 34 |
+
base_position: {x: 5.0, y: 5.0}
|
| 35 |
+
status: "available"
|
| 36 |
+
speed_kmh: 50.0
|
| 37 |
+
capabilities: ["fire"]
|
| 38 |
+
- unit_id: "POL-1"
|
| 39 |
+
unit_type: "police"
|
| 40 |
+
position: {x: 2.0, y: 2.0}
|
| 41 |
+
base_position: {x: 2.0, y: 2.0}
|
| 42 |
+
status: "available"
|
| 43 |
+
speed_kmh: 65.0
|
| 44 |
+
capabilities: ["mental_health_crisis"]
|
| 45 |
+
|
| 46 |
+
hospitals:
|
| 47 |
+
- hospital_id: "H1"
|
| 48 |
+
name: "City General Hospital"
|
| 49 |
+
position: {x: 5.0, y: 5.0}
|
| 50 |
+
capacity: 40
|
| 51 |
+
available_beds: 25
|
| 52 |
+
has_trauma_center: true
|
| 53 |
+
has_cardiac_unit: true
|
| 54 |
+
has_stroke_unit: true
|
| 55 |
+
on_diversion: false
|
| 56 |
+
|
| 57 |
+
calls:
|
| 58 |
+
- {arrival_minute: 1, type: "minor_injury", severity: 4}
|
| 59 |
+
- {arrival_minute: 3, type: "cardiac_arrest", severity: 1}
|
| 60 |
+
- {arrival_minute: 8, type: "fire", severity: 2}
|
| 61 |
+
- {arrival_minute: 15, type: "trauma", severity: 2}
|
| 62 |
+
- {arrival_minute: 22, type: "breathing_difficulty", severity: 3}
|
tasks/hard.yaml
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: hard
|
| 2 |
+
description: >
|
| 3 |
+
Earthquake response scenario. 30 calls in 60 minutes, 8 units, 3 hospitals
|
| 4 |
+
(one on diversion, one near capacity). 35% caller misreporting due to panic.
|
| 5 |
+
Strong play scores ~0.40-0.55.
|
| 6 |
+
|
| 7 |
+
grid_size: 15.0
|
| 8 |
+
caller_inaccuracy: 0.35
|
| 9 |
+
|
| 10 |
+
world_config:
|
| 11 |
+
grid_size_km: 15.0
|
| 12 |
+
time_limit_minutes: 60
|
| 13 |
+
step_duration_minutes: 1
|
| 14 |
+
call_timeout_minutes: 30
|
| 15 |
+
max_wait_step_minutes: 5
|
| 16 |
+
|
| 17 |
+
units:
|
| 18 |
+
- {unit_id: "ALS-1", unit_type: "als_ambulance", position: {x: 5.0, y: 12.0}, base_position: {x: 5.0, y: 12.0}, status: "available", speed_kmh: 40.0, capabilities: ["cardiac_arrest", "trauma", "stroke", "breathing_difficulty", "minor_injury"]}
|
| 19 |
+
- {unit_id: "ALS-2", unit_type: "als_ambulance", position: {x: 10.0, y: 5.0}, base_position: {x: 10.0, y: 5.0}, status: "available", speed_kmh: 40.0, capabilities: ["cardiac_arrest", "trauma", "stroke", "breathing_difficulty", "minor_injury"]}
|
| 20 |
+
- {unit_id: "BLS-1", unit_type: "bls_ambulance", position: {x: 3.0, y: 7.0}, base_position: {x: 3.0, y: 7.0}, status: "available", speed_kmh: 35.0, capabilities: ["trauma", "breathing_difficulty", "minor_injury"]}
|
| 21 |
+
- {unit_id: "BLS-2", unit_type: "bls_ambulance", position: {x: 12.0, y: 10.0},base_position: {x: 12.0, y: 10.0},status: "available", speed_kmh: 35.0, capabilities: ["trauma", "breathing_difficulty", "minor_injury"]}
|
| 22 |
+
- {unit_id: "BLS-3", unit_type: "bls_ambulance", position: {x: 7.0, y: 3.0}, base_position: {x: 7.0, y: 3.0}, status: "available", speed_kmh: 35.0, capabilities: ["trauma", "breathing_difficulty", "minor_injury"]}
|
| 23 |
+
- {unit_id: "FIRE-1",unit_type: "fire_engine", position: {x: 8.0, y: 8.0}, base_position: {x: 8.0, y: 8.0}, status: "available", speed_kmh: 38.0, capabilities: ["fire"]}
|
| 24 |
+
- {unit_id: "FIRE-2",unit_type: "fire_engine", position: {x: 2.0, y: 13.0}, base_position: {x: 2.0, y: 13.0}, status: "available", speed_kmh: 38.0, capabilities: ["fire"]}
|
| 25 |
+
- {unit_id: "POL-1", unit_type: "police", position: {x: 7.0, y: 7.0}, base_position: {x: 7.0, y: 7.0}, status: "available", speed_kmh: 50.0, capabilities: ["mental_health_crisis"]}
|
| 26 |
+
|
| 27 |
+
hospitals:
|
| 28 |
+
- {hospital_id: "H1", name: "Metro Trauma Center", position: {x: 6.0, y: 8.0}, capacity: 50, available_beds: 10, has_trauma_center: true, has_cardiac_unit: true, has_stroke_unit: true, on_diversion: false}
|
| 29 |
+
- {hospital_id: "H2", name: "Community Hospital", position: {x: 12.0, y: 4.0}, capacity: 25, available_beds: 5, has_trauma_center: false, has_cardiac_unit: true, has_stroke_unit: false, on_diversion: false}
|
| 30 |
+
- {hospital_id: "H3", name: "Childrens Hospital", position: {x: 3.0, y: 12.0}, capacity: 30, available_beds: 0, has_trauma_center: false, has_cardiac_unit: false, has_stroke_unit: false, on_diversion: true}
|
| 31 |
+
|
| 32 |
+
calls:
|
| 33 |
+
# Earthquake hits
|
| 34 |
+
- {arrival_minute: 1, type: "trauma", severity: 1}
|
| 35 |
+
- {arrival_minute: 1, type: "trauma", severity: 1}
|
| 36 |
+
- {arrival_minute: 1, type: "trauma", severity: 2}
|
| 37 |
+
- {arrival_minute: 2, type: "fire", severity: 1}
|
| 38 |
+
- {arrival_minute: 2, type: "trauma", severity: 2}
|
| 39 |
+
- {arrival_minute: 3, type: "cardiac_arrest", severity: 1}
|
| 40 |
+
- {arrival_minute: 3, type: "breathing_difficulty", severity: 2}
|
| 41 |
+
- {arrival_minute: 3, type: "trauma", severity: 3}
|
| 42 |
+
- {arrival_minute: 4, type: "fire", severity: 2}
|
| 43 |
+
- {arrival_minute: 5, type: "trauma", severity: 1}
|
| 44 |
+
# Aftershock
|
| 45 |
+
- {arrival_minute: 10, type: "trauma", severity: 1}
|
| 46 |
+
- {arrival_minute: 10, type: "trauma", severity: 2}
|
| 47 |
+
- {arrival_minute: 11, type: "cardiac_arrest", severity: 1}
|
| 48 |
+
- {arrival_minute: 11, type: "minor_injury", severity: 4}
|
| 49 |
+
- {arrival_minute: 12, type: "mental_health_crisis", severity: 3}
|
| 50 |
+
- {arrival_minute: 12, type: "breathing_difficulty", severity: 2}
|
| 51 |
+
- {arrival_minute: 13, type: "fire", severity: 1}
|
| 52 |
+
- {arrival_minute: 14, type: "trauma", severity: 2}
|
| 53 |
+
- {arrival_minute: 15, type: "stroke", severity: 1}
|
| 54 |
+
- {arrival_minute: 15, type: "minor_injury", severity: 4}
|
| 55 |
+
# Ongoing rescue
|
| 56 |
+
- {arrival_minute: 20, type: "trauma", severity: 2}
|
| 57 |
+
- {arrival_minute: 22, type: "cardiac_arrest", severity: 1}
|
| 58 |
+
- {arrival_minute: 25, type: "minor_injury", severity: 3}
|
| 59 |
+
- {arrival_minute: 28, type: "breathing_difficulty", severity: 2}
|
| 60 |
+
- {arrival_minute: 32, type: "trauma", severity: 2}
|
| 61 |
+
- {arrival_minute: 35, type: "fire", severity: 2}
|
| 62 |
+
- {arrival_minute: 40, type: "mental_health_crisis", severity: 3}
|
| 63 |
+
- {arrival_minute: 45, type: "stroke", severity: 1}
|
| 64 |
+
- {arrival_minute: 50, type: "minor_injury", severity: 4}
|
| 65 |
+
- {arrival_minute: 55, type: "trauma", severity: 2}
|
tasks/medium.yaml
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: medium
|
| 2 |
+
description: >
|
| 3 |
+
Urban scenario. 15 calls in 45 minutes, 6 units, 2 hospitals. Includes a mass
|
| 4 |
+
casualty bus accident at minute 12 and 20% caller inaccuracy. Reasonable play
|
| 5 |
+
scores ~0.55-0.70.
|
| 6 |
+
|
| 7 |
+
grid_size: 12.0
|
| 8 |
+
caller_inaccuracy: 0.20
|
| 9 |
+
|
| 10 |
+
world_config:
|
| 11 |
+
grid_size_km: 12.0
|
| 12 |
+
time_limit_minutes: 45
|
| 13 |
+
step_duration_minutes: 1
|
| 14 |
+
call_timeout_minutes: 25
|
| 15 |
+
max_wait_step_minutes: 5
|
| 16 |
+
|
| 17 |
+
units:
|
| 18 |
+
- unit_id: "ALS-1"
|
| 19 |
+
unit_type: "als_ambulance"
|
| 20 |
+
position: {x: 4.0, y: 8.0}
|
| 21 |
+
base_position: {x: 4.0, y: 8.0}
|
| 22 |
+
status: "available"
|
| 23 |
+
speed_kmh: 50.0
|
| 24 |
+
capabilities: ["cardiac_arrest", "trauma", "stroke", "breathing_difficulty", "minor_injury"]
|
| 25 |
+
- unit_id: "ALS-2"
|
| 26 |
+
unit_type: "als_ambulance"
|
| 27 |
+
position: {x: 9.0, y: 4.0}
|
| 28 |
+
base_position: {x: 9.0, y: 4.0}
|
| 29 |
+
status: "available"
|
| 30 |
+
speed_kmh: 50.0
|
| 31 |
+
capabilities: ["cardiac_arrest", "trauma", "stroke", "breathing_difficulty", "minor_injury"]
|
| 32 |
+
- unit_id: "BLS-1"
|
| 33 |
+
unit_type: "bls_ambulance"
|
| 34 |
+
position: {x: 6.0, y: 6.0}
|
| 35 |
+
base_position: {x: 6.0, y: 6.0}
|
| 36 |
+
status: "available"
|
| 37 |
+
speed_kmh: 45.0
|
| 38 |
+
capabilities: ["trauma", "breathing_difficulty", "minor_injury"]
|
| 39 |
+
- unit_id: "BLS-2"
|
| 40 |
+
unit_type: "bls_ambulance"
|
| 41 |
+
position: {x: 2.0, y: 3.0}
|
| 42 |
+
base_position: {x: 2.0, y: 3.0}
|
| 43 |
+
status: "available"
|
| 44 |
+
speed_kmh: 45.0
|
| 45 |
+
capabilities: ["trauma", "breathing_difficulty", "minor_injury"]
|
| 46 |
+
- unit_id: "FIRE-1"
|
| 47 |
+
unit_type: "fire_engine"
|
| 48 |
+
position: {x: 7.0, y: 9.0}
|
| 49 |
+
base_position: {x: 7.0, y: 9.0}
|
| 50 |
+
status: "available"
|
| 51 |
+
speed_kmh: 45.0
|
| 52 |
+
capabilities: ["fire"]
|
| 53 |
+
- unit_id: "POL-1"
|
| 54 |
+
unit_type: "police"
|
| 55 |
+
position: {x: 3.0, y: 1.0}
|
| 56 |
+
base_position: {x: 3.0, y: 1.0}
|
| 57 |
+
status: "available"
|
| 58 |
+
speed_kmh: 55.0
|
| 59 |
+
capabilities: ["mental_health_crisis"]
|
| 60 |
+
|
| 61 |
+
hospitals:
|
| 62 |
+
- hospital_id: "H1"
|
| 63 |
+
name: "City General"
|
| 64 |
+
position: {x: 5.0, y: 5.0}
|
| 65 |
+
capacity: 35
|
| 66 |
+
available_beds: 15
|
| 67 |
+
has_trauma_center: true
|
| 68 |
+
has_cardiac_unit: true
|
| 69 |
+
has_stroke_unit: true
|
| 70 |
+
on_diversion: false
|
| 71 |
+
- hospital_id: "H2"
|
| 72 |
+
name: "St Marys"
|
| 73 |
+
position: {x: 10.0, y: 2.0}
|
| 74 |
+
capacity: 20
|
| 75 |
+
available_beds: 8
|
| 76 |
+
has_trauma_center: false
|
| 77 |
+
has_cardiac_unit: true
|
| 78 |
+
has_stroke_unit: false
|
| 79 |
+
on_diversion: false
|
| 80 |
+
|
| 81 |
+
calls:
|
| 82 |
+
- {arrival_minute: 1, type: "minor_injury", severity: 4}
|
| 83 |
+
- {arrival_minute: 2, type: "breathing_difficulty", severity: 3}
|
| 84 |
+
- {arrival_minute: 5, type: "trauma", severity: 2}
|
| 85 |
+
- {arrival_minute: 7, type: "cardiac_arrest", severity: 1}
|
| 86 |
+
- {arrival_minute: 8, type: "minor_injury", severity: 4}
|
| 87 |
+
- {arrival_minute: 12, type: "trauma", severity: 1}
|
| 88 |
+
- {arrival_minute: 12, type: "trauma", severity: 2}
|
| 89 |
+
- {arrival_minute: 12, type: "trauma", severity: 2}
|
| 90 |
+
- {arrival_minute: 13, type: "minor_injury", severity: 3}
|
| 91 |
+
- {arrival_minute: 18, type: "fire", severity: 2}
|
| 92 |
+
- {arrival_minute: 22, type: "stroke", severity: 1}
|
| 93 |
+
- {arrival_minute: 25, type: "mental_health_crisis", severity: 3}
|
| 94 |
+
- {arrival_minute: 30, type: "cardiac_arrest", severity: 1}
|
| 95 |
+
- {arrival_minute: 33, type: "minor_injury", severity: 4}
|
| 96 |
+
- {arrival_minute: 38, type: "breathing_difficulty", severity: 2}
|