Skip to content

The simulation model

Every stage of model 2.1, with its formulas and a worked example.

This is model 2.1 (engine 2.1.0). Values such as strength, quality and utility are on a z-scale: 0 is average and 1 is one standard deviation above it. The full specification, with every formula and the random-number recipe, is docs/model_spec.md in the project repository.

Applicants and programs

Applicants belong to groups (for example US MD seniors or international graduates), each with its share of the applicants and a normal distribution of latent strength. Programs have a latent quality, optionally in tiers:

ai=μg+σgzi,qj=μt+σqzj′

The number of positions follows from the applicants per position you choose, P=N/applicants per position (rounded), and the positions are spread over the programs so that every program has at least one: evenly, or with right-skewed sizes as in the real Match.

Each applicant has a value for every applicant attribute programs evaluate (for example board_scores), and each program one for every program attribute applicants evaluate (for example reputation). You set how closely each attribute follows overall strength or quality, ρk:

xik=ρkstd(a)i+1−ρk2eik

The attribute program_size is the program's number of positions (on a log scale).

Preferences

Everyone weighs the other side's attributes. You set the average weights; each agent's weights are drawn around them (a Dirichlet distribution), and the weight concentration sets how much they vary.

An applicant's true utility for a program has three parts: a view everyone shares (mostly the program's quality, with some of its average-weighted attributes), Cj; the applicant's personal taste for the program's attributes, Tij; and a random personal fit, εij. Each part has mean 0 and standard deviation 1:

uij=ρCj+1−ρ(τTij+1−τεij)
  • ρ, the agreement, is the average correlation between two applicants' utilities: 1 means everyone ranks programs the same way, 0 that preferences are purely personal.
  • τ is the share of the personal part that comes from attribute taste rather than pure fit.

Programs value applicants the same way, with their own agreement: vji=ρPSi+…

What each side sees before interviews

Before interviews each side sees the other with error:

u^ij=uij+σeij

σ is the noise in utility SD units: 0 is perfect information, 0.5 keeps a correlation of about 0.89 with the truth, since the correlation is 1/1+σ2. Optionally less-known programs and applicants are seen with more error (visibility), and part of the error can be shared by everyone judging the same program or applicant (herding). Each side ranks everyone on the other side by these views; exact ties are broken by seeded random keys.

Applications and signals

Each applicant applies to ki programs: a fixed number, or a number drawn around the mean you set. They choose from their pre-interview ranking: the best ki programs, every program, random ones, or a portfolio of reach, target and safety programs. For the portfolio, each applicant judges their own standing with some error, and a program is a reach if its prestige is above that standing by more than the target band, a safety if it is below by more than the band, and a target otherwise.

Applicants can send preference signals in tiers (for example 3 gold and 5 silver) to programs they applied to: to their favourites, to realistic choices first, or at random. A share of programs read signals.

Invitations

Each program has sj=⌈mcj⌉ interview slots, where cj is its number of positions and m the interviews per position. It screens its applications with a score: its pre-interview view of the applicant, plus the signal's boost when the applicant signalled it and it reads signals, or minus a yield protection penalty for applicants who look too strong for it (who might go elsewhere).

Programs invite in waves: in each wave a program with open slots invites up to 20% more applicants than it has open slots, by screening score (or signalled applicants first, or at random above a threshold, depending on the strategy). Applicants go through their new invitations, the best ones or the first ones first, and accept while they are under their interview cap and the program still has an open slot; otherwise they decline and the slot goes to a later wave.

Interviews

An interview reveals a fit neither side knew about, and shrinks each side's pre-interview error:

uij*=uij+σfitfij,u~ij=uij*+(1−κ)eij

u* is the realised utility, which includes the fit; u~ is the post-interview view. The interview informativeness κ sets how much of the old error disappears: 0 leaves it all, 1 removes it (the applicant then knows u* exactly). Programs are symmetric.

Rank order lists

Applicants rank the programs where they interviewed by their post-interview view: all of them, the top k, those above a reservation utility, or all of them with the ones they are less likely to match moved down (likelihood weighted). Programs rank the applicants they interviewed, leaving out a bottom share (do not rank) or those below a threshold. Applicant lists hold at most 300 programs; applicants with a list take part in the match.

The match

Applicant-proposing deferred acceptance, as the NRMP (see How the Match works), or program-proposing for comparison. Every run checks that the match is stable, respects capacities and lists and, when both proposing sides run, that they match the same applicants and fill each program equally (the rural hospitals theorem). The validation report repeats the checks on hundreds of random markets against an independent solver.

Randomness and reproducibility

Every random draw comes from its own stream, derived from the seed, so the same parameters and seed give exactly the same results, and changing one parameter changes only what depends on it: changing the noise before interviews does not change the applicants or programs; changing interview informativeness does not change who applied or who was invited. Pair-level draws use a counter-based generator, so any pair's values can be recomputed on their own.

A worked example

With the default parameters and seed 42, the engine gives these values for the first applicant and the first program. The sum below is the engine's own utility, not a recomputation.

Applicant 1 and Program 1, default parameters, seed 42
Agreement, ρ0.600
Taste share of the personal part, τ0.500
Common view of the program, C-2.3720
The applicant's taste for it, T-0.1046
Personal fit, ε0.5869
True utility, √ρ·C + √(1−ρ)·(√τ·T + √(1−τ)·ε)-1.6216
Pre-interview error, σ·e (σ = 0.5)-0.1366
Pre-interview view, û = u + σ·e-1.7582