From 321ff76dfeb9194fe2fc9a07f9f653f7b2c2fb81 Mon Sep 17 00:00:00 2001 From: B Karthik Date: Tue, 1 Oct 2024 19:02:21 +0530 Subject: [PATCH 01/13] Added gale_shapley.cpp in greedy_algorithms --- greedy_algorithms/gale_shapley.cpp | 106 +++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 greedy_algorithms/gale_shapley.cpp diff --git a/greedy_algorithms/gale_shapley.cpp b/greedy_algorithms/gale_shapley.cpp new file mode 100644 index 00000000000..fcaf25a630f --- /dev/null +++ b/greedy_algorithms/gale_shapley.cpp @@ -0,0 +1,106 @@ +#include +#include +#include +#include +using namespace std; + +void stableMatch(const vector>& women_prefs, const vector>& men_prefs, int n) { + vector engagements(n, -1); + vector free_men(n, true); + vector next_proposal(n, 0); // Tracks the next woman to propose for each man + + while (true) { + int freeMan; + for (freeMan = 0; freeMan < n; freeMan++) { + if (free_men[freeMan]) break; + } + if (freeMan == n) break; + + int womanToPropose = men_prefs[freeMan][next_proposal[freeMan]]; + next_proposal[freeMan]++; + int currentFiance = engagements[womanToPropose]; + + if (currentFiance == -1) { + engagements[womanToPropose] = freeMan; + free_men[freeMan] = false; + } else { + if (find(women_prefs[womanToPropose].begin(), women_prefs[womanToPropose].end(), freeMan) < + find(women_prefs[womanToPropose].begin(), women_prefs[womanToPropose].end(), currentFiance)) { + engagements[womanToPropose] = freeMan; + free_men[freeMan] = false; + free_men[currentFiance] = true; + } + } + } + + cout << "Stable Matches:\n"; + for (int woman = 0; woman < n; woman++) { + cout << "Woman " << woman << " is engaged to Man " << engagements[woman] << endl; + } +} + +void runTestCase(int caseNum) { + const int n = 4; // Number of men and women + + // Test Case 1 + if (caseNum == 1) { + cout << "Test Case 1:\n"; + vector> women_prefs = { + {1, 0, 3, 2}, // Alice + {0, 1, 2, 3}, // Becky + {1, 2, 0, 3}, // Cathy + {3, 2, 1, 0} // Diana + }; + vector> men_prefs = { + {0, 1, 2, 3}, // Bob + {1, 0, 3, 2}, // Charlie + {0, 2, 3, 1}, // David + {2, 1, 0, 3} // Edward + }; + stableMatch(women_prefs, men_prefs, n); + } + + // Test Case 2 + else if (caseNum == 2) { + cout << "Test Case 2:\n"; + vector> women_prefs = { + {0, 1, 2, 3}, // Eve + {1, 0, 3, 2}, // Grace + {2, 1, 0, 3}, // Hannah + {3, 2, 1, 0} // Ivy + }; + vector> men_prefs = { + {1, 0, 3, 2}, // Frank + {0, 1, 2, 3}, // George + {1, 2, 0, 3}, // Henry + {2, 0, 1, 3} // Ian + }; + stableMatch(women_prefs, men_prefs, n); + } + + // Test Case 3 + else if (caseNum == 3) { + cout << "Test Case 3:\n"; + vector> women_prefs = { + {2, 1, 0, 3}, // Jade + {0, 2, 3, 1}, // Lucy + {3, 2, 1, 0}, // Mia + {1, 3, 0, 2} // Nina + }; + vector> men_prefs = { + {1, 0, 2, 3}, // Kyle + {0, 2, 3, 1}, // Liam + {2, 1, 3, 0}, // Mason + {3, 2, 1, 0} // Nathan + }; + stableMatch(women_prefs, men_prefs, n); + } +} + +int main() { + for (int i = 1; i <= 3; i++) { + runTestCase(i); + cout << endl; + } + return 0; +} From 13f9825cb55cc1d9e7d1d57f4020d1aeb3e53f42 Mon Sep 17 00:00:00 2001 From: B Karthik Date: Tue, 1 Oct 2024 19:22:35 +0530 Subject: [PATCH 02/13] Added gale_shapley.cpp in greedy_algorithms --- greedy_algorithms/gale_shapley.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/greedy_algorithms/gale_shapley.cpp b/greedy_algorithms/gale_shapley.cpp index fcaf25a630f..8a27b0b9018 100644 --- a/greedy_algorithms/gale_shapley.cpp +++ b/greedy_algorithms/gale_shapley.cpp @@ -1,3 +1,17 @@ +/** + * @file + * @brief Stable Marriage Problem implementation + * @details + * This implementation utilizes the Gale-Shapley algorithm to find stable matches + * between men and women based on their preferences. + * + * **Stable Marriage Problem** aims to find a stable matching between two equally sized + * sets of elements given an ordinal preference for each element. The algorithm was + * introduced by David Gale and Lloyd Shapley in 1962. + * + * @author [B Karthik](https://github.com/BKarthik7) + */ + #include #include #include From 418980d5b4afaefd906ddf45ac7e11e1c4449895 Mon Sep 17 00:00:00 2001 From: B Karthik Date: Tue, 1 Oct 2024 22:16:27 +0530 Subject: [PATCH 03/13] Genralized GaleShapley with reviewed change --- greedy_algorithms/gale_shapley.cpp | 139 +++++++++++++---------------- 1 file changed, 60 insertions(+), 79 deletions(-) diff --git a/greedy_algorithms/gale_shapley.cpp b/greedy_algorithms/gale_shapley.cpp index 8a27b0b9018..adf981e563c 100644 --- a/greedy_algorithms/gale_shapley.cpp +++ b/greedy_algorithms/gale_shapley.cpp @@ -1,13 +1,16 @@ /** * @file - * @brief Stable Marriage Problem implementation + * @brief [Stable Marriage](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm) * @details * This implementation utilizes the Gale-Shapley algorithm to find stable matches - * between men and women based on their preferences. * * **Stable Marriage Problem** aims to find a stable matching between two equally sized * sets of elements given an ordinal preference for each element. The algorithm was * introduced by David Gale and Lloyd Shapley in 1962. + * + * Reference: + * [Wikipedia](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm) + * [Wikipedia](https://en.wikipedia.org/wiki/Stable_marriage_problem) * * @author [B Karthik](https://github.com/BKarthik7) */ @@ -16,105 +19,83 @@ #include #include #include -using namespace std; -void stableMatch(const vector>& women_prefs, const vector>& men_prefs, int n) { - vector engagements(n, -1); - vector free_men(n, true); - vector next_proposal(n, 0); // Tracks the next woman to propose for each man +/** + * @namespace + * @brief Greedy Algorithms + */ +namespace greedy_algorithms { +/** + * @namespace + * @brief Functions for the [Gale Shapley](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm) algorithm + */ +namespace stable_marriage { +void gale_shapley(const std::vector>& set_2_prefs, const std::vector>& set_1_prefs) { + int n = set_2_prefs.size(); + std::vector engagements(n, -1); + std::vector free_set_1_s(n, true); + std::vector next_proposal(n, 0); // Tracks the next set_2 to propose for each set_1 while (true) { - int freeMan; - for (freeMan = 0; freeMan < n; freeMan++) { - if (free_men[freeMan]) break; + int free_set_1; + for (free_set_1 = 0; free_set_1 < n; free_set_1++) { + if (free_set_1_s[free_set_1]) break; } - if (freeMan == n) break; + if (free_set_1 == n) break; - int womanToPropose = men_prefs[freeMan][next_proposal[freeMan]]; - next_proposal[freeMan]++; - int currentFiance = engagements[womanToPropose]; + int set_2_to_propose = set_1_prefs[free_set_1][next_proposal[free_set_1]]; + next_proposal[free_set_1]++; + int currentFiance = engagements[set_2_to_propose]; if (currentFiance == -1) { - engagements[womanToPropose] = freeMan; - free_men[freeMan] = false; + engagements[set_2_to_propose] = free_set_1; + free_set_1_s[free_set_1] = false; } else { - if (find(women_prefs[womanToPropose].begin(), women_prefs[womanToPropose].end(), freeMan) < - find(women_prefs[womanToPropose].begin(), women_prefs[womanToPropose].end(), currentFiance)) { - engagements[womanToPropose] = freeMan; - free_men[freeMan] = false; - free_men[currentFiance] = true; + if (std::find(set_2_prefs[set_2_to_propose].begin(), set_2_prefs[set_2_to_propose].end(), free_set_1) < + std::find(set_2_prefs[set_2_to_propose].begin(), set_2_prefs[set_2_to_propose].end(), currentFiance)) { + engagements[set_2_to_propose] = free_set_1; + free_set_1_s[free_set_1] = false; + free_set_1_s[currentFiance] = true; } } } - cout << "Stable Matches:\n"; - for (int woman = 0; woman < n; woman++) { - cout << "Woman " << woman << " is engaged to Man " << engagements[woman] << endl; + std::cout << "Stable Matches:\n"; + for (int set_2 = 0; set_2 < n; set_2++) { + std::cout << "set_2's " << set_2 << " is matched to set_1's " << engagements[set_2] << std::endl; } + std::cout << std::endl; } +} // namespace stable_marriage +} // namespace greedy_algorithms -void runTestCase(int caseNum) { - const int n = 4; // Number of men and women +/** + * @brief Self-test implementations + * @returns void + */ +static void tests() { // Test Case 1 - if (caseNum == 1) { - cout << "Test Case 1:\n"; - vector> women_prefs = { - {1, 0, 3, 2}, // Alice - {0, 1, 2, 3}, // Becky - {1, 2, 0, 3}, // Cathy - {3, 2, 1, 0} // Diana - }; - vector> men_prefs = { - {0, 1, 2, 3}, // Bob - {1, 0, 3, 2}, // Charlie - {0, 2, 3, 1}, // David - {2, 1, 0, 3} // Edward - }; - stableMatch(women_prefs, men_prefs, n); - } - + std::vector> set_1_prefs = {{0, 1, 2, 3}, {2, 1, 3, 0}, {1, 2, 0, 3}, {3, 0, 1, 2}}; + std::vector> set_2_prefs = {{1, 0, 2, 3},{3, 0, 1, 2},{0, 2, 1, 3},{1, 2, 0, 3}}; + greedy_algorithms::stable_marriage::gale_shapley(set_2_prefs, set_1_prefs); + // Test Case 2 - else if (caseNum == 2) { - cout << "Test Case 2:\n"; - vector> women_prefs = { - {0, 1, 2, 3}, // Eve - {1, 0, 3, 2}, // Grace - {2, 1, 0, 3}, // Hannah - {3, 2, 1, 0} // Ivy - }; - vector> men_prefs = { - {1, 0, 3, 2}, // Frank - {0, 1, 2, 3}, // George - {1, 2, 0, 3}, // Henry - {2, 0, 1, 3} // Ian - }; - stableMatch(women_prefs, men_prefs, n); - } + set_1_prefs = {{0, 2, 1, 3}, {2, 3, 0, 1}, {3, 1, 2, 0}, {2, 1, 0, 3}}; + set_2_prefs = {{1, 0, 2, 3},{3, 0, 1, 2},{0, 2, 1, 3},{1, 2, 0, 3}}; + greedy_algorithms::stable_marriage::gale_shapley(set_2_prefs, set_1_prefs); // Test Case 3 - else if (caseNum == 3) { - cout << "Test Case 3:\n"; - vector> women_prefs = { - {2, 1, 0, 3}, // Jade - {0, 2, 3, 1}, // Lucy - {3, 2, 1, 0}, // Mia - {1, 3, 0, 2} // Nina - }; - vector> men_prefs = { - {1, 0, 2, 3}, // Kyle - {0, 2, 3, 1}, // Liam - {2, 1, 3, 0}, // Mason - {3, 2, 1, 0} // Nathan - }; - stableMatch(women_prefs, men_prefs, n); - } + set_1_prefs = {{0, 1, 2}, {2, 1, 0}, {1, 2, 0}}; + set_2_prefs = {{1, 0, 2},{2, 0, 1},{0, 2, 1}}; + greedy_algorithms::stable_marriage::gale_shapley(set_2_prefs, set_1_prefs); } +/** + * @brief Main function + * @returns 0 on exit + */ int main() { - for (int i = 1; i <= 3; i++) { - runTestCase(i); - cout << endl; - } + tests(); // run self-test implementations return 0; } From a68996343e1d7b3ccdcc06d58acf61a4003a4f36 Mon Sep 17 00:00:00 2001 From: B Karthik Date: Tue, 1 Oct 2024 22:20:24 +0530 Subject: [PATCH 04/13] fix: added description --- greedy_algorithms/gale_shapley.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/greedy_algorithms/gale_shapley.cpp b/greedy_algorithms/gale_shapley.cpp index adf981e563c..7cb31503847 100644 --- a/greedy_algorithms/gale_shapley.cpp +++ b/greedy_algorithms/gale_shapley.cpp @@ -1,10 +1,10 @@ /** * @file - * @brief [Stable Marriage](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm) + * @brief [Gale Shapley](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm) * @details * This implementation utilizes the Gale-Shapley algorithm to find stable matches * - * **Stable Marriage Problem** aims to find a stable matching between two equally sized + * **Gale Shapley** aims to find a stable matching between two equally sized * sets of elements given an ordinal preference for each element. The algorithm was * introduced by David Gale and Lloyd Shapley in 1962. * From f9fcb73932225c3e42640814f36fa2556c4d0e70 Mon Sep 17 00:00:00 2001 From: B Karthik Date: Tue, 1 Oct 2024 22:23:16 +0530 Subject: [PATCH 05/13] fix: fixed nameing of namespace --- greedy_algorithms/gale_shapley.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/greedy_algorithms/gale_shapley.cpp b/greedy_algorithms/gale_shapley.cpp index 7cb31503847..8ec17c17720 100644 --- a/greedy_algorithms/gale_shapley.cpp +++ b/greedy_algorithms/gale_shapley.cpp @@ -1,16 +1,16 @@ /** * @file - * @brief [Gale Shapley](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm) + * @brief [Gale Shapley Algorithm](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm) * @details * This implementation utilizes the Gale-Shapley algorithm to find stable matches * - * **Gale Shapley** aims to find a stable matching between two equally sized + * **Gale Shapley Algorithm** aims to find a stable matching between two equally sized * sets of elements given an ordinal preference for each element. The algorithm was * introduced by David Gale and Lloyd Shapley in 1962. * * Reference: * [Wikipedia](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm) - * [Wikipedia](https://en.wikipedia.org/wiki/Stable_marriage_problem) + * [Wikipedia](https://en.wikipedia.org/wiki/Stable_matching_problem) * * @author [B Karthik](https://github.com/BKarthik7) */ @@ -27,9 +27,9 @@ namespace greedy_algorithms { /** * @namespace - * @brief Functions for the [Gale Shapley](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm) algorithm + * @brief Functions for the Gale Shapley Algorithm */ -namespace stable_marriage { +namespace stable_matching { void gale_shapley(const std::vector>& set_2_prefs, const std::vector>& set_1_prefs) { int n = set_2_prefs.size(); std::vector engagements(n, -1); @@ -66,7 +66,7 @@ void gale_shapley(const std::vector>& set_2_prefs, const std::v } std::cout << std::endl; } -} // namespace stable_marriage +} // namespace stable_matching } // namespace greedy_algorithms /** @@ -78,17 +78,17 @@ static void tests() { // Test Case 1 std::vector> set_1_prefs = {{0, 1, 2, 3}, {2, 1, 3, 0}, {1, 2, 0, 3}, {3, 0, 1, 2}}; std::vector> set_2_prefs = {{1, 0, 2, 3},{3, 0, 1, 2},{0, 2, 1, 3},{1, 2, 0, 3}}; - greedy_algorithms::stable_marriage::gale_shapley(set_2_prefs, set_1_prefs); + greedy_algorithms::stable_matching::gale_shapley(set_2_prefs, set_1_prefs); // Test Case 2 set_1_prefs = {{0, 2, 1, 3}, {2, 3, 0, 1}, {3, 1, 2, 0}, {2, 1, 0, 3}}; set_2_prefs = {{1, 0, 2, 3},{3, 0, 1, 2},{0, 2, 1, 3},{1, 2, 0, 3}}; - greedy_algorithms::stable_marriage::gale_shapley(set_2_prefs, set_1_prefs); + greedy_algorithms::stable_matching::gale_shapley(set_2_prefs, set_1_prefs); // Test Case 3 set_1_prefs = {{0, 1, 2}, {2, 1, 0}, {1, 2, 0}}; set_2_prefs = {{1, 0, 2},{2, 0, 1},{0, 2, 1}}; - greedy_algorithms::stable_marriage::gale_shapley(set_2_prefs, set_1_prefs); + greedy_algorithms::stable_matching::gale_shapley(set_2_prefs, set_1_prefs); } /** From bdce70da097b6a4bf898833654fb7c4c07684c0b Mon Sep 17 00:00:00 2001 From: B Karthik Date: Wed, 2 Oct 2024 00:10:59 +0530 Subject: [PATCH 06/13] fix: reviewed changes --- greedy_algorithms/gale_shapley.cpp | 92 +++++++++++++++++------------- 1 file changed, 53 insertions(+), 39 deletions(-) diff --git a/greedy_algorithms/gale_shapley.cpp b/greedy_algorithms/gale_shapley.cpp index 8ec17c17720..d6ff16ca192 100644 --- a/greedy_algorithms/gale_shapley.cpp +++ b/greedy_algorithms/gale_shapley.cpp @@ -2,7 +2,7 @@ * @file * @brief [Gale Shapley Algorithm](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm) * @details - * This implementation utilizes the Gale-Shapley algorithm to find stable matches + * This implementation utilizes the Gale-Shapley algorithm to find stable matches. * * **Gale Shapley Algorithm** aims to find a stable matching between two equally sized * sets of elements given an ordinal preference for each element. The algorithm was @@ -17,8 +17,8 @@ #include #include -#include #include +#include /** * @namespace @@ -27,44 +27,59 @@ namespace greedy_algorithms { /** * @namespace - * @brief Functions for the Gale Shapley Algorithm + * @brief Functions for the Gale-Shapley Algorithm */ namespace stable_matching { -void gale_shapley(const std::vector>& set_2_prefs, const std::vector>& set_1_prefs) { - int n = set_2_prefs.size(); - std::vector engagements(n, -1); - std::vector free_set_1_s(n, true); - std::vector next_proposal(n, 0); // Tracks the next set_2 to propose for each set_1 +std::vector gale_shapley(const std::vector>& secondary_preferences, const std::vector>& primary_preferences) { + int num_elements = secondary_preferences.size(); + std::vector matches(num_elements, -1); + std::vector is_free_primary(num_elements, true); + std::vector proposal_index(num_elements, 0); // Tracks the next secondary to propose for each primary while (true) { - int free_set_1; - for (free_set_1 = 0; free_set_1 < n; free_set_1++) { - if (free_set_1_s[free_set_1]) break; + int free_primary_index = -1; + + // Find the next free primary + for (int i = 0; i < num_elements; i++) { + if (is_free_primary[i]) { + free_primary_index = i; + break; + } } - if (free_set_1 == n) break; - int set_2_to_propose = set_1_prefs[free_set_1][next_proposal[free_set_1]]; - next_proposal[free_set_1]++; - int currentFiance = engagements[set_2_to_propose]; + // If no free primary is found, break the loop + if (free_primary_index == -1) break; + + // Get the next secondary to propose + int secondary_to_propose = primary_preferences[free_primary_index][proposal_index[free_primary_index]]; + proposal_index[free_primary_index]++; + + // Get the current match of the secondary + int current_match = matches[secondary_to_propose]; - if (currentFiance == -1) { - engagements[set_2_to_propose] = free_set_1; - free_set_1_s[free_set_1] = false; + // If the secondary is free, match them + if (current_match == -1) { + matches[secondary_to_propose] = free_primary_index; + is_free_primary[free_primary_index] = false; } else { - if (std::find(set_2_prefs[set_2_to_propose].begin(), set_2_prefs[set_2_to_propose].end(), free_set_1) < - std::find(set_2_prefs[set_2_to_propose].begin(), set_2_prefs[set_2_to_propose].end(), currentFiance)) { - engagements[set_2_to_propose] = free_set_1; - free_set_1_s[free_set_1] = false; - free_set_1_s[currentFiance] = true; + // Determine if the current match should be replaced + auto new_proposer_rank = std::find(secondary_preferences[secondary_to_propose].begin(), + secondary_preferences[secondary_to_propose].end(), + free_primary_index); + auto current_match_rank = std::find(secondary_preferences[secondary_to_propose].begin(), + secondary_preferences[secondary_to_propose].end(), + current_match); + + // If the new proposer is preferred over the current match + if (new_proposer_rank < current_match_rank) { + matches[secondary_to_propose] = free_primary_index; + is_free_primary[free_primary_index] = false; + is_free_primary[current_match] = true; // Current match is now free } } } - std::cout << "Stable Matches:\n"; - for (int set_2 = 0; set_2 < n; set_2++) { - std::cout << "set_2's " << set_2 << " is matched to set_1's " << engagements[set_2] << std::endl; - } - std::cout << std::endl; + return matches; } } // namespace stable_matching } // namespace greedy_algorithms @@ -73,22 +88,21 @@ void gale_shapley(const std::vector>& set_2_prefs, const std::v * @brief Self-test implementations * @returns void */ - static void tests() { // Test Case 1 - std::vector> set_1_prefs = {{0, 1, 2, 3}, {2, 1, 3, 0}, {1, 2, 0, 3}, {3, 0, 1, 2}}; - std::vector> set_2_prefs = {{1, 0, 2, 3},{3, 0, 1, 2},{0, 2, 1, 3},{1, 2, 0, 3}}; - greedy_algorithms::stable_matching::gale_shapley(set_2_prefs, set_1_prefs); + std::vector> primary_preferences = {{0, 1, 2, 3}, {2, 1, 3, 0}, {1, 2, 0, 3}, {3, 0, 1, 2}}; + std::vector> secondary_preferences = {{1, 0, 2, 3}, {3, 0, 1, 2}, {0, 2, 1, 3}, {1, 2, 0, 3}}; + assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 2, 1, 3})); // Test Case 2 - set_1_prefs = {{0, 2, 1, 3}, {2, 3, 0, 1}, {3, 1, 2, 0}, {2, 1, 0, 3}}; - set_2_prefs = {{1, 0, 2, 3},{3, 0, 1, 2},{0, 2, 1, 3},{1, 2, 0, 3}}; - greedy_algorithms::stable_matching::gale_shapley(set_2_prefs, set_1_prefs); + primary_preferences = {{0, 2, 1, 3}, {2, 3, 0, 1}, {3, 1, 2, 0}, {2, 1, 0, 3}}; + secondary_preferences = {{1, 0, 2, 3}, {3, 0, 1, 2}, {0, 2, 1, 3}, {1, 2, 0, 3}}; + assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 3, 1, 2})); // Test Case 3 - set_1_prefs = {{0, 1, 2}, {2, 1, 0}, {1, 2, 0}}; - set_2_prefs = {{1, 0, 2},{2, 0, 1},{0, 2, 1}}; - greedy_algorithms::stable_matching::gale_shapley(set_2_prefs, set_1_prefs); + primary_preferences = {{0, 1, 2}, {2, 1, 0}, {1, 2, 0}}; + secondary_preferences = {{1, 0, 2}, {2, 0, 1}, {0, 2, 1}}; + assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 2, 1})); } /** @@ -96,6 +110,6 @@ static void tests() { * @returns 0 on exit */ int main() { - tests(); // run self-test implementations + tests(); // Run self-test implementations return 0; } From ca6586d776f5346e200da3bb0e1250bb25c37e2b Mon Sep 17 00:00:00 2001 From: B Karthik Date: Wed, 2 Oct 2024 00:12:36 +0530 Subject: [PATCH 07/13] fix: reviewed changes --- greedy_algorithms/gale_shapley.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/greedy_algorithms/gale_shapley.cpp b/greedy_algorithms/gale_shapley.cpp index d6ff16ca192..6ad185d5a92 100644 --- a/greedy_algorithms/gale_shapley.cpp +++ b/greedy_algorithms/gale_shapley.cpp @@ -84,10 +84,7 @@ std::vector gale_shapley(const std::vector>& secondary_pre } // namespace stable_matching } // namespace greedy_algorithms -/** - * @brief Self-test implementations - * @returns void - */ + static void tests() { // Test Case 1 std::vector> primary_preferences = {{0, 1, 2, 3}, {2, 1, 3, 0}, {1, 2, 0, 3}, {3, 0, 1, 2}}; From 272e3661bf82e3db5de20b045f2247cf1802610c Mon Sep 17 00:00:00 2001 From: B Karthik Date: Thu, 3 Oct 2024 13:31:50 +0530 Subject: [PATCH 08/13] TestCase Empty vector --- greedy_algorithms/gale_shapley.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/greedy_algorithms/gale_shapley.cpp b/greedy_algorithms/gale_shapley.cpp index 6ad185d5a92..87bb7867e8f 100644 --- a/greedy_algorithms/gale_shapley.cpp +++ b/greedy_algorithms/gale_shapley.cpp @@ -100,6 +100,11 @@ static void tests() { primary_preferences = {{0, 1, 2}, {2, 1, 0}, {1, 2, 0}}; secondary_preferences = {{1, 0, 2}, {2, 0, 1}, {0, 2, 1}}; assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 2, 1})); + + // Test Case 4 + primary_preferences = {}; + secondary_preferences = {}; + assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({})); } /** From bb17cb8a756b99533ad41e52911d32ea59eff2f9 Mon Sep 17 00:00:00 2001 From: B Karthik Date: Thu, 3 Oct 2024 13:39:27 +0530 Subject: [PATCH 09/13] function description --- greedy_algorithms/gale_shapley.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/greedy_algorithms/gale_shapley.cpp b/greedy_algorithms/gale_shapley.cpp index 87bb7867e8f..82fcae8d33e 100644 --- a/greedy_algorithms/gale_shapley.cpp +++ b/greedy_algorithms/gale_shapley.cpp @@ -29,6 +29,17 @@ namespace greedy_algorithms { * @namespace * @brief Functions for the Gale-Shapley Algorithm */ + +/** + * @brief The main function that finds the stable matching between two sets of elements + * using the Gale-Shapley Algorithm. + * @note This doesn't work on negative preferences. the preferences should be continuous integers starting from + * 0 to number of preferences - 1. + * @param primary_preferences the preferences of the primary set should be a 2D vector + * @param secondary_preferences the preferences of the secondary set should be a 2D vector + * @returns matches the stable matching between the two sets + */ + namespace stable_matching { std::vector gale_shapley(const std::vector>& secondary_preferences, const std::vector>& primary_preferences) { int num_elements = secondary_preferences.size(); @@ -84,7 +95,10 @@ std::vector gale_shapley(const std::vector>& secondary_pre } // namespace stable_matching } // namespace greedy_algorithms - +/** + * @brief Self-test implementations + * @returns void + */ static void tests() { // Test Case 1 std::vector> primary_preferences = {{0, 1, 2, 3}, {2, 1, 3, 0}, {1, 2, 0, 3}, {3, 0, 1, 2}}; From 3021d9d7012bd85df831ddcbcbc79714f1a4c559 Mon Sep 17 00:00:00 2001 From: B Karthik <115967163+BKarthik7@users.noreply.github.com> Date: Thu, 3 Oct 2024 23:45:49 +0530 Subject: [PATCH 10/13] Update greedy_algorithms/gale_shapley.cpp Co-authored-by: realstealthninja <68815218+realstealthninja@users.noreply.github.com> --- greedy_algorithms/gale_shapley.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/greedy_algorithms/gale_shapley.cpp b/greedy_algorithms/gale_shapley.cpp index 82fcae8d33e..1e4b85408c8 100644 --- a/greedy_algorithms/gale_shapley.cpp +++ b/greedy_algorithms/gale_shapley.cpp @@ -39,8 +39,6 @@ namespace greedy_algorithms { * @param secondary_preferences the preferences of the secondary set should be a 2D vector * @returns matches the stable matching between the two sets */ - -namespace stable_matching { std::vector gale_shapley(const std::vector>& secondary_preferences, const std::vector>& primary_preferences) { int num_elements = secondary_preferences.size(); std::vector matches(num_elements, -1); From 08d29f2ca5f101b7b4eb4b58d0d2ccc216218478 Mon Sep 17 00:00:00 2001 From: B Karthik <115967163+BKarthik7@users.noreply.github.com> Date: Thu, 3 Oct 2024 23:46:28 +0530 Subject: [PATCH 11/13] Update greedy_algorithms/gale_shapley.cpp Co-authored-by: realstealthninja <68815218+realstealthninja@users.noreply.github.com> --- greedy_algorithms/gale_shapley.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/greedy_algorithms/gale_shapley.cpp b/greedy_algorithms/gale_shapley.cpp index 1e4b85408c8..9dc480062af 100644 --- a/greedy_algorithms/gale_shapley.cpp +++ b/greedy_algorithms/gale_shapley.cpp @@ -29,7 +29,7 @@ namespace greedy_algorithms { * @namespace * @brief Functions for the Gale-Shapley Algorithm */ - +namespace stable_matching { /** * @brief The main function that finds the stable matching between two sets of elements * using the Gale-Shapley Algorithm. From ca2c57a005a13348b179ad780be3e2bdf1e1da3a Mon Sep 17 00:00:00 2001 From: B Karthik Date: Thu, 3 Oct 2024 23:53:06 +0530 Subject: [PATCH 12/13] Change type --- greedy_algorithms/gale_shapley.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/greedy_algorithms/gale_shapley.cpp b/greedy_algorithms/gale_shapley.cpp index 82fcae8d33e..232b7aa0297 100644 --- a/greedy_algorithms/gale_shapley.cpp +++ b/greedy_algorithms/gale_shapley.cpp @@ -41,17 +41,17 @@ namespace greedy_algorithms { */ namespace stable_matching { -std::vector gale_shapley(const std::vector>& secondary_preferences, const std::vector>& primary_preferences) { - int num_elements = secondary_preferences.size(); - std::vector matches(num_elements, -1); +std::vector gale_shapley(const std::vector>& secondary_preferences, const std::vector>& primary_preferences) { + unsigned int num_elements = secondary_preferences.size(); + std::vector matches(num_elements, -1); std::vector is_free_primary(num_elements, true); - std::vector proposal_index(num_elements, 0); // Tracks the next secondary to propose for each primary + std::vector proposal_index(num_elements, 0); // Tracks the next secondary to propose for each primary while (true) { int free_primary_index = -1; // Find the next free primary - for (int i = 0; i < num_elements; i++) { + for (unsigned int i = 0; i < num_elements; i++) { if (is_free_primary[i]) { free_primary_index = i; break; @@ -62,11 +62,11 @@ std::vector gale_shapley(const std::vector>& secondary_pre if (free_primary_index == -1) break; // Get the next secondary to propose - int secondary_to_propose = primary_preferences[free_primary_index][proposal_index[free_primary_index]]; + unsigned int secondary_to_propose = primary_preferences[free_primary_index][proposal_index[free_primary_index]]; proposal_index[free_primary_index]++; // Get the current match of the secondary - int current_match = matches[secondary_to_propose]; + unsigned int current_match = matches[secondary_to_propose]; // If the secondary is free, match them if (current_match == -1) { @@ -101,24 +101,24 @@ std::vector gale_shapley(const std::vector>& secondary_pre */ static void tests() { // Test Case 1 - std::vector> primary_preferences = {{0, 1, 2, 3}, {2, 1, 3, 0}, {1, 2, 0, 3}, {3, 0, 1, 2}}; - std::vector> secondary_preferences = {{1, 0, 2, 3}, {3, 0, 1, 2}, {0, 2, 1, 3}, {1, 2, 0, 3}}; - assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 2, 1, 3})); + std::vector> primary_preferences = {{0, 1, 2, 3}, {2, 1, 3, 0}, {1, 2, 0, 3}, {3, 0, 1, 2}}; + std::vector> secondary_preferences = {{1, 0, 2, 3}, {3, 0, 1, 2}, {0, 2, 1, 3}, {1, 2, 0, 3}}; + assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 2, 1, 3})); // Test Case 2 primary_preferences = {{0, 2, 1, 3}, {2, 3, 0, 1}, {3, 1, 2, 0}, {2, 1, 0, 3}}; secondary_preferences = {{1, 0, 2, 3}, {3, 0, 1, 2}, {0, 2, 1, 3}, {1, 2, 0, 3}}; - assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 3, 1, 2})); + assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 3, 1, 2})); // Test Case 3 primary_preferences = {{0, 1, 2}, {2, 1, 0}, {1, 2, 0}}; secondary_preferences = {{1, 0, 2}, {2, 0, 1}, {0, 2, 1}}; - assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 2, 1})); + assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 2, 1})); // Test Case 4 primary_preferences = {}; secondary_preferences = {}; - assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({})); + assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({})); } /** From e4ff4af16cfbcf691728f04c4314ff301d4fe9f2 Mon Sep 17 00:00:00 2001 From: B Karthik Date: Fri, 4 Oct 2024 09:28:31 +0530 Subject: [PATCH 13/13] typechange with header documentation --- greedy_algorithms/gale_shapley.cpp | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/greedy_algorithms/gale_shapley.cpp b/greedy_algorithms/gale_shapley.cpp index 0fb08d7a16d..ddc6298fa44 100644 --- a/greedy_algorithms/gale_shapley.cpp +++ b/greedy_algorithms/gale_shapley.cpp @@ -15,10 +15,10 @@ * @author [B Karthik](https://github.com/BKarthik7) */ -#include -#include -#include -#include +#include /// for std::u32int_t +#include /// for std::vector +#include /// for std::find +#include /// for assert /** * @namespace @@ -39,17 +39,17 @@ namespace stable_matching { * @param secondary_preferences the preferences of the secondary set should be a 2D vector * @returns matches the stable matching between the two sets */ -std::vector gale_shapley(const std::vector>& secondary_preferences, const std::vector>& primary_preferences) { - unsigned int num_elements = secondary_preferences.size(); - std::vector matches(num_elements, -1); +std::vector gale_shapley(const std::vector>& secondary_preferences, const std::vector>& primary_preferences) { + std::uint32_t num_elements = secondary_preferences.size(); + std::vector matches(num_elements, -1); std::vector is_free_primary(num_elements, true); - std::vector proposal_index(num_elements, 0); // Tracks the next secondary to propose for each primary + std::vector proposal_index(num_elements, 0); // Tracks the next secondary to propose for each primary while (true) { int free_primary_index = -1; // Find the next free primary - for (unsigned int i = 0; i < num_elements; i++) { + for (std::uint32_t i = 0; i < num_elements; i++) { if (is_free_primary[i]) { free_primary_index = i; break; @@ -60,11 +60,11 @@ std::vector gale_shapley(const std::vector gale_shapley(const std::vector> primary_preferences = {{0, 1, 2, 3}, {2, 1, 3, 0}, {1, 2, 0, 3}, {3, 0, 1, 2}}; - std::vector> secondary_preferences = {{1, 0, 2, 3}, {3, 0, 1, 2}, {0, 2, 1, 3}, {1, 2, 0, 3}}; - assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 2, 1, 3})); + std::vector> primary_preferences = {{0, 1, 2, 3}, {2, 1, 3, 0}, {1, 2, 0, 3}, {3, 0, 1, 2}}; + std::vector> secondary_preferences = {{1, 0, 2, 3}, {3, 0, 1, 2}, {0, 2, 1, 3}, {1, 2, 0, 3}}; + assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 2, 1, 3})); // Test Case 2 primary_preferences = {{0, 2, 1, 3}, {2, 3, 0, 1}, {3, 1, 2, 0}, {2, 1, 0, 3}}; secondary_preferences = {{1, 0, 2, 3}, {3, 0, 1, 2}, {0, 2, 1, 3}, {1, 2, 0, 3}}; - assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 3, 1, 2})); + assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 3, 1, 2})); // Test Case 3 primary_preferences = {{0, 1, 2}, {2, 1, 0}, {1, 2, 0}}; secondary_preferences = {{1, 0, 2}, {2, 0, 1}, {0, 2, 1}}; - assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 2, 1})); + assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({0, 2, 1})); // Test Case 4 primary_preferences = {}; secondary_preferences = {}; - assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({})); + assert(greedy_algorithms::stable_matching::gale_shapley(secondary_preferences, primary_preferences) == std::vector({})); } /**