Flight Gate Assignment Example
The Flight Gate Assignment problem assigns flights to airport gates so that total passenger transit time is minimised while respecting time-overlap constraints. It is a key problem in airport operations research.
import getpass
import os
import numpy as np
from dotenv import load_dotenv
from luna_quantum.algorithms import SCIP
from luna_usecases.flight_gate_assignment import (
FlightGateAssignmentCollection,
FlightGateAssignmentData,
FlightGateAssignmentFormulation,
FlightGateAssignmentInstance,
)
load_dotenv()
if "LUNA_API_KEY" not in os.environ:
os.environ["LUNA_API_KEY"] = getpass.getpass("Enter your Luna API key: ")
Create Data
Define 4 flights with passenger counts and time windows, and 3 gates with positions.
data = FlightGateAssignmentData.from_schedule(
arrival_passengers=[120, 80, 150, 90],
departure_passengers=[100, 110, 70, 130],
flight_times=[(0.0, 2.0), (1.0, 3.0), (2.5, 4.5), (3.0, 5.0)],
gate_to_terminal=np.array([[0.0, 0.0], [1.0, 0.0], [0.5, 1.0]]),
buffer_time=0.5,
)
print(data.to_string())
Plot Data
Visualize flight time windows and gate layout.
Create Formulation
Assign flights to gates minimizing passenger walking distance, respecting time overlaps.
Flight Gate Assignment Formulation:
Flights: 4
Gates: 3
Buffer time: 0.5
Decision Variables:
x[f,g] in {0,1} for f = 0, ..., 3, g = 0, ..., 2
x[f,g] = 1 if flight f is assigned to gate g
Total: 12 binary variables
Objective:
minimize sum_(Undefined, Undefined) (arr_pax[f]*dist[g,0] + dep_pax[f]*dist[g,1]) * x[f,g]
Constraints:
1. Each flight assigned to exactly one gate (4 constraints):
sum_g x[f,g] == 1 for all f = 0, ..., 3
2. Non-overlapping flights at same gate (12 constraints):
x[f1,g] + x[f2,g] <= 1 for all overlapping pairs (f1,f2), g = 0, ..., 2
Create Instance
Combine data and formulation into a solvable instance.
instance = FlightGateAssignmentInstance(data=data, formulation=formulation)
print(instance.to_string())
Data:Flight Gate Assignment Data:
Flights: 4
Gates: 3
Buffer time: 0.5
Formulation:Flight Gate Assignment Formulation:
Flights: 4
Gates: 3
Buffer time: 0.5
Decision Variables:
x[f,g] in {0,1} for f = 0, ..., 3, g = 0, ..., 2
x[f,g] = 1 if flight f is assigned to gate g
Total: 12 binary variables
Objective:
minimize sum_(Undefined, Undefined) (arr_pax[f]*dist[g,0] + dep_pax[f]*dist[g,1]) * x[f,g]
Constraints:
1. Each flight assigned to exactly one gate (4 constraints):
sum_g x[f,g] == 1 for all f = 0, ..., 3
2. Non-overlapping flights at same gate (12 constraints):
x[f1,g] + x[f2,g] <= 1 for all overlapping pairs (f1,f2), g = 0, ..., 2
Formulate Model
Translate the instance into a mathematical optimization model.
Solve and Interpret
Solve the model with SCIP and interpret the raw result into a use-case-specific solution.
scip = SCIP()
job = scip.run(model)
sol = job.result()
uc_solution = instance.interpret(sol)
print(uc_solution.to_string())
/Users/maximilianjanetschek/PycharmProjects/luna-usecases/.venv/lib/python3.13/site-packages/rich/live.py:260:
UserWarning: install "ipywidgets" for Jupyter support
warnings.warn('install "ipywidgets" for Jupyter support')
2026-05-29 11:33:33 INFO Sleeping for 5.0 seconds. Waiting and checking a function in a loop.
2026-05-29 11:33:39 INFO Sleeping for 10.0 seconds. Waiting and checking a function in a loop.
2026-05-29 11:33:50 INFO Sleeping for 15.0 seconds. Waiting and checking a function in a loop.
2026-05-29 11:34:07 INFO Sleeping for 20.0 seconds. Waiting and checking a function in a loop.
Flight Gate Assignment Solution:
Total transit time: 225.00
Valid: True
Assignments: {0: 0, 1: 1, 2: 2, 3: 0}
Plot Solution
Visualize the optimal solution.
<Axes: title={'center': 'FGA Solution - transit 225.0'}, xlabel='Time (bc = baggage claim dist., ci = check-in dist.)'>
Collections
Generate a benchmark collection of random instances for batch processing.
collection = FlightGateAssignmentCollection.from_random(
min_flights=3,
max_flights=5,
n_gates=3,
seed=42,
)
model = collection.instances[0].formulate()
print(model)
Model: flight_gate_assignment<flight_gate_assignment>
Minimize
759.2076155731002 * x_0_0 + 1502.554563337249 * x_0_1
+ 1468.877425136867 * x_0_2 + 300.375532664159 * x_1_0
+ 593.1773484883886 * x_1_1 + 641.9422753541782 * x_1_2
+ 426.5532537392471 * x_2_0 + 844.0948044103003 * x_2_1
+ 829.9810983990487 * x_2_2
Subject To
one_gate_0: x_0_0 + x_0_1 + x_0_2 == 1
one_gate_1: x_1_0 + x_1_1 + x_1_2 == 1
one_gate_2: x_2_0 + x_2_1 + x_2_2 == 1
no_overlap_0_2_g0: x_0_0 + x_2_0 <= 1
no_overlap_0_2_g1: x_0_1 + x_2_1 <= 1
no_overlap_0_2_g2: x_0_2 + x_2_2 <= 1
Binary
x_0_0 x_0_1 x_0_2 x_1_0 x_1_1 x_1_2 x_2_0 x_2_1 x_2_2