Monte Carlo simulation of airline overbooking
Airlines overbook flights to maximize profits.
Consider a flight with seats for 100 passengers.
If the airline allows only up to 100 reservations for the flight, each customer will be guarenteed a seat on the plane. However, several seats will likely be empty because a fraction of the customers that reserve a seat will likely miss the flight. For each empty seat, the airline looses revenue.
If the airline allows greater than 100 reservations– i.e. if the airline overbooks the flight– it is more likely that enough customers show up to fill the plane so that the airline receives revenue from each seat on the airplane. However, if more than 100 customers that reserved a flight show up, then (i) customers bumped from the flight will be angry and not fly with that airline again and (ii) the airline must pay out vouchers to incentivize volunteers to take a different flight. This is costly.
Clearly, there is a delicate balance of how much to overbook. Don’t overbook at all: all customers are happy, but flights operate below full capacity and we lose out on revenue. Overbook too much: flights are likely operating near full capacity so we receive revenue from each seat, but customers bumped from the flight are angry and costly vouchers must be paid to volunteers.
We wrote a code in the Julia programming language to simulate the process of customers showing up to flights and identify the optimal amount to overbook.
As input, we need the probability that a given customer shows up to the flight after making a reservation.
probability_show = 0.935
show_up simulates the stochastic process of a customer showing up for the flight after making a reservation.
function show_up(probability_show::Float64) if rand() <= probability_show return true # passenger showed up else return false # passenger didn't show up end end
simulate_flight simulates the stochastic process of
nb_tickets_sold reservations made for a flight and returns the number of customers that show up.
function simulate_flight(nb_tickets_sold::Int64, probability_show::Float64) n = 0 # number of folks who bought tix that will show up for i = 1:nb_tickets_sold if show_up(probability_show) n = n + 1 end end return n end
The revenue received from a flight will depend on the number of reservations made (
nb_tickets_sold), number of seats on the plane (
nb_seats), the probability that a given customer shows up (
probability_show), the revenue received per seat (
revenue_per_seat), and the cost of a voucher to incentivize volunteers to take a different flight when the plane is overbooked, (
voucher_cost). The latter may include the implicit cost of losing customers to different airlines after angering them. The function
simulate_net_revenuesimulates the stochastic process and returns the net revenue from the flight.
function simulate_net_revenue(nb_tickets_sold::Int64, nb_seats::Int, probability_show::Float64, revenue_per_seat::Float64, voucher_cost::Float64) # how many ticket purchasers actually showed up? nb_shows = simulate_flight(nb_tickets_sold, probability_show) # no one bumped from flight if less or equal folks show up than for # the number of seats we have if nb_shows <= nb_seats return revenue_per_seat * nb_shows # if more customers show up than seats we hv, must pay out vouchers else vouchers_out = nb_shows - nb_seats return nb_seats * revenue_per_seat - voucher_cost * vouchers_out end end
For a $350 flight on a plane of 100 seats, where vouchers are twice the cost of the ticket:
nb_seats = 100 revenue_per_seat = 350.0 # USD voucher_cost = revenue_per_seat * 2.0 # USD
We now simulate the process of different amounts of overbooking to identify the optimal amount of overbooking. Since this is a stochastic process, we run 10,000 simulations to simulate 10,000 flights so we can calculate the average net revenue for each amount of overbooking and gauge the variance among flights.
nb_flights = 10000 max_overbooking = 15 # revenue[i, k] is net revenue received from flight i with k-1 tickets over capacity sold revenue = zeros(nb_flights, max_overbooking + 1) for tix_overbooked = 0:max_overbooking nb_tickets_sold = nb_seats + tix_overbooked for f = 1:nb_flights # simulate nb_flights flights revenue[f, tix_overbooked + 1] = simulate_net_revenue(nb_tickets_sold, nb_seats, probability_show, revenue_per_seat, voucher_cost) end end
We depict the results using a box plot for each amount of overbooking:
using PyPlot boxplot(revenue, labels=0:max_overbooking) xlabel("# tickets sold beyond capacity") ylabel("net revenue")
The box plot shows that, if we do not overbook (0 on the x-axis), we on average receive less net revenue than if we do overbook. If we overbook too much, e.g. sell 15 tickets beyond capacity, we see that the average net revenue is less than if we overbook because we are paying out costly vouchers. The optimal amount of overbooking with these parameters is shown by the box plot to be 5-7 tickets beyond capacity. Of course, this result depends on the probability that a customer will show up, the cost of the flight and voucher, and number of seats on the plane.
Note: airlines hire analysts to do exactly this. See this NYT article.
This code was developed by Mira Khare, Melanie Huynh, Arni Sturluson, and two high school students for the Summer Experience in Science and Engineering for Youth (SESEY) at Oregon State University.