Functional Scope (In-Scope)
- Interval-Scheduling Gate Allocation: Models gate allocations as scheduled non-overlapping intervals, accounting for turnaround buffers.
- Physical Aircraft Compatibility: Gate searches ensure gates match flight wingspans, jet bridge alignments, and boarding types.
- Reactive Delay Cascades: Handles incoming flight delay propagation, shifting intervals dynamically and triggering automatic gate reassignments.
- Resource Dispatch: Coordinates ground crew turnarounds and allocates baggage carousel belts.
Explicit Boundaries (Out-of-Scope)
- Low-Level ATC Telemetry Sockets: Live radar socket connections or analog air-traffic communication structures are out-of-scope.
- Global Reservation Inventory: Excludes live passenger booking, seating management, and ticket transaction processors.
Clean reference designs demonstrating interval-scheduling gate assignments in Java and Python:
// ─── JAVA BLUEPRINT ──────────────────────────────────────────────────────────
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
enum AircraftType { SMALL, MEDIUM, LARGE }
class Flight {
private final String flightNumber;
private final AircraftType aircraftType;
private final long scheduledTime;
private final long duration;
private long delay;
public Flight(String flightNumber, AircraftType aircraftType, long scheduledTime, long duration) {
this.flightNumber = flightNumber;
this.aircraftType = aircraftType;
this.scheduledTime = scheduledTime;
this.duration = duration;
this.delay = 0;
}
public String getFlightNumber() { return flightNumber; }
public AircraftType getAircraftType() { return aircraftType; }
public long getScheduledTime() { return scheduledTime; }
public long getDuration() { return duration; }
public synchronized long getDelay() { return delay; }
public synchronized void addDelay(long delayMillis) {
this.delay += delayMillis;
}
public synchronized long getActualStartTime() {
return scheduledTime + delay;
}
public synchronized long getActualEndTime() {
return scheduledTime + delay + duration;
}
}
class TimeInterval {
public final long start;
public final long end;
public final String flightNumber;
public TimeInterval(long start, long end, String flightNumber) {
this.start = start;
this.end = end;
this.flightNumber = flightNumber;
}
}
class Gate {
private final String id;
private final Set<AircraftType> compatibleTypes;
private final List<TimeInterval> schedule = new ArrayList<>();
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public Gate(String id, Set<AircraftType> compatibleTypes) {
this.id = id;
this.compatibleTypes = new HashSet<>(compatibleTypes);
}
public String getId() { return id; }
public boolean isCompatible(AircraftType type) {
return compatibleTypes.contains(type);
}
public boolean hasConflict(long start, long end) {
lock.readLock().lock();
try {
for (TimeInterval interval : schedule) {
if (Math.max(interval.start, start) < Math.min(interval.end, end)) {
return true;
}
}
return false;
} finally {
lock.readLock().unlock();
}
}
public void bookInterval(long start, long end, String flightNumber) {
lock.writeLock().lock();
try {
schedule.add(new TimeInterval(start, end, flightNumber));
} finally {
lock.writeLock().unlock();
}
}
public void removeInterval(String flightNumber) {
lock.writeLock().lock();
try {
schedule.removeIf(ti -> ti.flightNumber.equals(flightNumber));
} finally {
lock.writeLock().unlock();
}
}
public List<TimeInterval> getSchedule() {
lock.readLock().lock();
try {
return new ArrayList<>(schedule);
} finally {
lock.readLock().unlock();
}
}
}
class GateAssignmentService {
private final List<Gate> gates = new ArrayList<>();
private final Map<String, Gate> flightToGateMap = new ConcurrentHashMap<>();
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
public void addGate(Gate gate) {
rwLock.writeLock().lock();
try {
gates.add(gate);
} finally {
rwLock.writeLock().unlock();
}
}
public Gate assignGate(Flight flight, long turnaroundBuffer) throws Exception {
rwLock.writeLock().lock();
try {
long occupationStart = flight.getActualStartTime();
long occupationEnd = flight.getActualEndTime() + turnaroundBuffer;
for (Gate gate : gates) {
if (gate.isCompatible(flight.getAircraftType()) && !gate.hasConflict(occupationStart, occupationEnd)) {
gate.bookInterval(occupationStart, occupationEnd, flight.getFlightNumber());
flightToGateMap.put(flight.getFlightNumber(), gate);
return gate;
}
}
throw new IllegalStateException("No compatible gate available for flight: " + flight.getFlightNumber());
} finally {
rwLock.writeLock().unlock();
}
}
public void handleFlightDelay(Flight flight, long delayMillis, long turnaroundBuffer) throws Exception {
rwLock.writeLock().lock();
try {
Gate gate = flightToGateMap.get(flight.getFlightNumber());
if (gate == null) {
throw new IllegalArgumentException("Flight " + flight.getFlightNumber() + " is not currently assigned to a gate.");
}
// Remove old schedule interval
gate.removeInterval(flight.getFlightNumber());
flight.addDelay(delayMillis);
long newStart = flight.getActualStartTime();
long newEnd = flight.getActualEndTime() + turnaroundBuffer;
// Attempt to keep same gate if conflict free, otherwise migrates
if (!gate.hasConflict(newStart, newEnd)) {
gate.bookInterval(newStart, newEnd, flight.getFlightNumber());
System.out.println("[ATC] Delayed Flight " + flight.getFlightNumber() + " kept original Gate " + gate.getId());
} else {
System.out.println("[ATC] Delayed Flight " + flight.getFlightNumber() + " conflicted with Gate " + gate.getId() + ". Reassigning...");
flightToGateMap.remove(flight.getFlightNumber());
Gate newGate = assignGate(flight, turnaroundBuffer);
System.out.println("[ATC] Migrated Flight " + flight.getFlightNumber() + " to new Gate " + newGate.getId());
}
} finally {
rwLock.writeLock().unlock();
}
}
public Gate getAssignedGate(String flightNumber) {
return flightToGateMap.get(flightNumber);
}
}
public class Main {
public static void main(String[] args) {
System.out.println("=== INITIALIZING AIRPORT MANAGEMENT ===");
GateAssignmentService gas = new GateAssignmentService();
// Register Gates
// G1: Compatible with Medium and Large jets
Gate g1 = new Gate("G1", new HashSet<>(Arrays.asList(AircraftType.MEDIUM, AircraftType.LARGE)));
// G2: Compatible with Medium and Small jets
Gate g2 = new Gate("G2", new HashSet<>(Arrays.asList(AircraftType.SMALL, AircraftType.MEDIUM)));
gas.addGate(g1);
gas.addGate(g2);
long now = System.currentTimeMillis();
long hour = 3600 * 1000;
long buffer = 15 * 60 * 1000; // 15 mins buffer
System.out.println("\\n=== 1. SCHEDULING INITIAL FLIGHTS ===");
Flight f1 = new Flight("AA101", AircraftType.LARGE, now, 2 * hour);
Flight f2 = new Flight("UA202", AircraftType.MEDIUM, now + hour, hour);
try {
Gate assign1 = gas.assignGate(f1, buffer);
System.out.println("Assigned " + f1.getFlightNumber() + " to Gate " + assign1.getId());
Gate assign2 = gas.assignGate(f2, buffer);
System.out.println("Assigned " + f2.getFlightNumber() + " to Gate " + assign2.getId());
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("\\n=== 2. HANDLING CONFLICT WITH DELAY ===");
// Flight AA101 (large, occupying G1 from now to now+2h) is delayed by 1 hour.
// It now occupies from now+1h to now+3h.
// This conflicts with G1 scheduling.
try {
System.out.println("Adding 1 hour delay to Flight AA101...");
gas.handleFlightDelay(f1, hour, buffer);
} catch (Exception e) {
System.out.println("Delay handling failed: " + e.getMessage());
}
}
}