CoolFace
Apppublic

PunitRaveendran/Air_Traffic_Control_System

sourceHugging Faceapache-2.0updated 6mo agoView on Hugging Face
1likes
grader2.py63 linesDownload Raw Back to graders
1"""Grader 2: Weighted scoring for delay, fuel-critical handling, and separation compliance."""2from typing import Dict, Any3 4 5def grade(episode_log: Dict[str, Any]) -> float:6    """7    Weighted score: 40% delay, 40% fuel-critical handling, 20% separation compliance.8 9    FIX (Bug 8): fuel_critical_count now uses 'initial_fuel_critical_ids' passed from the10    environment, which records aircraft that were FUEL_CRITICAL at spawn time.11    Previously it used final fuel_remaining_min < 15, which includes any aircraft that12    naturally depleted fuel over a long episode — massively inflating the denominator13    and making fuel_score collapse to near-zero even with perfect play.14    """15    # Updated bounds to guarantee scores are strictly between (0, 1) at 4 decimal places16    MIN_SCORE = 0.00117    MAX_SCORE = 0.99918 19    if not episode_log:20        return MIN_SCORE21 22    aircraft = episode_log.get("aircraft", [])23    total_aircraft = len(aircraft)24    if total_aircraft == 0:25        return MIN_SCORE26 27    # 40%: Landings completed28    landed = sum(1 for ac in aircraft if ac.get("status") == "LANDED")29    delay_score = landed / total_aircraft30 31    # 40%: Fuel-critical aircraft all land32    # Use initial_fuel_critical_ids if available (set at episode start before any fuel depletion).33    # Fall back to priority flag only (not fuel_remaining_min) to avoid counting aircraft34    # that aged into fuel-critical status during a long episode.35    initial_fc_ids = set(episode_log.get("initial_fuel_critical_ids", []))36    if initial_fc_ids:37        fuel_critical_count = len(initial_fc_ids)38        fuel_landed = sum(39            1 for ac in aircraft40            if ac.get("id") in initial_fc_ids and ac.get("status") == "LANDED"41        )42    else:43        # Fallback: count only aircraft whose priority is FUEL_CRITICAL (set at spawn44        # or upgraded during tick — but not using final fuel level which degrades over time)45        fuel_critical_count = sum(46            1 for ac in aircraft if ac.get("priority") == "FUEL_CRITICAL"47        )48        fuel_landed = sum(49            1 for ac in aircraft50            if ac.get("priority") == "FUEL_CRITICAL" and ac.get("status") == "LANDED"51        )52    fuel_score = fuel_landed / fuel_critical_count if fuel_critical_count > 0 else 1.053 54    # 20%: Separation compliance (duplicate sequence positions = violations)55    separation_violations = episode_log.get("separation_violations", 0)56    max_violations = 1057    separation_score = max(0.0, 1.0 - separation_violations / max_violations)58 59    final_score = 0.4 * delay_score + 0.4 * fuel_score + 0.2 * separation_score60    61    # Enforce safe boundaries on the final returned score62    return max(MIN_SCORE, min(MAX_SCORE, final_score))63