Algorithms_in_C++ 1.0.0
Set of algorithms implemented in C++.
Loading...
Searching...
No Matches
greedy_algorithms::stable_matching Namespace Reference

Functions for the Gale-Shapley Algorithm. More...

Functions

std::vector< std::uint32_tgale_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 Algorithm.
 

Detailed Description

Functions for the Gale-Shapley Algorithm.

Function Documentation

◆ gale_shapley()

std::vector< std::uint32_t > greedy_algorithms::stable_matching::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 Algorithm.

Note
This doesn't work on negative preferences. the preferences should be continuous integers starting from 0 to number of preferences - 1.
Parameters
primary_preferencesthe preferences of the primary set should be a 2D vector
secondary_preferencesthe preferences of the secondary set should be a 2D vector
Returns
matches the stable matching between the two sets
42 {
43 std::uint32_t num_elements = secondary_preferences.size();
44 std::vector<std::uint32_t> matches(num_elements, -1);
45 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
47
48 while (true) {
49 int free_primary_index = -1;
50
51 // Find the next free primary
52 for (std::uint32_t i = 0; i < num_elements; i++) {
53 if (is_free_primary[i]) {
54 free_primary_index = i;
55 break;
56 }
57 }
58
59 // If no free primary is found, break the loop
60 if (free_primary_index == -1) break;
61
62 // Get the next secondary to propose
63 std::uint32_t secondary_to_propose = primary_preferences[free_primary_index][proposal_index[free_primary_index]];
64 proposal_index[free_primary_index]++;
65
66 // Get the current match of the secondary
67 std::uint32_t current_match = matches[secondary_to_propose];
68
69 // If the secondary is free, match them
70 if (current_match == -1) {
71 matches[secondary_to_propose] = free_primary_index;
72 is_free_primary[free_primary_index] = false;
73 } else {
74 // 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);
81
82 // If the new proposer is preferred over the current match
83 if (new_proposer_rank < current_match_rank) {
84 matches[secondary_to_propose] = free_primary_index;
85 is_free_primary[free_primary_index] = false;
86 is_free_primary[current_match] = true; // Current match is now free
87 }
88 }
89 }
90
91 return matches;
92}
T begin(T... args)
T end(T... args)
T find(T... args)
T size(T... args)
Here is the call graph for this function: