Return to JUNTO

JUNTO Practice: Probability, Airplane Seats

Discussed on May 19, 2020.

From "Twenty problems in probability":

One hundred people line up to board an airplane. Each has a boarding pass with assigned seat. However, the first person to board has lost his boarding pass and takes a random seat. After that, each person takes the assigned seat if it is unoccupied, and one of unoccupied seats at random otherwise. What is the probability that the last person to board gets to sit in his assigned seat?

Please provide an answer and a justification.

Solutions

Click to see:

Oscar Martinez

#!/usr/bin/env python

import numpy as np
import random


def simulate_passengers(n_passengers):
    passengers = [p for p in range(n_passengers)]
    seats = [None] * 100
    seats[np.random.randint(low=0, high=100)] = 0
    for assignment, passenger in enumerate(passengers[1:]):
        if seats[assignment] is not None:
            available_seats = [
                i for i, o in enumerate(seats) if o is None
            ]
            random_seat = random.choice(available_seats)
            seats[random_seat] = passenger
        elif seats[assignment] is None:
            seats[assignment] = passenger

    passenger_n_got_seat = (
        1
        if seats[n_passengers - 1] == n_passengers - 1
        else 0
    )

    return passenger_n_got_seat


np.mean([simulate_passengers(100) for _ in range(10000)])
0.5047

John Lekberg

I think the probability that the last person to board gets to sit in their assigned seat is about 50%.

import random
import statistics


def random_last_gets_seat():
    """Sample the boolean random variable, 'the
    last person to board gets to sit in their assigned seat'.
    """
    N = 100

    taken = [False] * N

    # First person takes a random seat.
    taken[random.randrange(N)] = True

    for passenger in range(1, N - 1):
        # passenger i is assigned to seat i
        assignment = passenger
        if taken[assignment]:
            remaining = [
                seat
                for seat, is_taken in enumerate(taken)
                if not is_taken
            ]
            assignment = random.choice(remaining)
        taken[assignment] = True

    last_passenger_assigned_seat = N - 1
    return taken[last_passenger_assigned_seat]


sample = [random_last_gets_seat() for _ in range(10000)]
statistics.mean(sample)
0.5075

Daniel Bassett

Answer: 0.4984.

import random
import collections


class Person(object):
    def __init__(self, assigned, rank):
        self.assigned = assigned
        self.rank = rank
        self.seat = None

    def __repr__(self):
        return (
            "Person: assigned: %s, rank: %s, seat: %s"
            % (self.assigned, self.rank, self.seat)
        )


def random_seat(seats):
    (seat,) = random.sample(seats, 1)
    new_seats = seats - set([seat])
    return (seat, new_seats)


def make_persons(n=100):
    tickets = [i for i in range(1, n + 1)]
    random.shuffle(tickets)
    return [
        Person(ticket, rank + 1)
        for rank, ticket in enumerate(tickets)
    ]


def simulate(persons):
    n = len(persons)
    seats = set([i for i in range(1, n + 1)])
    for index, person in enumerate(persons):
        if person.rank == 1:
            person.seat, seats = random_seat(seats)
        else:
            if person.assigned in seats:
                person.seat = person.assigned
                seats = seats - set([person.seat])
            else:
                person.seat, seats = random_seat(seats)
    last_person = persons[-1]
    return last_person.seat == last_person.assigned


def main():
    times = 10000
    size = 100
    count = collections.Counter()
    for i in range(0, times):
        persons = make_persons(size)
        result = simulate(persons)
        count[result] += 1
    print(count[False] * 1.0 / times)


if __name__ == "__main__":
    main()