Skip to content

Commit 5ec6fb0

Browse files
committed
consize
1 parent c40fb3e commit 5ec6fb0

File tree

1 file changed

+85
-30
lines changed

1 file changed

+85
-30
lines changed

src/greedy/stable_matching.rs

Lines changed: 85 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,33 @@ pub fn stable_matching(
44
men_preferences: &HashMap<String, Vec<String>>,
55
women_preferences: &HashMap<String, Vec<String>>,
66
) -> HashMap<String, String> {
7+
let (mut free_men, mut current_partner, mut man_engaged, mut next_proposal) =
8+
initialize_data_structures(men_preferences, women_preferences);
9+
10+
while let Some(man) = free_men.pop_front() {
11+
handle_proposal(
12+
&man,
13+
&mut free_men,
14+
&mut current_partner,
15+
&mut man_engaged,
16+
&mut next_proposal,
17+
men_preferences,
18+
women_preferences,
19+
);
20+
}
21+
22+
extract_stable_matches(man_engaged)
23+
}
24+
25+
fn initialize_data_structures(
26+
men_preferences: &HashMap<String, Vec<String>>,
27+
women_preferences: &HashMap<String, Vec<String>>,
28+
) -> (
29+
VecDeque<String>,
30+
HashMap<String, Option<String>>,
31+
HashMap<String, Option<String>>,
32+
HashMap<String, usize>,
33+
) {
734
let mut free_men: VecDeque<String> = VecDeque::new();
835
let mut current_partner: HashMap<String, Option<String>> = HashMap::new();
936
let mut man_engaged: HashMap<String, Option<String>> = HashMap::new();
@@ -18,48 +45,76 @@ pub fn stable_matching(
1845
current_partner.insert(woman.clone(), None);
1946
}
2047

21-
fn woman_prefers_new_man(
22-
woman: &str,
23-
man1: &str,
24-
man2: &str,
25-
preferences: &HashMap<String, Vec<String>>,
26-
) -> bool {
27-
let woman_preferences = &preferences[woman];
28-
woman_preferences.iter().position(|m| m == man1).unwrap()
29-
< woman_preferences.iter().position(|m| m == man2).unwrap()
30-
}
48+
(free_men, current_partner, man_engaged, next_proposal)
49+
}
3150

32-
while let Some(man) = free_men.pop_front() {
33-
let man_pref_list = &men_preferences[&man];
34-
let next_woman_idx = *next_proposal.get(&man).unwrap();
35-
let woman = &man_pref_list[next_woman_idx];
36-
37-
next_proposal.insert(man.clone(), next_woman_idx + 1);
38-
39-
if let Some(current_man) = current_partner[woman].clone() {
40-
if woman_prefers_new_man(woman, &man, &current_man, women_preferences) {
41-
man_engaged.insert(man.clone(), Some(woman.clone()));
42-
current_partner.insert(woman.clone(), Some(man.clone()));
43-
free_men.push_back(current_man);
44-
} else {
45-
free_men.push_back(man);
46-
}
51+
fn handle_proposal(
52+
man: &str,
53+
free_men: &mut VecDeque<String>,
54+
current_partner: &mut HashMap<String, Option<String>>,
55+
man_engaged: &mut HashMap<String, Option<String>>,
56+
next_proposal: &mut HashMap<String, usize>,
57+
men_preferences: &HashMap<String, Vec<String>>,
58+
women_preferences: &HashMap<String, Vec<String>>,
59+
) {
60+
let man_pref_list = &men_preferences[man];
61+
let next_woman_idx = *next_proposal.get(man).unwrap();
62+
let woman = &man_pref_list[next_woman_idx];
63+
64+
next_proposal.insert(man.to_string(), next_woman_idx + 1);
65+
66+
if let Some(current_man) = current_partner[woman].clone() {
67+
if woman_prefers_new_man(woman, man, &current_man, women_preferences) {
68+
update_engagement(
69+
man,
70+
woman,
71+
current_man,
72+
free_men,
73+
current_partner,
74+
man_engaged,
75+
);
4776
} else {
48-
man_engaged.insert(man.clone(), Some(woman.clone()));
49-
current_partner.insert(woman.clone(), Some(man.clone()));
77+
free_men.push_back(man.to_string());
5078
}
79+
} else {
80+
man_engaged.insert(man.to_string(), Some(woman.to_string()));
81+
current_partner.insert(woman.to_string(), Some(man.to_string()));
5182
}
83+
}
84+
85+
fn update_engagement(
86+
man: &str,
87+
woman: &str,
88+
current_man: String,
89+
free_men: &mut VecDeque<String>,
90+
current_partner: &mut HashMap<String, Option<String>>,
91+
man_engaged: &mut HashMap<String, Option<String>>,
92+
) {
93+
man_engaged.insert(man.to_string(), Some(woman.to_string()));
94+
current_partner.insert(woman.to_string(), Some(man.to_string()));
95+
free_men.push_back(current_man);
96+
}
97+
98+
fn woman_prefers_new_man(
99+
woman: &str,
100+
man1: &str,
101+
man2: &str,
102+
preferences: &HashMap<String, Vec<String>>,
103+
) -> bool {
104+
let woman_preferences = &preferences[woman];
105+
woman_preferences.iter().position(|m| m == man1).unwrap()
106+
< woman_preferences.iter().position(|m| m == man2).unwrap()
107+
}
52108

53-
let mut stable_matches: HashMap<String, String> = HashMap::new();
109+
fn extract_stable_matches(man_engaged: HashMap<String, Option<String>>) -> HashMap<String, String> {
110+
let mut stable_matches = HashMap::new();
54111
for (man, woman_option) in man_engaged {
55112
if let Some(woman) = woman_option {
56113
stable_matches.insert(man, woman);
57114
}
58115
}
59-
60116
stable_matches
61117
}
62-
63118
#[cfg(test)]
64119
mod tests {
65120
use super::*;

0 commit comments

Comments
 (0)