use solverforge_core::domain::{
EntityCollectionExtractor, EntityDescriptor, PlanningSolution, SolutionDescriptor,
};
use solverforge_core::score::SoftScore;
use solverforge_scoring::ScoreDirector;
use std::any::TypeId;
use super::EntityReference;
use crate::heuristic::selector::entity::FromSolutionEntitySelector;
use crate::heuristic::selector::mimic::{
MimicRecorder, MimicRecordingEntitySelector, MimicReplayingEntitySelector,
};
use crate::heuristic::selector::EntitySelector;
#[derive(Clone, Debug)]
struct Queen {
id: i64,
}
#[derive(Clone, Debug)]
struct NQueensSolution {
queens: Vec<Queen>,
score: Option<SoftScore>,
}
impl PlanningSolution for NQueensSolution {
type Score = SoftScore;
fn score(&self) -> Option<Self::Score> {
self.score
}
fn set_score(&mut self, score: Option<Self::Score>) {
self.score = score;
}
}
fn get_queens(s: &NQueensSolution) -> &Vec<Queen> {
&s.queens
}
fn get_queens_mut(s: &mut NQueensSolution) -> &mut Vec<Queen> {
&mut s.queens
}
fn create_test_director(n: usize) -> ScoreDirector<NQueensSolution, ()> {
let queens: Vec<_> = (0..n).map(|i| Queen { id: i as i64 }).collect();
let solution = NQueensSolution {
queens,
score: None,
};
let extractor = Box::new(EntityCollectionExtractor::new(
"Queen",
"queens",
get_queens,
get_queens_mut,
));
let entity_desc =
EntityDescriptor::new("Queen", TypeId::of::<Queen>(), "queens").with_extractor(extractor);
let descriptor = SolutionDescriptor::new("NQueensSolution", TypeId::of::<NQueensSolution>())
.with_entity(entity_desc);
ScoreDirector::simple(solution, descriptor, |s, _| s.queens.len())
}
#[test]
fn test_mimic_recording_selector() {
let director = create_test_director(3);
let solution = director.working_solution();
for (i, queen) in solution.queens.iter().enumerate() {
assert_eq!(queen.id, i as i64);
}
let recorder = MimicRecorder::new("test");
let child = FromSolutionEntitySelector::new(0);
let recording = MimicRecordingEntitySelector::new(child, recorder);
let entities: Vec<_> = recording.iter(&director).collect();
assert_eq!(entities.len(), 3);
assert_eq!(entities[0], EntityReference::new(0, 0));
assert_eq!(entities[1], EntityReference::new(0, 1));
assert_eq!(entities[2], EntityReference::new(0, 2));
}
#[test]
fn test_mimic_replaying_selector() {
let director = create_test_director(3);
let recorder = MimicRecorder::new("test");
let child = FromSolutionEntitySelector::new(0);
let recording = MimicRecordingEntitySelector::new(child, recorder.clone());
let replaying = MimicReplayingEntitySelector::new(recorder);
let mut recording_iter = recording.iter(&director);
let first = recording_iter.next().unwrap();
assert_eq!(first, EntityReference::new(0, 0));
let replayed: Vec<_> = replaying.iter(&director).collect();
assert_eq!(replayed.len(), 1);
assert_eq!(replayed[0], EntityReference::new(0, 0));
let second = recording_iter.next().unwrap();
assert_eq!(second, EntityReference::new(0, 1));
let replayed: Vec<_> = replaying.iter(&director).collect();
assert_eq!(replayed.len(), 1);
assert_eq!(replayed[0], EntityReference::new(0, 1));
}
#[test]
fn test_mimic_synchronized_iteration() {
let director = create_test_director(3);
let recorder = MimicRecorder::new("test");
let child = FromSolutionEntitySelector::new(0);
let recording = MimicRecordingEntitySelector::new(child, recorder.clone());
let replaying = MimicReplayingEntitySelector::new(recorder);
for recorded in recording.iter(&director) {
let replayed: Vec<_> = replaying.iter(&director).collect();
assert_eq!(replayed.len(), 1);
assert_eq!(replayed[0], recorded);
}
}
#[test]
fn test_mimic_empty_selector() {
let director = create_test_director(0);
let recorder = MimicRecorder::new("test");
let child = FromSolutionEntitySelector::new(0);
let recording = MimicRecordingEntitySelector::new(child, recorder.clone());
let replaying = MimicReplayingEntitySelector::new(recorder);
let entities: Vec<_> = recording.iter(&director).collect();
assert_eq!(entities.len(), 0);
let replayed: Vec<_> = replaying.iter(&director).collect();
assert_eq!(replayed.len(), 0);
}