Flight Optimizer

Graph-based flight line ordering with endurance constraints, refueling stops, and multi-day scheduling. Uses a greedy nearest-neighbour heuristic over a transit-time weighted directed graph.

Graph construction

build_graph(aircraft, flight_lines, airports)[source]

Build a directed graph connecting airports and visit-item endpoints.

Each input item is one of:

  • FlightLine — a single bidirectional flight line.

  • Pattern — an atomic, direction-locked composite visit item.

  • Waypoint — a single point in space, with optional delay for in-place loiter time.

Patterns and bare Waypoints are represented as a single pair of endpoint nodes (entry/exit) with one forward along-edge — there is no individual graph node for an internal pattern leg, and a Waypoint’s two endpoint nodes share the same waypoint reference. This is what enforces atomicity in greedy_optimize.

Nodes:
  • Airport nodes keyed by ICAO code

  • Visit-item endpoint nodes keyed by "{key}_start" and "{key}_end", where key is derived from the item’s site_name (FlightLine), pattern_id/name (Pattern), or name (Waypoint).

Edges:
  • flight_line: along each FlightLine (both directions)

  • pattern: along each Pattern (forward only — entry -> exit)

  • waypoint: along each bare Waypoint (forward only; weight equals waypoint.delay in hours, or 0)

  • departure: airport -> visit-item endpoint

  • transit: between visit-item endpoints (via Dubins path)

  • return: visit-item endpoint -> airport

All edge weights are transit time in hours.

Parameters:
  • aircraft (Aircraft) – Aircraft to use for performance calculations.

  • flight_lines (list) – List of FlightLine | Pattern | Waypoint objects to schedule. (Parameter name retained for backward compatibility; the optimizer now also accepts Pattern and bare Waypoint objects in this list.)

  • airports (list) – List of Airport objects (potential departure/return/refuel points).

Return type:

DiGraph

Returns:

nx.DiGraph with time-weighted edges.

Optimization

greedy_optimize(aircraft, flight_lines, airports, takeoff_airport, return_airport=None, max_endurance=None, refuel_time=0.5, max_daily_flight_time=None, takeoff_landing_overhead=0.25, max_days=1)[source]

Greedy nearest-neighbor optimization of visit-item ordering.

Builds a graph of all visit items and airports, then iteratively selects the closest feasible unvisited item, inserting refuel stops when endurance limits would be exceeded. Supports multi-day missions where daily flight time resets each day.

Parameters:
  • aircraft (Aircraft) – Aircraft performing the mission.

  • flight_lines (list) – List of FlightLine | Pattern | Waypoint objects to cover. Patterns and bare Waypoints are treated as atomic visit items: the optimizer may reorder a Pattern or Waypoint relative to other items but never splits it apart. Pattern traversal is direction-locked (entry -> exit). A bare Waypoint has identical entry/exit (a single point); its internal time equals waypoint.delay (loiter), or 0 if unset, and a delay too large to fit in remaining endurance forces a refuel before the waypoint, never inside the loiter.

  • airports (list) – List of Airport objects available for refueling.

  • takeoff_airport (Airport) – Departure airport.

  • return_airport (Airport | None) – Return airport (defaults to takeoff_airport).

  • max_endurance (float | None) – Maximum flight time in hours before refueling. Defaults to aircraft.endurance.

  • refuel_time (float) – Time in hours for refueling stop (default 0.5).

  • max_daily_flight_time (float | None) – Maximum flying hours per day. Defaults to aircraft.endurance (no daily limit beyond endurance).

  • takeoff_landing_overhead (float) – Time in hours for takeoff/landing procedures not captured in route calculations (default 0.25).

  • max_days (int) – Maximum number of flight days (default 1).

Returns:

  • “flight_sequence”: list of FlightLine | Pattern | Waypoint objects in the order they were scheduled. FlightLines may be reversed from their original orientation; Patterns and bare Waypoints appear unchanged (direction-locked entry -> exit).

  • ”items_covered”: int — number of completed visit items (each Pattern, FlightLine, or Waypoint counts as 1).

  • ”items_skipped”: list[str] — keys of visit items the optimizer was unable to schedule.

  • ”lines_covered”: int — number of actual flight-line legs completed. A line-based Pattern contributes one per internal leg; a waypoint-based Pattern or bare Waypoint contributes 0. For all-FlightLine input this equals items_covered.

  • ”lines_skipped”: list[str] — keys of the actual flight-line legs that were skipped. A skipped line-based Pattern is expanded to "{item_key}:{line_id}" for each of its internal legs; skipped waypoint-based Patterns and bare Waypoints contribute nothing.

  • ”route”: list of node names traversed

  • ”total_time”: total mission time in hours (across all days)

  • ”daily_times”: list of flight time per day

  • ”lines_covered”: number of visit items completed

  • ”lines_skipped”: list of item keys that were infeasible

  • ”refuel_stops”: list of airport ICAO codes where refueling occurred

  • ”days_used”: number of days used

  • ”takeoff_airport”: Airport object

  • ”return_airport”: Airport object

  • ”graph”: the constructed DiGraph

Return type:

dict with