use crate::api::constraint_set::IncrementalConstraint;
use crate::constraint::IncrementalPentaConstraint;
use solverforge_core::score::SoftScore;
use solverforge_core::{ConstraintRef, ImpactType};
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
struct Task {
team: u32,
}
#[derive(Clone)]
struct Solution {
tasks: Vec<Task>,
}
fn tasks(s: &Solution) -> &[Task] {
s.tasks.as_slice()
}
#[test]
fn test_penta_constraint_evaluate() {
let constraint = IncrementalPentaConstraint::new(
ConstraintRef::new("", "Cluster"),
ImpactType::Penalty,
tasks,
|_s: &Solution, t: &Task, _idx: usize| t.team,
|_s: &Solution, _a: &Task, _b: &Task, _c: &Task, _d: &Task, _e: &Task| true,
|_s: &Solution, _a: usize, _b: usize, _c: usize, _d: usize, _e: usize| SoftScore::of(1),
false,
);
let solution = Solution {
tasks: vec![
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
Task { team: 2 },
],
};
assert_eq!(constraint.evaluate(&solution), SoftScore::of(-1));
}
#[test]
fn test_penta_constraint_multiple_pentas() {
let constraint = IncrementalPentaConstraint::new(
ConstraintRef::new("", "Cluster"),
ImpactType::Penalty,
tasks,
|_s: &Solution, t: &Task, _idx: usize| t.team,
|_s: &Solution, _a: &Task, _b: &Task, _c: &Task, _d: &Task, _e: &Task| true,
|_s: &Solution, _a: usize, _b: usize, _c: usize, _d: usize, _e: usize| SoftScore::of(1),
false,
);
let solution = Solution {
tasks: vec![
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
],
};
assert_eq!(constraint.evaluate(&solution), SoftScore::of(-6));
}
#[test]
fn test_penta_constraint_incremental() {
let mut constraint = IncrementalPentaConstraint::new(
ConstraintRef::new("", "Cluster"),
ImpactType::Penalty,
tasks,
|_s: &Solution, t: &Task, _idx: usize| t.team,
|_s: &Solution, _a: &Task, _b: &Task, _c: &Task, _d: &Task, _e: &Task| true,
|_s: &Solution, _a: usize, _b: usize, _c: usize, _d: usize, _e: usize| SoftScore::of(1),
false,
);
let solution = Solution {
tasks: vec![
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
],
};
let total = constraint.initialize(&solution);
assert_eq!(total, SoftScore::of(-1));
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_penta_constraint_reward() {
let constraint = IncrementalPentaConstraint::new(
ConstraintRef::new("", "Team bonus"),
ImpactType::Reward,
tasks,
|_s: &Solution, t: &Task, _idx: usize| t.team,
|_s: &Solution, _a: &Task, _b: &Task, _c: &Task, _d: &Task, _e: &Task| true,
|_s: &Solution, _a: usize, _b: usize, _c: usize, _d: usize, _e: usize| SoftScore::of(5),
false,
);
let solution = Solution {
tasks: vec![
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
],
};
assert_eq!(constraint.evaluate(&solution), SoftScore::of(5));
}