diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..aeebc23 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,21 @@ +repos: + - repo: https://github.com/Quantco/pre-commit-mirrors-prettier + rev: 3.2.5 + hooks: + - id: prettier-conda + files: \.(md|yml|yaml)$ + - repo: https://github.com/Quantco/pre-commit-mirrors-pre-commit-hooks + rev: 4.6.0 + hooks: + - id: trailing-whitespace-conda + - id: end-of-file-fixer-conda + - id: check-merge-conflict-conda + args: ["--assume-in-merge"] + - repo: https://github.com/Quantco/pre-commit-mirrors-typos + rev: 1.24.5 + hooks: + - id: typos-conda + - repo: https://github.com/Quantco/pre-commit-mirrors-clang-format + rev: 18.1.8 + hooks: + - id: clang-format-conda diff --git a/NEWS.md b/NEWS.md index e2a56a5..cb09bf1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,69 +1,68 @@ # matchingR 1.3.3 - * Fixed unit test for validate functions that caused a CRAN check to fail. +- Fixed unit test for validate functions that caused a CRAN check to fail. # matchingR 1.3.2 - * Fix vignette index. +- Fix vignette index. # matchingR 1.3.1 - * Add dummy roommate when number of roommates is odd [#37](https://github.com/jtilly/matchingR/issues/37) - * Run code base through `styler` and `lintr` +- Add dummy roommate when number of roommates is odd [#37](https://github.com/jtilly/matchingR/issues/37) +- Run code base through `styler` and `lintr` # matchingR 1.3.0 - * Allow colleges to have different numbers of slots [#31](https://github.com/jtilly/matchingR/issues/31) - * Change row names in vignette [#34](https://github.com/jtilly/matchingR/issues/34) - * Remove need for microbenchmark package [#35](https://github.com/jtilly/matchingR/issues/35) - * Registration of entry points in compiled code +- Allow colleges to have different numbers of slots [#31](https://github.com/jtilly/matchingR/issues/31) +- Change row names in vignette [#34](https://github.com/jtilly/matchingR/issues/34) +- Remove need for microbenchmark package [#35](https://github.com/jtilly/matchingR/issues/35) +- Registration of entry points in compiled code # matchingR 1.2.2 -This is a minor update. +This is a minor update. - * Colleges may have different numbers of slots in the college admissions problem ([#30](https://github.com/jtilly/matchingR/issues/30)) +- Colleges may have different numbers of slots in the college admissions problem ([#30](https://github.com/jtilly/matchingR/issues/30)) # matchingR 1.2.1 -This is a minor update. +This is a minor update. - * Fixed bug in galeShapley.checkStability that resulted in UBSAN throwing an error +- Fixed bug in galeShapley.checkStability that resulted in UBSAN throwing an error # matchingR 1.2 - * Fixed a bug in the stable roommate matching algorithm that caused - problems on Mac OS X / clang - * Changed function names throughout the package (deprecated old function names) - * Updated documentation - * Added tests - * Removed option to define preferences in row major order +- Fixed a bug in the stable roommate matching algorithm that caused + problems on Mac OS X / clang +- Changed function names throughout the package (deprecated old function names) +- Updated documentation +- Added tests +- Removed option to define preferences in row major order # matchingR 1.1.1 -This is a minor update. - - * It fixes a memory leak warning in the stable roommate algorithm. - * It includes minor edits of the vignettes and documentation. - * We have substantially shortened the computational performance vignette - so that the package can be built and checked faster +This is a minor update. +- It fixes a memory leak warning in the stable roommate algorithm. +- It includes minor edits of the vignettes and documentation. +- We have substantially shortened the computational performance vignette + so that the package can be built and checked faster # matchingR 1.1 This is a major update that added additional algorithms to the package. - * Added algorithm to compute a solution to the stable roommate problem - (`roommate`) - * Added top trading cycle algorithm (`toptrading`) - * Switched the layout of preference matrices from row order to column order - to make the code faster - * Added two vignettes: An introductory vignette to the package in general - and a computational performance vignette +- Added algorithm to compute a solution to the stable roommate problem + (`roommate`) +- Added top trading cycle algorithm (`toptrading`) +- Switched the layout of preference matrices from row order to column order + to make the code faster +- Added two vignettes: An introductory vignette to the package in general + and a computational performance vignette # matchingR 1.0.1 Initial release that computes two versions of the Gale-Shapley algorithm: - - * Stable Marriage Problem - * College Admissions Problem + +- Stable Marriage Problem +- College Admissions Problem diff --git a/R/RcppExports.R b/R/RcppExports.R index 2a9066f..064b32a 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -74,7 +74,7 @@ cpp_wrapper_galeshapley_check_stability <- function(proposerUtils, reviewerUtils #' This is the C++ wrapper for the stable roommate problem. Users should not #' call this function directly, but instead use #' \code{\link{roommate}}. -#' +#' #' @param pref is a matrix with the preference order of each individual in the #' market. If there are \code{n} individuals, then this matrix will be of #' dimension \code{n-1} by \code{n}. The \code{i,j}th element refers to @@ -115,7 +115,7 @@ cpp_wrapper_irving_check_stability <- function(pref, matchings) { } #' Computes the top trading cycle algorithm -#' +#' #' This is the C++ wrapper for the top trading cycle algorithm. Users should not #' call this function directly, but instead use #' \code{\link{toptrading}}. @@ -195,4 +195,3 @@ sortIndexOneSided <- function(u) { rankIndex <- function(sortedIdx) { .Call('_matchingR_rankIndex', PACKAGE = 'matchingR', sortedIdx) } - diff --git a/README.md b/README.md index 855bf8a..622732e 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,36 @@ -Matching Algorithms in R and C++ -=============== +# Matching Algorithms in R and C++ + [![GitHub Actions](https://github.com/jtilly/matchingR/workflows/Test%20Package/badge.svg)](https://github.com/jtilly/matchingR/actions) [![Coverage Status](https://coveralls.io/repos/jtilly/matchingR/badge.svg?branch=master)](https://coveralls.io/github/jtilly/matchingR) [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/matchingR)](https://cran.r-project.org/package=matchingR) [![CRAN_Downloads](https://cranlogs.r-pkg.org/badges/grand-total/matchingR?color=brightgreen)](https://cran.r-project.org/package=matchingR) - [!["You know that I'll never leave you. Not as long as she's with someone."](https://imgs.xkcd.com/comics/all_the_girls.png)](https://xkcd.com/770/ "You know that I'll never leave you. Not as long as she's with someone.") - `matchingR` is an R package which quickly computes the [Gale-Shapley algorithm](https://www.jstor.org/stable/2312726), [Irving's algorithm for the stable roommate problem](https://www.sciencedirect.com/science/article/pii/0196677485900331/), and the [top trading cycle algorithm](https://www.sciencedirect.com/science/article/abs/pii/0304406874900330/) for large matching markets. The package provides functions to compute the solutions to the - [stable marriage problem](https://en.wikipedia.org/wiki/Stable_matching), the - [college admission problem](https://en.wikipedia.org/wiki/Hospital_resident), the - [stable roommates problem](https://en.wikipedia.org/wiki/Stable_roommates_problem), and the - [house allocation problem](https://web.stanford.edu/~niederle/HouseAllocation.pdf). +[stable marriage problem](https://en.wikipedia.org/wiki/Stable_matching), the +[college admission problem](https://en.wikipedia.org/wiki/Hospital_resident), the +[stable roommates problem](https://en.wikipedia.org/wiki/Stable_roommates_problem), and the +[house allocation problem](https://web.stanford.edu/~niederle/HouseAllocation.pdf). The package may be useful when the number of market participants is large or when many matchings need to be computed (e.g., for simulation or estimation purposes). It has been used in practice to compute the Gale-Shapley stable matching with 30,000 participants on each side of the market. Matching markets are common in practice and widely studied by economists. Popular examples include - * the [National Resident Matching Program](https://www.nrmp.org/) which matches graduates from medical school to residency programs at teaching hospitals throughout the United States - * the matching of students to schools including the [New York City High School Match](https://www.jstor.org/stable/4132848) or the [Boston Public School Match](https://www.jstor.org/stable/4132849) (and many more) - * the matching of kidney donors to recipients in [kidney exchanges](https://www.jstor.org/stable/4132851). +- the [National Resident Matching Program](https://www.nrmp.org/) which matches graduates from medical school to residency programs at teaching hospitals throughout the United States +- the matching of students to schools including the [New York City High School Match](https://www.jstor.org/stable/4132848) or the [Boston Public School Match](https://www.jstor.org/stable/4132849) (and many more) +- the matching of kidney donors to recipients in [kidney exchanges](https://www.jstor.org/stable/4132851). -Installation ------------- +## Installation `matchingR` may be installed from [CRAN](https://cran.r-project.org/package=matchingR): + ```r install.packages("matchingR") ``` + The latest development release is available from GitHub: + ```r devtools::install_github("jtilly/matchingR") ``` @@ -40,6 +40,7 @@ devtools::install_github("jtilly/matchingR") ### Gale-Shapley Algorithm for Two-Sided Markets **Stable Marriage Problem** + ```r library(matchingR) @@ -63,6 +64,7 @@ galeShapley.checkStability(uM, uW, matching$proposals, matching$engagements) ``` **College Admissions Problem** + ```r library(matchingR) @@ -100,6 +102,7 @@ galeShapley.checkStability(uStudents, uColleges, matching$matched.students, matc ``` ### Irving's Algorithm for the Stable Roommate Problem + ```r library(matchingR) @@ -123,6 +126,7 @@ results ``` ### Top-Trading Cycle Algorithm + ```r library(matchingR) @@ -146,5 +150,6 @@ results ``` ## Documentation -* [Reference Manual](https://jtilly.io/matchingR/matchingR.pdf "Matching Algorithms in R and C++: Reference Manual") -* [Vignette: Matching Algorithms in R and C++: An Introduction to matchingR](https://jtilly.io/matchingR/vignettes/matchingR-intro.html "Matching Algorithms in R and C++: An Introduction to matchingR") + +- [Reference Manual](https://jtilly.io/matchingR/matchingR.pdf "Matching Algorithms in R and C++: Reference Manual") +- [Vignette: Matching Algorithms in R and C++: An Introduction to matchingR](https://jtilly.io/matchingR/vignettes/matchingR-intro.html "Matching Algorithms in R and C++: An Introduction to matchingR") diff --git a/man/matchingR-deprecated.Rd b/man/matchingR-deprecated.Rd index beef726..84b0dde 100644 --- a/man/matchingR-deprecated.Rd +++ b/man/matchingR-deprecated.Rd @@ -47,4 +47,3 @@ the matchingR package. Eventually, these functions will be removed. \code{checkStabilityTopTradingCycle} \tab was replaced by \code{\link{cpp_wrapper_ttc_check_stability}}\cr } } - diff --git a/src/Makevars b/src/Makevars index cf70727..3f5a1b1 100644 --- a/src/Makevars +++ b/src/Makevars @@ -1,4 +1,4 @@ CXX_STD = CXX11 PKG_CPPFLAGS = -I../inst/include PKG_CXXFLAGS = $(SHLIB_OPENMP_CXXFLAGS) -PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) \ No newline at end of file +PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) diff --git a/src/galeshapley.cpp b/src/galeshapley.cpp index 87f0d61..d1ed299 100644 --- a/src/galeshapley.cpp +++ b/src/galeshapley.cpp @@ -60,24 +60,24 @@ List cpp_wrapper_galeshapley(const umat& proposerPref, const mat& reviewerUtils) // number of proposers (men) int M = proposerPref.n_cols; - + // number of reviewers (women) int N = proposerPref.n_rows; - + // initialize engagements, proposals vec engagements(N), proposals(M); - - // create an integer queue of bachelors + + // create an integer queue of bachelors // the idea of using queues for this problem is borrowed from // http://rosettacode.org/wiki/Stable_marriage_problem#C.2B.2B queue bachelors; - + // set all proposals to N (aka no proposals) proposals.fill(N); - + // set all engagements to M (aka no engagements) engagements.fill(M); - + // every proposer starts out as a bachelor for(int iX=M-1; iX >= 0; iX--) { bachelors.push(iX); @@ -85,49 +85,49 @@ List cpp_wrapper_galeshapley(const umat& proposerPref, const mat& reviewerUtils) // loop until there are no more proposals to be made while (!bachelors.empty()) { - + // get the index of the proposer int proposer = bachelors.front(); - - // get the proposer's preferences: we use a raw pointer to the memory + + // get the proposer's preferences: we use a raw pointer to the memory // used by the column `proposer` for performance reasons (this is to avoid // making a copy of the proposers vector of preferences) const uword * proposerPrefcol = proposerPref.colptr(proposer); - + // find the best available match for proposer for(int jX=0; jX reviewerUtils(engagements(wX), wX)) { - + // wX's previous partner becomes unmatched (`N` means unmatched) proposals(engagements(wX)) = N; bachelors.push(engagements(wX)); - + // proposer and wX form a match engagements(wX) = proposer; proposals(proposer) = wX; - + // go to the next proposer break; } } - + // remove proposer from bachelor queue: proposer will remain unmatched bachelors.pop(); } @@ -171,13 +171,13 @@ bool cpp_wrapper_galeshapley_check_stability(mat proposerUtils, mat reviewerUtil // number of workers const int M = proposerUtils.n_cols; - + // number of firms const int N = proposerUtils.n_rows; - + // number of slots per firm const int slotsReviewers = engagements.n_cols; - + // number of slots per worker const int slotsProposers = proposals.n_cols; @@ -191,19 +191,19 @@ bool cpp_wrapper_galeshapley_check_stability(mat proposerUtils, mat reviewerUtil proposerUtils.insert_rows(N, 1); proposerUtils.row(N).fill(-1e10); } - + // loop over workers for(int wX=0; wX reviewerUtils(engagements(fX, sfX), fX) && proposerUtils(fX, wX) > proposerUtils(proposals(wX, swX), wX)) { ::Rf_warning("matching is not stable; worker %d would rather be matched to firm %d and vice versa.\n", wX, fX); diff --git a/src/roommate.cpp b/src/roommate.cpp index ff42e13..3f8c5a9 100644 --- a/src/roommate.cpp +++ b/src/roommate.cpp @@ -24,7 +24,7 @@ //' This is the C++ wrapper for the stable roommate problem. Users should not //' call this function directly, but instead use //' \code{\link{roommate}}. -//' +//' //' @param pref is a matrix with the preference order of each individual in the //' market. If there are \code{n} individuals, then this matrix will be of //' dimension \code{n-1} by \code{n}. The \code{i,j}th element refers to diff --git a/src/toptradingcycle.cpp b/src/toptradingcycle.cpp index 24af99e..24faece 100644 --- a/src/toptradingcycle.cpp +++ b/src/toptradingcycle.cpp @@ -20,7 +20,7 @@ // [[Rcpp::depends(RcppArmadillo)]] //' Computes the top trading cycle algorithm -//' +//' //' This is the C++ wrapper for the top trading cycle algorithm. Users should not //' call this function directly, but instead use //' \code{\link{toptrading}}. diff --git a/vignettes/bibliography.bib b/vignettes/bibliography.bib index 0db3358..3eaf64c 100644 --- a/vignettes/bibliography.bib +++ b/vignettes/bibliography.bib @@ -28,4 +28,4 @@ @article{shapley1973cores number={1}, pages={23--37}, year={1973} -} \ No newline at end of file +} diff --git a/vignettes/matchingR-intro.Rmd b/vignettes/matchingR-intro.Rmd index 288adeb..c6c487d 100644 --- a/vignettes/matchingR-intro.Rmd +++ b/vignettes/matchingR-intro.Rmd @@ -18,7 +18,7 @@ library(matchingR) [college admission problem](https://en.wikipedia.org/wiki/Hospital_resident), the [stable roommates problem](https://en.wikipedia.org/wiki/Stable_roommates_problem), and the [house allocation problem](https://web.stanford.edu/~niederle/HouseAllocation.pdf). - + The package may be useful when the number of market participants is large or when many matchings need to be computed (e.g., for simulation or estimation purposes). It has been used in practice to compute the Gale-Shapley stable matching with 30,000 participants on each side of the market. Matching markets are common in practice and widely studied by economists. Popular examples include @@ -29,9 +29,9 @@ Matching markets are common in practice and widely studied by economists. Popula # Two-sided Matching Markets: Gale-Shapley Algorithm -Consider the following marriage market: There are `N` men and `N` women. Each man, `m`, receives utility `uM(w, m)` from a match with woman `w`, and similarly each woman receives a payoff of `uW(m, w)` from being matched with a man. +Consider the following marriage market: There are `N` men and `N` women. Each man, `m`, receives utility `uM(w, m)` from a match with woman `w`, and similarly each woman receives a payoff of `uW(m, w)` from being matched with a man. -A matching assigns men to women such that each man is assigned to one woman and each woman is assigned to one man. A matching is **stable** if there is no man and woman who would jointly prefer to be matched to each other over their current spouses. In other words, a matching is stable if there are no pairs `(m, w'), (m', w)`, such that `m` is matched with `w'`, `m'` is matched with `w`, and both `uW(m, w) > uW(m', w)` and `uM(m, w) > uM(m, w')`. +A matching assigns men to women such that each man is assigned to one woman and each woman is assigned to one man. A matching is **stable** if there is no man and woman who would jointly prefer to be matched to each other over their current spouses. In other words, a matching is stable if there are no pairs `(m, w'), (m', w)`, such that `m` is matched with `w'`, `m'` is matched with `w`, and both `uW(m, w) > uW(m', w)` and `uM(m, w) > uM(m, w')`. For example, we might have preferences for men given by ```{r} @@ -77,7 +77,7 @@ prefW ``` The matching algorithm discussed below can take either payoff matrices of the type `uM` and `uW` or preference orderings of the type `prefM` and `prefW` as arguments. -The Gale-Shapley algorithm works as follows: Single men ("the proposers") sequentially make proposals to each of their most preferred available women ("the reviewers"). A woman can hold on to at most one proposal at a time. A *single* woman will accept any proposal that is made to her. A woman who already has a proposal will reject any proposal she values less than her current proposal in hand. If a woman receives a proposal from a man that she values more than her current proposal, she will accept the proposal and her previous match will rejoin the line of proposers. This process continues until all men are matched to all women. +The Gale-Shapley algorithm works as follows: Single men ("the proposers") sequentially make proposals to each of their most preferred available women ("the reviewers"). A woman can hold on to at most one proposal at a time. A *single* woman will accept any proposal that is made to her. A woman who already has a proposal will reject any proposal she values less than her current proposal in hand. If a woman receives a proposal from a man that she values more than her current proposal, she will accept the proposal and her previous match will rejoin the line of proposers. This process continues until all men are matched to all women. For the preferences specified in `uM` and `uW`, we can compute the Gale-Shapley Algorithm by hand. Initially, all men are single. @@ -166,7 +166,7 @@ galeShapley.checkStability(uW, uM, resultsW$proposals, resultsW$engagements) ``` ### Example: College Admissions Problem -The following is an example of `galeShapley.collegeAdmissions` where 1000 students get matched to 400 colleges, where each college has two slots. By construction, 200 students will remain unmatched. We draw students' and colleges' preferences, `uStudents` and `uColleges`, respectively, by from a uniform distribution. +The following is an example of `galeShapley.collegeAdmissions` where 1000 students get matched to 400 colleges, where each college has two slots. By construction, 200 students will remain unmatched. We draw students' and colleges' preferences, `uStudents` and `uColleges`, respectively, by from a uniform distribution. ```{r} # set seed set.seed(1) @@ -190,7 +190,7 @@ This package implements the algorithm by @irving1985roommates for one-sided matc Consider the following example: A set of `n` potential roommates, each with ranked preferences over all the other potential roommates, are to be matched to rooms, two roommates per room. A matching is **stable** if there is no roommate `r1` that would rather be matched to some other roommate `d2` than to his current roommate `r2` and the other roommate `d2` would rather be matched to `r1` than to his current roommate `d1`. -Preferences of potential roommates are summarized by an $n-1 \times n$ dimensional matrix, e.g., if $n = 6$, +Preferences of potential roommates are summarized by an $n-1 \times n$ dimensional matrix, e.g., if $n = 6$, ```{r} pref = matrix(c(3, 6, 2, 5, 3, 5, 4, 5, 4, 2, 1, 1, @@ -207,7 +207,7 @@ roommate.checkPreferences(pref) The algorithm proceeds in two phases. -In phase 1, potential roommates take turns sequentially proposing to the other roommates. Each roommate who is proposed to can accept or reject the proposal. A roommate accepts if he currently has made no better proposal which was accepted to another roommate. If a roommate has accepted a proposal, and then receives a better proposal, he rejects the old proposal and substitutes in the new proposal. +In phase 1, potential roommates take turns sequentially proposing to the other roommates. Each roommate who is proposed to can accept or reject the proposal. A roommate accepts if he currently has made no better proposal which was accepted to another roommate. If a roommate has accepted a proposal, and then receives a better proposal, he rejects the old proposal and substitutes in the new proposal. In the above example, @@ -222,9 +222,9 @@ In the above example, In phase 2, we begin by eliminating all potential roommate matches which are worse than the current proposals held. For example, in the above example, `3` has a proposal from `5`, and so we eliminate `1` and `6` from `3`'s column, and symmetrically eliminate `3` from `1` and `6`'s column. This results in the following 'reduced' preference listing: ``` - 6, 2, 5, 3, + 6, 2, 5, 3, 4, 5, 4, 2, 1 -2, 4, 5, 3, 2, +2, 4, 5, 3, 2, 6, 1, 6, 4, 4 3, 1, 2 ``` @@ -234,22 +234,22 @@ The algorithm proceeds by finding and eliminating 'rotations'. A rotation is a s For example, `(1, 4), (3, 2)` is a rotation in the above table, because `1` loves `4`, `3` loves `2`, `4` hates `1`, `2` hates `3`, `2` is second on `1`s list, and `4` is second on `3`'s list. Eliminating this rotation involves `2` rejecting `3`, `4` rejecting `1`, and then we remove every successive potential roommate as well to preserve the stable table property, resulting in ``` - 6, 5, 3, + 6, 5, 3, 5, 4, 2, 1 -2, 4, 5, 3, 2, +2, 4, 5, 3, 2, 6, 1, 6, 4, 4 2 ``` A further rotation is `(1, 2), (2, 6), (4, 5)`. Eliminating it yields ``` - 3, + 3, 5, 4, 2, 1 - 4, 5, 3, 2, + 4, 5, 3, 2, 6, ``` A final rotation is `(2, 5), (3, 4)`. Eliminating it yields ``` - 3, + 3, 2, 1 4, 5, 6, @@ -295,7 +295,7 @@ This package implements the top trading cycle algorithm. Consider the following problem: A set of $n$ agents each currently own their own home, and have preferences over the homes of other agents. The problem is to trade the homes between the agents in such a way so that no two agents want to swap homes. -Preferences of agents are summarized by an $n \times n$ dimensional matrix, e.g., if $n = 4$, +Preferences of agents are summarized by an $n \times n$ dimensional matrix, e.g., if $n = 4$, ```{r} pref = matrix(c(4, 4, 2, 4, @@ -306,7 +306,7 @@ pref = matrix(c(4, 4, 2, 4, Column $i$ represents the preferences of the $i$th agent, and row $j$ represents the ranking of the roommate whose index is encoded in that row. For example, in the above preference matrix, agent `1` most prefers the home of agent `4`, followed by `2`, followed by `1`, followed by `3`. -Roughly speaking, the top trading cycle proceeds by identifying cycles of agents, then eliminating those cycles until no agents remain. A cycle is a sequence of agents such that each agent most prefers the next agent's home (out of the remaining unmatched agents), and the last agent in the sequence most prefers the first agent in the sequence's home. +Roughly speaking, the top trading cycle proceeds by identifying cycles of agents, then eliminating those cycles until no agents remain. A cycle is a sequence of agents such that each agent most prefers the next agent's home (out of the remaining unmatched agents), and the last agent in the sequence most prefers the first agent in the sequence's home. ``` 4, 4, 2, 4 @@ -324,7 +324,7 @@ For example, for the above preference matrix, when all the agents are unmatched, 3, 3, ``` -Now, a rotation is $\{1, 2\}$, because `1` most prefers `2`s house, and `2` most prefers `1`s house. So agents `1` and `2` will swap homes, leaving agent `3` all by himself. +Now, a rotation is $\{1, 2\}$, because `1` most prefers `2`s house, and `2` most prefers `1`s house. So agents `1` and `2` will swap homes, leaving agent `3` all by himself. ``` @@ -339,7 +339,7 @@ Therefore, the final matching is that agent `1` swaps with agent `2`, and agents results = toptrading(pref = pref) results ``` -The function `toptrading.checkStability` can be used to check if the resulting allocation is in fact stable: +The function `toptrading.checkStability` can be used to check if the resulting allocation is in fact stable: ```{r} toptrading.checkStability(pref = pref, matchings = results) ```