TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
gale_shapley.cpp
Go to the documentation of this file.
1
20#include <algorithm>
21#include <cassert>
22#include <cstdint>
23#include <vector>
24
29namespace greedy_algorithms {
34namespace stable_matching {
46std::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) {
49 std::uint32_t num_elements = secondary_preferences.size();
50 std::vector<std::uint32_t> matches(num_elements, -1);
51 std::vector<bool> is_free_primary(num_elements, true);
52 std::vector<std::uint32_t> proposal_index(
53 num_elements,
54 0); // Tracks the next secondary to propose for each primary
55
56 while (true) {
57 int free_primary_index = -1;
58
59 // Find the next free primary
60 for (std::uint32_t i = 0; i < num_elements; i++) {
61 if (is_free_primary[i]) {
62 free_primary_index = i;
63 break;
64 }
65 }
66
67 // If no free primary is found, break the loop
68 if (free_primary_index == -1)
69 break;
70
71 // Get the next secondary to propose
72 std::uint32_t secondary_to_propose =
73 primary_preferences[free_primary_index]
74 [proposal_index[free_primary_index]];
75 proposal_index[free_primary_index]++;
76
77 // Get the current match of the secondary
78 std::uint32_t current_match = matches[secondary_to_propose];
79
80 // If the secondary is free, match them
81 if (current_match == -1) {
82 matches[secondary_to_propose] = free_primary_index;
83 is_free_primary[free_primary_index] = false;
84 } else {
85 // Determine if the current match should be replaced
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);
94
95 // If the new proposer is preferred over the current match
96 if (new_proposer_rank < current_match_rank) {
97 matches[secondary_to_propose] = free_primary_index;
98 is_free_primary[free_primary_index] = false;
99 is_free_primary[current_match] =
100 true; // Current match is now free
101 }
102 }
103 }
104
105 return matches;
106}
107} // namespace stable_matching
108} // namespace greedy_algorithms
109
114static void tests() {
115 // Test Case 1
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}};
121 secondary_preferences, primary_preferences) ==
122 std::vector<std::uint32_t>({0, 2, 1, 3}));
123
124 // Test Case 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}};
130 secondary_preferences, primary_preferences) ==
131 std::vector<std::uint32_t>({0, 3, 1, 2}));
132
133 // Test Case 3
134 primary_preferences = {{0, 1, 2}, {2, 1, 0}, {1, 2, 0}};
135 secondary_preferences = {{1, 0, 2}, {2, 0, 1}, {0, 2, 1}};
137 secondary_preferences, primary_preferences) ==
138 std::vector<std::uint32_t>({0, 2, 1}));
139
140 // Test Case 4
141 primary_preferences = {};
142 secondary_preferences = {};
144 secondary_preferences, primary_preferences) ==
145 std::vector<std::uint32_t>({}));
146}
147
152int main() {
153 tests(); // Run self-test implementations
154 return 0;
155}
static void tests()
Self-test implementations.
int main()
Main function.
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)
The main function that finds the stable matching between two sets of elements using the Gale-Shapley ...
for string class