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:
The number of positions follows from the applicants per position you choose, (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, :
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), ; the applicant's personal taste for the program's attributes, ; and a random personal fit, . Each part has mean 0 and standard deviation 1:
- , 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:
What each side sees before interviews
Before interviews each side sees the other with error:
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 . 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 programs: a fixed number, or a number drawn around the mean you set. They choose from their pre-interview ranking: the best 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 interview slots, where is its number of positions and 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:
is the realised utility, which includes the fit; 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 exactly). Programs are symmetric.
Rank order lists
Applicants rank the programs where they interviewed by their post-interview view: all of them, the top , 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.
| 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 |