use solverforge_core::score::SoftScore;
use solverforge_core::{ConstraintRef, ImpactType};
use crate::api::constraint_set::IncrementalConstraint;
use crate::constraint::grouped::GroupedUniConstraint;
use crate::stream::collection_extract::vec;
use crate::stream::collector::count;
use crate::stream::filter::TrueFilter;
#[derive(Clone)]
struct GroupedShift {
employee_id: usize,
}
#[derive(Clone)]
struct GroupedSolution {
shifts: Vec<GroupedShift>,
}
#[test]
fn test_grouped_constraint_evaluate() {
let constraint = GroupedUniConstraint::new(
ConstraintRef::new("", "Workload"),
ImpactType::Penalty,
vec(|s: &GroupedSolution| &s.shifts),
TrueFilter,
|shift: &GroupedShift| shift.employee_id,
count::<GroupedShift>(),
|count: &usize| SoftScore::of((*count * *count) as i64),
false,
);
let solution = GroupedSolution {
shifts: vec![
GroupedShift { employee_id: 1 },
GroupedShift { employee_id: 1 },
GroupedShift { employee_id: 1 },
GroupedShift { employee_id: 2 },
],
};
assert_eq!(constraint.evaluate(&solution), SoftScore::of(-10));
}
#[test]
fn test_grouped_constraint_incremental() {
let mut constraint = GroupedUniConstraint::new(
ConstraintRef::new("", "Workload"),
ImpactType::Penalty,
vec(|s: &GroupedSolution| &s.shifts),
TrueFilter,
|shift: &GroupedShift| shift.employee_id,
count::<GroupedShift>(),
|count: &usize| SoftScore::of(*count as i64),
false,
);
let solution = GroupedSolution {
shifts: vec![
GroupedShift { employee_id: 1 },
GroupedShift { employee_id: 1 },
GroupedShift { employee_id: 2 },
],
};
let total = constraint.initialize(&solution);
assert_eq!(total, SoftScore::of(-3));
let delta = constraint.on_retract(&solution, 0, 0);
assert_eq!(delta, SoftScore::of(1));
let delta = constraint.on_insert(&solution, 0, 0);
assert_eq!(delta, SoftScore::of(-1));
}
#[test]
fn test_grouped_constraint_reward() {
let constraint = GroupedUniConstraint::new(
ConstraintRef::new("", "Collaboration"),
ImpactType::Reward,
vec(|s: &GroupedSolution| &s.shifts),
TrueFilter,
|shift: &GroupedShift| shift.employee_id,
count::<GroupedShift>(),
|count: &usize| SoftScore::of(*count as i64),
false,
);
let solution = GroupedSolution {
shifts: vec![
GroupedShift { employee_id: 1 },
GroupedShift { employee_id: 1 },
],
};
assert_eq!(constraint.evaluate(&solution), SoftScore::of(2));
}