File size: 1,768 Bytes
2e50ccd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
"""Compute hub scores for airports.

Hub score = route_count * carrier_diversity * continent_reach
Used for: connecting flight search (top hubs as waypoints) and autocomplete ranking.
"""

from __future__ import annotations

from .config import HUB_MIN_ROUTES, HUB_TOP_N
from .data_loader import RouteGraph


def compute_hub_scores(graph: RouteGraph) -> list[str]:
    """Compute hub scores for all airports. Returns top hub IATA codes.

    Modifies airports in-place to set hub_score.
    """
    for airport in graph.airports.values():
        route_count = len(airport.routes)
        if route_count < 5:
            airport.hub_score = 0.0
            continue

        # Carrier diversity: unique carriers across all routes
        carriers = set()
        for route in airport.routes:
            for c in route.carriers:
                carriers.add(c["iata"])
        carrier_diversity = len(carriers)

        # Continent reach: unique continents reachable
        continents = set()
        for route in airport.routes:
            dest = graph.airports.get(route.destination)
            if dest:
                continents.add(dest.continent)
        continent_reach = len(continents)

        airport.hub_score = route_count * (carrier_diversity ** 0.5) * (continent_reach ** 0.3)

    # Normalize scores to 0-100
    max_score = max((a.hub_score for a in graph.airports.values()), default=1.0)
    if max_score > 0:
        for airport in graph.airports.values():
            airport.hub_score = round(airport.hub_score / max_score * 100, 2)

    # Return top hubs
    hubs = sorted(
        [a for a in graph.airports.values() if len(a.routes) >= HUB_MIN_ROUTES],
        key=lambda a: -a.hub_score,
    )
    return [h.iata for h in hubs[:HUB_TOP_N]]