1 个不稳定版本
0.1.0 | 2020 年 11 月 13 日 |
---|
#1311 在 数学 分类中
36KB
592 行
Matchmaker
这个库可以用来公平地将学生匹配到类别(或活动)。或将学生匹配到学校。或将任何事物匹配到其他事物。
背景
这个库解决的匹配问题在数学上被称为居民问题,是稳定婚姻问题的一个子集。有多个已知的算法可以解决这个问题,每个算法都有其优缺点。关于这个主题的更多信息,请参阅阿姆斯特丹中学入学问题匹配算法。
算法
目前,这个库只实现了 延迟接受 - 单一平局处理
算法。这个库的设计允许实现其他算法(只需要完成它)。
使用方法
默认匹配
学生被分配到多个类别,但每个学生只能被分配一次。
use matchmaker::da_stb::match_students;
use matchmaker::{Category, Student};
use rand::thread_rng;
use std::collections::VecDeque;
// Create categories
let cooking = Category::new("Cooking", 10);
let reading = Category::new("Reading", 10);
let walking = Category::new("Walking", 5);
// Create student Bert
// Bert wishes to be placed in category cooking or reading (in that order)
let bert = Student::new(
"Bert",
VecDeque::from(vec![cooking.clone(), reading.clone()]),
Vec::new(),
);
// Create student Suze
// Suze wishes to be placed in category cooking or reading (in that order),
// but does not wish to be placed in category walking
let suze = Student::new(
"Suze",
VecDeque::from(vec![reading.clone(), cooking.clone()]),
Vec::from([walking.clone()]),
);
let mut rng = thread_rng();
let categories = Vec::from([cooking, reading, walking]);
let match_result = match_students(Vec::from([bert, suze]), &categories, &mut rng);
println!("Students matched to categories:");
println!();
for category in &categories {
println!("{}:", &category.name);
for student in match_result
.placed
.get(&category.name)
.unwrap_or(&Vec::new())
{
println!(" - {}", &student.name);
}
}
if match_result.not_placable.is_empty() {
println!();
println!("All students could be placed.");
}
这将产生以下结果
Students matched to categories:
Cooking:
- Bert
Reading:
- Suze
Walking:
All students could be placed.
将学生放置在多个类别中
学生被分配到多个类别。一个学生可以分配到多个类别。
示例
use matchmaker::{Category, Student};
use matchmaker::da_stb::match_students_to_multiple_categories;
use rand::thread_rng;
use std::collections::VecDeque;
// Create categories
let cooking = Category::new("Cooking", 10);
let reading = Category::new("Reading", 10);
let walking = Category::new("Walking", 5);
// Create student Bert
// Bert wishes to be placed in category cooking or reading (in that order)
let bert = Student::new(
"Bert",
VecDeque::from(vec![cooking.clone(), reading.clone()]),
Vec::new(),
);
// Create student Suze
// Suze wishes to be placed in category cooking or reading (in that order),
// but does not wish to be placed in category walking
let suze = Student::new(
"Suze",
VecDeque::from(vec![cooking.clone(), reading.clone()]),
Vec::from([walking.clone()]),
);
let mut rng = thread_rng();
let categories = Vec::from([cooking, reading, walking]);
let match_result = match_students_to_multiple_categories(
Vec::from([bert, suze]),
&categories,
&mut rng);
println!("Students matched to categories:");
println!();
for category in &categories {
println!("{}:", &category.name);
for student in match_result
.placed
.get(&category.name)
.unwrap_or(&Vec::new())
{
println!(" - {}", &student.name);
}
}
if match_result.not_placable.is_empty() {
println!();
println!("All students could be placed.");
}
这将产生以下结果
Students matched to categories:
Cooking:
- Suze
- Bert
Reading:
- Bert
- Suze
Walking:
- Bert
All students could be placed.
// 版权 (c) 2020 Delirious Penguin // // 此源代码形式受 Mozilla 公共许可证,第 2.0 版的约束。如果没有与此文件一起分发 MPL 复制品,您可以从 http://mozilla.org/MPL/2.0/ 获得一份。
依赖项
~1–1.6MB
~34K SLoC