The Taylor Swift Algorithm is a simplified simulation of a ticket purchasing process that suggests an alternative model to fairness away from a First-Come-First-Served concept
-
Inspired by my own attempts to buy Taylor Swift tickets for the Singapore Eras Tour via Ticketmaster, I found the Ticket Allocation system to be rather compelling and an interesting alternative to First-Come-First-Served. So I wanted to do a reverse-engineering over a simplified model
-
The way Ticketmaster handled the sales is described below:
- Ticket sales open at a particular time,
t_sale
- If a user enters the Ticketmaster page at the current time,
t_curr
such thatt_curr < t_sale
, they are put into a Waiting Room. Users are only put into the Waiting Room if they arrive att_curr < t_sale
- When
t_curr > t_sale
, users from the Waiting Room can enter the payment service. Those who arrived at timet_curr > t_sale
don't have to go to a Waiting Room but realistically they won't have a shot of buying tickets because of the SHEER number of people who came in early - To ensure some semblance of fair balloting, each user that enters the payment service are put into a holding queue where their queue numbers are randomised and this determines the order of who can make payments for tickets
-
There are some interesting merits in such a protocol - one of which is that it somewhat eliminates "Fastest Fingers First", especially when the difference in entry time between users can go as small as nanoseconds, and those who enter at batches similar times (within an acceptable range) have a fair shot at getting the ticket WITHIN their timing batch
-
Realistically for the Eras Tour, for the set of people in the Waiting Room
W
BEFORE sale timet_sale
, and the set of ticketsT
, it was clear to me that|W| > |T|
so in that case the algorithm is straightforward - shuffle the order of everyone from the Waiting Room as they are transitioned into the holding queue. -
However, what was interesting to me was this scenario: If instead
|W| < |T|
(i.e. less people in the Waiting Room than tickets available, remember the Waiting Room is only for people who arrive att_curr < t_sale
) BUT there are more users coming in to buy and they arrive att_curr > t_sale
, how would a Ticket Allocation algorithm handle their queue positions? If we're randomising queue numbers within people of the same arrival time batch, surely we must be careful not to displace those who arrived at an earlier time batch?
To simplify the model, we make these following assumptions:
-
For the set of Users,
U
attempting to purchase from a set of ticketsT
, we assume|U| > |T|
. In other words, there are more users trying to buy tickets than actual tickets available -
We define a function
f: U -> T
such that for each useru ∈ U
,f(u) = t
, wheret ∈ T
. The functionf
represents the process of a user buying a ticket. In other words, we want to ensure that each user can only buy one ticket, meaning the functionf
is well-defined and each user is mapped to a unique ticket. It is worth revisiting this assumption and explore how the algorithm changes if users can buy several tickets -
When a user attempts to pay for the ticket, they are successful. Again, this is worth revisiting in a future iteration of the project.
-
Time is defined as a discrete variable
- Let
U
denote the set of all users. - Let
T
denote the set of all tickets. - Let
t(u)
denote the time when user u arrives. - Let
p(u)
denote the ticket purchase attempt by user u. - Let
q(u)
denote the queue position of user u.
-
Progress: For
∀t ∈ T
, if|U| ≥ |T|
,∃u ∈ U
such that the ticket purchasep(u)
for the tickett
is successful. In simpler terms, if the number of users is greater than or equal to the number of tickets, every ticket will eventually be sold. -
Mutual Exclusion: For
∀t ∈ T
and for every pair of users{u, v} ∈ U
, if useru
is in the process of a ticket purchasep(u)
for the tickett
, then no other userv
can initiate a ticket purchasep(v)
for the tickett
. In simpler terms, only one user can attempt to purchase a specific ticket at a given time. -
No Starvation: For
∀u ∈ U
and any tickett ∈ T
, if useru
is willing to purchase a ticket and tickets are available (|U| > |T|
), there exists a timet'
such that for allt'' > t'
, useru
will have been given an opportunity to purchase a ticket. In simpler terms, if tickets are available and a user wants to purchase a ticket, then that user will eventually be given an opportunity to make a purchase. -
Fairness: For any two users
{u, v} ∈ U
, wheret(u) = t(v)
, the absolute difference betweenq(u)
andq(v)
should be within an acceptable ranger
. Formally,t(u) = t(v) → |q(u) - q(v)| <= r
. This means if two users arrive at the same time, their positions in the queue shouldn't be too far apart, where the definition of "too far" is determined by the acceptable ranger
.
Proofs are outlined in this article
The project is structured into several Java classes, each encapsulating a part of the system:
User.java
: Represents a user in the systemTicket.java
: Represents a ticket that a user can purchase.WaitingRoomService.java
: Manages the waiting room where users are stored before they can purchase tickets.QueueManagerService.java
: Manages the queue of users waiting to purchase tickets.QueueService.java
: Processes the queue of users and attempts to let each user purchase a ticket.TicketingSystem.java
: The main class that combines all services and runs the simulation.App.java
: The entry point of the application.
Have Java 8 or later installed on your machine.
-
Clone the repo
git clone https://github.com/nicholas-gcc/taylor-swift-algorithm.git
-
Compile the project
javac -d bin src/main/ticketing/system/*.java src/main/ticketing/system/**/*.java
This command compiles all the Java files in the specified directories and saves the compiled bytecode files in the bin directory.
-
Run the entry point of the application
java -cp bin ticketing.system.App
This project is open for improvements and bugfixes. Feel free to submit a pull request or open an issue.