Move valid_residents to the scheduler impl and simplify it
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
use crate::{bounds::WorkloadBounds, config::UserConfig, schedule::MonthlySchedule, slot::Slot};
|
||||
use crate::{
|
||||
bounds::WorkloadBounds, config::UserConfig, schedule::MonthlySchedule,
|
||||
slot::Slot,
|
||||
};
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
@@ -41,15 +44,15 @@ impl Scheduler {
|
||||
}
|
||||
|
||||
// sort candidates by current workload, add rng for tie breakers
|
||||
let mut candidates = self.config.candidates(slot, schedule);
|
||||
candidates.sort_unstable_by_key(|&(resident, _)| {
|
||||
let workload = schedule.current_workload(resident);
|
||||
let mut valid_resident_ids = self.valid_residents(slot, schedule);
|
||||
valid_resident_ids.sort_unstable_by_key(|res_id| {
|
||||
let workload = schedule.current_workload(res_id);
|
||||
let tie_breaker: f64 = rand::rng().random();
|
||||
(workload, (tie_breaker * 1000.0) as usize)
|
||||
});
|
||||
|
||||
for (resident, _) in candidates {
|
||||
schedule.insert(slot, resident);
|
||||
for id in &valid_resident_ids {
|
||||
schedule.insert(slot, id);
|
||||
|
||||
if self.search(schedule, slot.next()) {
|
||||
log::trace!("Solution found, exiting recursive algorithm");
|
||||
@@ -61,6 +64,19 @@ impl Scheduler {
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
/// Return all valid residents for the current slot
|
||||
pub fn valid_residents(&self, slot: Slot, schedule: &MonthlySchedule) -> Vec<String> {
|
||||
let other_slot_resident_id = schedule.get_resident_id(&slot.other_position());
|
||||
|
||||
self.config
|
||||
.residents
|
||||
.iter()
|
||||
.filter(|r| Some(&r.id) != other_slot_resident_id)
|
||||
.filter(|r| !r.negative_shifts.contains(&slot.day))
|
||||
.map(|r| r.id.clone())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -121,11 +137,14 @@ mod tests {
|
||||
}
|
||||
|
||||
for r in &scheduler.config.residents {
|
||||
let workload = schedule.current_workload(r);
|
||||
let workload = schedule.current_workload(&r.id);
|
||||
let limit = *scheduler.bounds.max_workloads.get(&r.id).unwrap();
|
||||
assert!(workload <= limit as usize);
|
||||
}
|
||||
|
||||
println!("{}", schedule.pretty_print(&scheduler.config));
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_valid_residents(mut schedule: MonthlySchedule, scheduler: Scheduler) {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user