-
-
Notifications
You must be signed in to change notification settings - Fork 359
Gale-Shapley implementation in Rust #715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
use std::vec::Vec; | ||
use std::collections::HashMap; | ||
use std::fmt; | ||
|
||
#[derive(Hash, Eq, PartialEq, Copy, Clone)] | ||
struct PersonId(pub char); | ||
|
||
impl fmt::Display for PersonId { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
write!(f, "{}", self.0) | ||
} | ||
} | ||
|
||
#[derive(Clone)] | ||
struct Person { | ||
id: PersonId, | ||
partner: Option<PersonId>, | ||
preferences: Vec<PersonId>, | ||
} | ||
|
||
fn gale_shapley(people: Vec<Person>) -> HashMap<PersonId, PersonId> { | ||
let mut stable_matching: HashMap<PersonId, PersonId> = HashMap::new(); | ||
|
||
for person in people { | ||
let partner = stable_matching | ||
.get(&person.id) | ||
.or_else(|| // execute this if person doesn't have partner | ||
person.preferences | ||
.iter() | ||
// skip all preferences which already have a pair | ||
.skip_while(|id| stable_matching.contains_key(id)) | ||
.next() | ||
) | ||
.map(|&id| id); | ||
|
||
if let Some(partner) = partner { // set partner | ||
stable_matching.insert(person.id, partner); | ||
stable_matching.insert(partner, person.id); | ||
} | ||
} | ||
stable_matching | ||
} | ||
|
||
fn main() { | ||
// create men vector | ||
let men: Vec<Person> = vec![ | ||
('A', vec!['E', 'G', 'F', 'H']), | ||
('B', vec!['F', 'H', 'E', 'F']), | ||
('C', vec!['F', 'E', 'H', 'G']), | ||
('D', vec!['E', 'H', 'F', 'G']) | ||
] | ||
.into_iter() | ||
.map(|(id, pref)| | ||
Person { | ||
id: PersonId(id), | ||
partner: None, | ||
preferences: pref.into_iter().map(PersonId).collect(), | ||
} | ||
).collect(); | ||
|
||
// create women vector | ||
let women: Vec<Person> = vec![ | ||
('E', vec!['A', 'D', 'C', 'B']), | ||
('F', vec!['D', 'B', 'A', 'C']), | ||
('G', vec!['D', 'A', 'C', 'B']), | ||
('H', vec!['B', 'A', 'D', 'C']) | ||
] | ||
.into_iter() | ||
.map(|(id, pref)| | ||
Person { | ||
id: PersonId(id), | ||
partner: None, | ||
preferences: pref.into_iter().map(PersonId).collect(), | ||
} | ||
).collect(); | ||
|
||
let people: Vec<Person> = men.iter().cloned().chain( | ||
women.iter().cloned()).collect(); | ||
|
||
println!("Men: \n"); | ||
for man in &men { | ||
println!("\t{}: {:?}", man.id, man.preferences.clone() | ||
// convert men.preference to vector of chars | ||
.into_iter() | ||
.map(|person| person.0) | ||
.collect::<Vec<char>>()); | ||
} | ||
println!("Women: \n"); | ||
for woman in &women { | ||
println!("\t{}: {:?}", woman.id, woman.preferences.clone() | ||
// convert women.preference to vector of chars | ||
.into_iter() | ||
.map(|person| person.0) | ||
.collect::<Vec<char>>()); | ||
} | ||
|
||
let stable_matching: HashMap<PersonId, PersonId> = gale_shapley(people); | ||
|
||
// display stable matches | ||
for man in men { | ||
let partner_id = stable_matching.get(&man.id); | ||
match partner_id { | ||
Some(p) => println!("{} + {}", man.id, p), | ||
None => () | ||
} | ||
} | ||
Comment on lines
+100
to
+106
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get the feeling that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @fanninpm How would we use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @n1trob4ct3r You can use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @fanninpm Yes that would be a problem too. Is there anything else? Is it ready for merging? |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you want to just derive debug, instead of manually implementing display, to simplify the entire code a bit. Even if you don't want to remove the Display implementation, deriving debug is never a bad practice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I now see that your code relies on the exact representation quite a bit, so then maybe just add a derive debug?