use std::marker::PhantomData;
use solverforge_core::domain::PlanningSolution;
use solverforge_scoring::Director;
use crate::heuristic::{Move, MoveSelector};
use crate::phase::localsearch::{
AcceptedCountForager, Acceptor, HillClimbingAcceptor, LateAcceptanceAcceptor,
LocalSearchForager, LocalSearchPhase, SimulatedAnnealingAcceptor, TabuSearchAcceptor,
};
use super::super::PhaseFactory;
pub struct LocalSearchPhaseFactory<S, M, MS, A, Fo>
where
S: PlanningSolution,
M: Move<S>,
MS: MoveSelector<S, M>,
A: Acceptor<S>,
Fo: LocalSearchForager<S, M>,
{
move_selector: MS,
acceptor: A,
forager: Fo,
step_limit: Option<u64>,
_marker: PhantomData<fn() -> (S, M)>,
}
impl<S, M, MS, A, Fo> LocalSearchPhaseFactory<S, M, MS, A, Fo>
where
S: PlanningSolution,
M: Move<S>,
MS: MoveSelector<S, M>,
A: Acceptor<S>,
Fo: LocalSearchForager<S, M>,
{
pub fn new(move_selector: MS, acceptor: A, forager: Fo) -> Self {
Self {
move_selector,
acceptor,
forager,
step_limit: None,
_marker: PhantomData,
}
}
pub fn with_step_limit(mut self, limit: u64) -> Self {
self.step_limit = Some(limit);
self
}
}
impl<S, M, MS> LocalSearchPhaseFactory<S, M, MS, HillClimbingAcceptor, AcceptedCountForager<S>>
where
S: PlanningSolution,
M: Move<S>,
MS: MoveSelector<S, M>,
{
pub fn hill_climbing(move_selector: MS) -> Self {
Self::new(
move_selector,
HillClimbingAcceptor::new(),
AcceptedCountForager::new(1),
)
}
}
impl<S, M, MS> LocalSearchPhaseFactory<S, M, MS, TabuSearchAcceptor<S>, AcceptedCountForager<S>>
where
S: PlanningSolution,
M: Move<S>,
MS: MoveSelector<S, M>,
{
pub fn tabu_search(move_selector: MS, tabu_size: usize) -> Self {
Self::new(
move_selector,
TabuSearchAcceptor::new(tabu_size),
AcceptedCountForager::new(1),
)
}
}
impl<S, M, MS>
LocalSearchPhaseFactory<S, M, MS, SimulatedAnnealingAcceptor, AcceptedCountForager<S>>
where
S: PlanningSolution,
M: Move<S>,
MS: MoveSelector<S, M>,
{
pub fn simulated_annealing(move_selector: MS, starting_temp: f64, decay_rate: f64) -> Self {
Self::new(
move_selector,
SimulatedAnnealingAcceptor::new(starting_temp, decay_rate),
AcceptedCountForager::new(1),
)
}
}
impl<S, M, MS> LocalSearchPhaseFactory<S, M, MS, LateAcceptanceAcceptor<S>, AcceptedCountForager<S>>
where
S: PlanningSolution,
M: Move<S>,
MS: MoveSelector<S, M>,
{
pub fn late_acceptance(move_selector: MS, size: usize) -> Self {
Self::new(
move_selector,
LateAcceptanceAcceptor::new(size),
AcceptedCountForager::new(1),
)
}
}
impl<S, D, M, MS, A, Fo> PhaseFactory<S, D> for LocalSearchPhaseFactory<S, M, MS, A, Fo>
where
S: PlanningSolution,
D: Director<S>,
M: Move<S> + Send + Sync + 'static,
MS: MoveSelector<S, M> + Clone + Send + Sync + 'static,
A: Acceptor<S> + Clone + Send + Sync + 'static,
Fo: LocalSearchForager<S, M> + Clone + Send + Sync + 'static,
{
type Phase = LocalSearchPhase<S, M, MS, A, Fo>;
fn create(&self) -> Self::Phase {
LocalSearchPhase::new(
self.move_selector.clone(),
self.acceptor.clone(),
self.forager.clone(),
self.step_limit,
)
}
}