11/* *
22 * @file
3- * @brief [Gale Shapley Algorithm](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm)
3+ * @brief [Gale Shapley
4+ * Algorithm](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm)
45 * @details
5- * This implementation utilizes the Gale-Shapley algorithm to find stable matches.
6+ * This implementation utilizes the Gale-Shapley algorithm to find stable
7+ * matches.
68 *
7- * **Gale Shapley Algorithm** aims to find a stable matching between two equally sized
8- * sets of elements given an ordinal preference for each element. The algorithm was
9- * introduced by David Gale and Lloyd Shapley in 1962.
10- *
11- * Reference:
9+ * **Gale Shapley Algorithm** aims to find a stable matching between two equally
10+ * sized sets of elements given an ordinal preference for each element. The
11+ * algorithm was introduced by David Gale and Lloyd Shapley in 1962.
12+ *
13+ * Reference:
1214 * [Wikipedia](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm)
1315 * [Wikipedia](https://en.wikipedia.org/wiki/Stable_matching_problem)
1416 *
1517 * @author [B Karthik](https://github.com/BKarthik7)
1618 */
1719
18- #include < iostream> // / for std::u32int_t
19- #include < vector> // / for std::vector
2020#include < algorithm> // / for std::find
2121#include < cassert> // / for assert
22+ #include < cstdint> // / for std::uint32_t
23+ #include < vector> // / for std::vector
2224
2325/* *
2426 * @namespace
@@ -31,19 +33,25 @@ namespace greedy_algorithms {
3133 */
3234namespace stable_matching {
3335/* *
34- * @brief The main function that finds the stable matching between two sets of elements
35- * using the Gale-Shapley Algorithm.
36- * @note This doesn't work on negative preferences. the preferences should be continuous integers starting from
37- * 0 to number of preferences - 1.
38- * @param primary_preferences the preferences of the primary set should be a 2D vector
39- * @param secondary_preferences the preferences of the secondary set should be a 2D vector
36+ * @brief The main function that finds the stable matching between two sets of
37+ * elements using the Gale-Shapley Algorithm.
38+ * @note This doesn't work on negative preferences. the preferences should be
39+ * continuous integers starting from 0 to number of preferences - 1.
40+ * @param primary_preferences the preferences of the primary set should be a 2D
41+ * vector
42+ * @param secondary_preferences the preferences of the secondary set should be a
43+ * 2D vector
4044 * @returns matches the stable matching between the two sets
4145 */
42- std::vector<std::uint32_t > gale_shapley (const std::vector<std::vector<std::uint32_t >>& secondary_preferences, const std::vector<std::vector<std::uint32_t >>& primary_preferences) {
46+ std::vector<std::uint32_t > gale_shapley (
47+ const std::vector<std::vector<std::uint32_t >>& secondary_preferences,
48+ const std::vector<std::vector<std::uint32_t >>& primary_preferences) {
4349 std::uint32_t num_elements = secondary_preferences.size ();
4450 std::vector<std::uint32_t > matches (num_elements, -1 );
4551 std::vector<bool > is_free_primary (num_elements, true );
46- std::vector<std::uint32_t > proposal_index (num_elements, 0 ); // Tracks the next secondary to propose for each primary
52+ std::vector<std::uint32_t > proposal_index (
53+ num_elements,
54+ 0 ); // Tracks the next secondary to propose for each primary
4755
4856 while (true ) {
4957 int free_primary_index = -1 ;
@@ -57,10 +65,13 @@ std::vector<std::uint32_t> gale_shapley(const std::vector<std::vector<std::uint3
5765 }
5866
5967 // If no free primary is found, break the loop
60- if (free_primary_index == -1 ) break ;
68+ if (free_primary_index == -1 )
69+ break ;
6170
6271 // Get the next secondary to propose
63- std::uint32_t secondary_to_propose = primary_preferences[free_primary_index][proposal_index[free_primary_index]];
72+ std::uint32_t secondary_to_propose =
73+ primary_preferences[free_primary_index]
74+ [proposal_index[free_primary_index]];
6475 proposal_index[free_primary_index]++;
6576
6677 // Get the current match of the secondary
@@ -72,18 +83,21 @@ std::vector<std::uint32_t> gale_shapley(const std::vector<std::vector<std::uint3
7283 is_free_primary[free_primary_index] = false ;
7384 } else {
7485 // Determine if the current match should be replaced
75- auto new_proposer_rank = std::find (secondary_preferences[secondary_to_propose].begin (),
76- secondary_preferences[secondary_to_propose].end (),
77- free_primary_index);
78- auto current_match_rank = std::find (secondary_preferences[secondary_to_propose].begin (),
79- secondary_preferences[secondary_to_propose].end (),
80- current_match);
86+ auto new_proposer_rank =
87+ std::find (secondary_preferences[secondary_to_propose].begin (),
88+ secondary_preferences[secondary_to_propose].end (),
89+ free_primary_index);
90+ auto current_match_rank =
91+ std::find (secondary_preferences[secondary_to_propose].begin (),
92+ secondary_preferences[secondary_to_propose].end (),
93+ current_match);
8194
8295 // If the new proposer is preferred over the current match
8396 if (new_proposer_rank < current_match_rank) {
8497 matches[secondary_to_propose] = free_primary_index;
8598 is_free_primary[free_primary_index] = false ;
86- is_free_primary[current_match] = true ; // Current match is now free
99+ is_free_primary[current_match] =
100+ true ; // Current match is now free
87101 }
88102 }
89103 }
@@ -99,31 +113,43 @@ std::vector<std::uint32_t> gale_shapley(const std::vector<std::vector<std::uint3
99113 */
100114static void tests () {
101115 // Test Case 1
102- std::vector<std::vector<std::uint32_t >> primary_preferences = {{0 , 1 , 2 , 3 }, {2 , 1 , 3 , 0 }, {1 , 2 , 0 , 3 }, {3 , 0 , 1 , 2 }};
103- std::vector<std::vector<std::uint32_t >> secondary_preferences = {{1 , 0 , 2 , 3 }, {3 , 0 , 1 , 2 }, {0 , 2 , 1 , 3 }, {1 , 2 , 0 , 3 }};
104- assert (greedy_algorithms::stable_matching::gale_shapley (secondary_preferences, primary_preferences) == std::vector<std::uint32_t >({0 , 2 , 1 , 3 }));
116+ std::vector<std::vector<std::uint32_t >> primary_preferences = {
117+ {0 , 1 , 2 , 3 }, {2 , 1 , 3 , 0 }, {1 , 2 , 0 , 3 }, {3 , 0 , 1 , 2 }};
118+ std::vector<std::vector<std::uint32_t >> secondary_preferences = {
119+ {1 , 0 , 2 , 3 }, {3 , 0 , 1 , 2 }, {0 , 2 , 1 , 3 }, {1 , 2 , 0 , 3 }};
120+ assert (greedy_algorithms::stable_matching::gale_shapley (
121+ secondary_preferences, primary_preferences) ==
122+ std::vector<std::uint32_t >({0 , 2 , 1 , 3 }));
105123
106124 // Test Case 2
107- primary_preferences = {{0 , 2 , 1 , 3 }, {2 , 3 , 0 , 1 }, {3 , 1 , 2 , 0 }, {2 , 1 , 0 , 3 }};
108- secondary_preferences = {{1 , 0 , 2 , 3 }, {3 , 0 , 1 , 2 }, {0 , 2 , 1 , 3 }, {1 , 2 , 0 , 3 }};
109- assert (greedy_algorithms::stable_matching::gale_shapley (secondary_preferences, primary_preferences) == std::vector<std::uint32_t >({0 , 3 , 1 , 2 }));
125+ primary_preferences = {
126+ {0 , 2 , 1 , 3 }, {2 , 3 , 0 , 1 }, {3 , 1 , 2 , 0 }, {2 , 1 , 0 , 3 }};
127+ secondary_preferences = {
128+ {1 , 0 , 2 , 3 }, {3 , 0 , 1 , 2 }, {0 , 2 , 1 , 3 }, {1 , 2 , 0 , 3 }};
129+ assert (greedy_algorithms::stable_matching::gale_shapley (
130+ secondary_preferences, primary_preferences) ==
131+ std::vector<std::uint32_t >({0 , 3 , 1 , 2 }));
110132
111133 // Test Case 3
112134 primary_preferences = {{0 , 1 , 2 }, {2 , 1 , 0 }, {1 , 2 , 0 }};
113135 secondary_preferences = {{1 , 0 , 2 }, {2 , 0 , 1 }, {0 , 2 , 1 }};
114- assert (greedy_algorithms::stable_matching::gale_shapley (secondary_preferences, primary_preferences) == std::vector<std::uint32_t >({0 , 2 , 1 }));
136+ assert (greedy_algorithms::stable_matching::gale_shapley (
137+ secondary_preferences, primary_preferences) ==
138+ std::vector<std::uint32_t >({0 , 2 , 1 }));
115139
116140 // Test Case 4
117141 primary_preferences = {};
118142 secondary_preferences = {};
119- assert (greedy_algorithms::stable_matching::gale_shapley (secondary_preferences, primary_preferences) == std::vector<std::uint32_t >({}));
143+ assert (greedy_algorithms::stable_matching::gale_shapley (
144+ secondary_preferences, primary_preferences) ==
145+ std::vector<std::uint32_t >({}));
120146}
121147
122148/* *
123149 * @brief Main function
124150 * @returns 0 on exit
125151 */
126152int main () {
127- tests (); // Run self-test implementations
153+ tests (); // Run self-test implementations
128154 return 0 ;
129155}
0 commit comments