use super::*;
use solverforge_core::domain::PlanningSolution;
use solverforge_core::score::SoftScore;
#[derive(Clone, Debug)]
struct DummySolution {
score: Option<SoftScore>,
}
impl PlanningSolution for DummySolution {
type Score = SoftScore;
fn score(&self) -> Option<Self::Score> {
self.score
}
fn set_score(&mut self, score: Option<Self::Score>) {
self.score = score;
}
}
#[test]
fn test_hill_climbing_accepts_improving() {
let mut acceptor: Box<dyn Acceptor<DummySolution>> = Box::new(HillClimbingAcceptor::new());
assert!(acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-5)));
}
#[test]
fn test_hill_climbing_rejects_worsening() {
let mut acceptor: Box<dyn Acceptor<DummySolution>> = Box::new(HillClimbingAcceptor::new());
assert!(!acceptor.is_accepted(&SoftScore::of(-5), &SoftScore::of(-10)));
}
#[test]
fn test_hill_climbing_rejects_equal() {
let mut acceptor: Box<dyn Acceptor<DummySolution>> = Box::new(HillClimbingAcceptor::new());
assert!(!acceptor.is_accepted(&SoftScore::of(-5), &SoftScore::of(-5)));
}
#[test]
fn test_simulated_annealing_accepts_improving() {
let mut acceptor: Box<dyn Acceptor<DummySolution>> =
Box::new(SimulatedAnnealingAcceptor::new(1.0, 0.99));
assert!(acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-5)));
}
#[test]
fn test_late_acceptance_history() {
let mut acceptor = LateAcceptanceAcceptor::<DummySolution>::new(5);
acceptor.phase_started(&SoftScore::of(-10));
assert!(acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-5)));
assert!(acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-10)));
assert!(!acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-15)));
}
#[test]
fn test_tabu_search_accepts_improving() {
let mut acceptor = TabuSearchAcceptor::<DummySolution>::new(5);
acceptor.phase_started(&SoftScore::of(-10));
assert!(acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-5)));
}
#[test]
fn test_tabu_search_accepts_equal() {
let mut acceptor = TabuSearchAcceptor::<DummySolution>::new(5);
acceptor.phase_started(&SoftScore::of(-10));
assert!(acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-10)));
}
#[test]
fn test_tabu_search_rejects_tabu() {
let mut acceptor = TabuSearchAcceptor::<DummySolution>::new(5);
acceptor.phase_started(&SoftScore::of(-10));
acceptor.step_ended(&SoftScore::of(-5));
assert!(!acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-5)));
}
#[test]
fn test_tabu_search_aspiration_accepts_new_best() {
let mut acceptor = TabuSearchAcceptor::<DummySolution>::new(5);
acceptor.phase_started(&SoftScore::of(-10));
acceptor.step_ended(&SoftScore::of(-3));
assert!(acceptor.is_accepted(&SoftScore::of(-5), &SoftScore::of(-2)));
}
#[test]
fn test_tabu_search_without_aspiration() {
let mut acceptor = TabuSearchAcceptor::<DummySolution>::without_aspiration(5);
acceptor.phase_started(&SoftScore::of(-10));
acceptor.step_ended(&SoftScore::of(-3));
assert!(!acceptor.is_accepted(&SoftScore::of(-5), &SoftScore::of(-3)));
}
#[test]
fn test_tabu_search_tabu_list_eviction() {
let mut acceptor = TabuSearchAcceptor::<DummySolution>::new(3);
acceptor.phase_started(&SoftScore::of(-10));
acceptor.step_ended(&SoftScore::of(-9));
acceptor.step_ended(&SoftScore::of(-8));
acceptor.step_ended(&SoftScore::of(-7));
assert!(!acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-9)));
assert!(!acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-8)));
assert!(!acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-7)));
acceptor.step_ended(&SoftScore::of(-6));
assert!(acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-9)));
assert!(!acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-8)));
assert!(!acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-7)));
assert!(!acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-6)));
}
#[test]
fn test_tabu_search_phase_ended_clears_tabu() {
let mut acceptor = TabuSearchAcceptor::<DummySolution>::new(5);
acceptor.phase_started(&SoftScore::of(-10));
acceptor.step_ended(&SoftScore::of(-5));
assert!(!acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-5)));
acceptor.phase_ended();
acceptor.phase_started(&SoftScore::of(-10));
assert!(acceptor.is_accepted(&SoftScore::of(-10), &SoftScore::of(-5)));
}
#[test]
fn test_entity_tabu_accepts_improving() {
let mut acceptor = EntityTabuAcceptor::new(5);
<EntityTabuAcceptor as Acceptor<DummySolution>>::phase_started(
&mut acceptor,
&SoftScore::of(-10),
);
assert!(
<EntityTabuAcceptor as Acceptor<DummySolution>>::is_accepted(
&mut acceptor,
&SoftScore::of(-10),
&SoftScore::of(-5)
)
);
}
#[test]
fn test_entity_tabu_accepts_equal() {
let mut acceptor = EntityTabuAcceptor::new(5);
<EntityTabuAcceptor as Acceptor<DummySolution>>::phase_started(
&mut acceptor,
&SoftScore::of(-10),
);
assert!(
<EntityTabuAcceptor as Acceptor<DummySolution>>::is_accepted(
&mut acceptor,
&SoftScore::of(-10),
&SoftScore::of(-10)
)
);
}
#[test]
fn test_entity_tabu_rejects_worsening() {
let mut acceptor = EntityTabuAcceptor::new(5);
<EntityTabuAcceptor as Acceptor<DummySolution>>::phase_started(
&mut acceptor,
&SoftScore::of(-10),
);
assert!(
!<EntityTabuAcceptor as Acceptor<DummySolution>>::is_accepted(
&mut acceptor,
&SoftScore::of(-5),
&SoftScore::of(-10)
)
);
}
#[test]
fn test_entity_tabu_tracking() {
let mut acceptor = EntityTabuAcceptor::new(3);
<EntityTabuAcceptor as Acceptor<DummySolution>>::phase_started(
&mut acceptor,
&SoftScore::of(-10),
);
<EntityTabuAcceptor as Acceptor<DummySolution>>::step_started(&mut acceptor);
acceptor.record_entity_move(1);
acceptor.record_entity_move(2);
<EntityTabuAcceptor as Acceptor<DummySolution>>::step_ended(&mut acceptor, &SoftScore::of(-5));
assert!(acceptor.is_entity_tabu(1));
assert!(acceptor.is_entity_tabu(2));
assert!(!acceptor.is_entity_tabu(3));
}
#[test]
fn test_entity_tabu_eviction() {
let mut acceptor = EntityTabuAcceptor::new(3);
<EntityTabuAcceptor as Acceptor<DummySolution>>::phase_started(
&mut acceptor,
&SoftScore::of(-10),
);
<EntityTabuAcceptor as Acceptor<DummySolution>>::step_started(&mut acceptor);
acceptor.record_entity_move(1);
<EntityTabuAcceptor as Acceptor<DummySolution>>::step_ended(&mut acceptor, &SoftScore::of(-9));
<EntityTabuAcceptor as Acceptor<DummySolution>>::step_started(&mut acceptor);
acceptor.record_entity_move(2);
<EntityTabuAcceptor as Acceptor<DummySolution>>::step_ended(&mut acceptor, &SoftScore::of(-8));
<EntityTabuAcceptor as Acceptor<DummySolution>>::step_started(&mut acceptor);
acceptor.record_entity_move(3);
<EntityTabuAcceptor as Acceptor<DummySolution>>::step_ended(&mut acceptor, &SoftScore::of(-7));
assert!(acceptor.is_entity_tabu(1));
assert!(acceptor.is_entity_tabu(2));
assert!(acceptor.is_entity_tabu(3));
<EntityTabuAcceptor as Acceptor<DummySolution>>::step_started(&mut acceptor);
acceptor.record_entity_move(4);
<EntityTabuAcceptor as Acceptor<DummySolution>>::step_ended(&mut acceptor, &SoftScore::of(-6));
assert!(!acceptor.is_entity_tabu(1));
assert!(acceptor.is_entity_tabu(2));
assert!(acceptor.is_entity_tabu(3));
assert!(acceptor.is_entity_tabu(4));
}
#[test]
fn test_entity_tabu_phase_ended_clears() {
let mut acceptor = EntityTabuAcceptor::new(5);
<EntityTabuAcceptor as Acceptor<DummySolution>>::phase_started(
&mut acceptor,
&SoftScore::of(-10),
);
<EntityTabuAcceptor as Acceptor<DummySolution>>::step_started(&mut acceptor);
acceptor.record_entity_move(1);
<EntityTabuAcceptor as Acceptor<DummySolution>>::step_ended(&mut acceptor, &SoftScore::of(-5));
assert!(acceptor.is_entity_tabu(1));
<EntityTabuAcceptor as Acceptor<DummySolution>>::phase_ended(&mut acceptor);
assert!(!acceptor.is_entity_tabu(1));
}