In this vignette, we explore the computational performance of the various algorithms implemented in this package.

Gale-Shapley Algorithm

The computational performance of the Gale-Shapley Algorithm highly depends on how similar agents’ preferences are. When some woman is the most preferred to many men, the algorithm will require a lot more rounds to compute the stable matching than when preferences are completely random. To capture this we will construct preferences that feature a common and an idiosyncratic component. The weight on the common component (“the level of commonality”) is denoted by \(\lambda\). When \(\lambda=1\), all men have identical preferences over all women and vice versa. When \(\lambda=0\), all preferences are completely random.

Preferences for men are then constructed as follows:

# number of men and women, respectively
n = 100
# level of commonality
lambda = 0.5
# men's preferences
uM = lambda * matrix(runif(n), nrow = n, ncol = n) +
    (1 - lambda) * runif(n ^ 2)

The common component matrix(runif(n), nrow = n, ncol = n) is a matrix of dimension n by n that has identical columns. The idiosyncratic component runif(n ^ 2) is a matrix of dimension n by n where each element is a separate draw from a uniform distribution.

Women’s preferences are constructed similarly:

# womens's preferences
uW = lambda * matrix(runif(n), nrow = n, ncol = n) +
    (1 - lambda) * runif(n ^ 2)

We benchmark the matching functions for three different market sizes

# market sizes
N = c(100, 500, 1000)

and three different levels of commonality

# levels of commonality
Commonality = c(0.25, 0.5, 0.75)

The test function is constructed as follows:

set.seed(1)

test_galeShapley.marriageMarket = function(n, lambda) {
    uM = lambda * matrix(runif(n), nrow = n, ncol = n) +
        (1 - lambda) * runif(n ^ 2)
    uW = lambda * matrix(runif(n), nrow = n, ncol = n) +
        (1 - lambda) * runif(n ^ 2)
    galeShapley.marriageMarket(uM, uW)
}

In this example, there are equal numbers of men and women, so everyone will get matched. Note that we are benchmarking the generation of preferences and the computation of the stable matching jointly.

Run time (in seconds) for the matching of men to women
lambda=0.25 lambda=0.50 lambda=0.75
N=100 0.002014 0.001986 0.002199
N=500 0.043580 0.046021 0.052397
N=1,000 0.210000 0.208197 0.240806

Irving’s Algorithm

In the roommate problem, existence of a stable matching is not guaranteed, and indeed for large markets, can be very likely to not exist. Therefore, there are two relevant measures of speed to be considered: First, the average time to find a stable matching or to verify that no stable matching exists, and second, the average time to find a stable matching, conditional on such a matching existing.

The code to find a stable matching, from the documentation, is

u = matrix(rnorm(16), nrow = 4)
results = roommate(utils = u)

The function we use to benchmark is

test_roommate = function(n) {
    roommate(utils = matrix(rnorm( 4 * n ^ 2 ), nrow = 2 * n))
}

That is, \(n\) represents the number of rooms available.

Proportion of matchings which exist and run time (in seconds) for the stable roommate algorithm.
No. of instances No. with solution Proportion with solution Proportion with solution (Irving 1985) Average cpu time
N=2 50 47 0.94 0.961 0.000712
N=3 50 46 0.92 0.931 0.001880
N=4 50 40 0.80 0.909 0.001306
N=5 50 41 0.82 0.868 0.001608
N=6 50 45 0.90 0.871 0.001872
N=7 50 40 0.80 0.867 0.003647
N=8 50 41 0.82 0.857 0.004880
N=9 50 45 0.90 0.830 0.002625
N=10 50 38 0.76 0.815 0.005228
N=11 50 40 0.80 0.808 0.004494
N=12 50 42 0.84 0.816 0.004135
N=13 50 41 0.82 0.788 0.004533
N=14 50 45 0.90 0.750 0.005729
N=15 50 41 0.82 0.766 0.014417
N=16 50 38 0.76 0.755 0.009636
N=17 50 36 0.72 0.770 0.008181
N=18 50 36 0.72 0.740 0.006062
N=19 50 35 0.70 0.725 0.014277
N=20 50 38 0.76 0.745 0.011697

Top Trading Cycle Algorithm

The code to find a stable matching using the top trading cycle algorithm is

u = matrix(rnorm(16), nrow = 4)
results = toptrading(utils = u)

The function we use to benchmark is

test_toptrading = function(n) {
    toptrading(utils = matrix(rnorm( n ^ 2 ), nrow = n))
}

so that n represents the number of agents in the market.

Run time (in s) for top trading cycle algorithm
Average cpu time
N=2 0.000151
N=4 0.000230
N=8 0.000152
N=16 0.000292
N=32 0.000268
N=64 0.000685
N=128 0.002667
N=256 0.013259
N=512 0.062924
N=1,024 0.224553