use crate::api::constraint_set::IncrementalConstraint;
use crate::constraint::IncrementalQuadConstraint;
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_quad_constraint_evaluate() {
let constraint = IncrementalQuadConstraint::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| true,
|_s: &Solution, _a: usize, _b: usize, _c: usize, _d: usize| SoftScore::of(1),
false,
);
let solution = Solution {
tasks: vec![
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_quad_constraint_multiple_quads() {
let constraint = IncrementalQuadConstraint::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| true,
|_s: &Solution, _a: usize, _b: usize, _c: usize, _d: 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 },
],
};
assert_eq!(constraint.evaluate(&solution), SoftScore::of(-5));
}
#[test]
fn test_quad_constraint_incremental() {
let mut constraint = IncrementalQuadConstraint::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| true,
|_s: &Solution, _a: usize, _b: usize, _c: usize, _d: usize| SoftScore::of(1),
false,
);
let solution = Solution {
tasks: vec![
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_quad_constraint_reward() {
let constraint = IncrementalQuadConstraint::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| true,
|_s: &Solution, _a: usize, _b: usize, _c: usize, _d: usize| SoftScore::of(5),
false,
);
let solution = Solution {
tasks: vec![
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
Task { team: 1 },
],
};
assert_eq!(constraint.evaluate(&solution), SoftScore::of(5));
}