use core::{
fmt::Debug,
ops::{Div, Mul, Sub},
};
use mop_common::rand::distributions::uniform::SampleUniform;
use mop_facades::{
opt_problem::{BorrowAsRef, Cstr, Obj, OptProblem, OptProblemResults, Pct},
OptFacadeSolver,
};
use mop_solvers::{
genetic_algorithm::{
operators::{crossover::Crossover, mating_selection::MatingSelection, mutation::Mutation},
spea2::Spea2,
GeneticAlgorithmParams,
},
prelude::{NumCast, One, Pow, Zero},
Solver,
};
#[derive(Debug)]
pub struct Spea2Adapter<GAPC, GAPM, GAPMS, MPC, MPD, MPO, MPOR, MPS>
where
MPOR: Debug,
{
partial: Option<(Pct, GeneticAlgorithmParams<GAPC, GAPM, GAPMS>)>,
spea2: Option<Spea2<GAPC, GAPM, GAPMS, MPC, MPD, MPO, MPOR, MPS>>,
}
impl<GAPC, GAPM, GAPMS, MPC, MPD, MPO, MPOR, MPS>
Spea2Adapter<GAPC, GAPM, GAPMS, MPC, MPD, MPO, MPOR, MPS>
where
MPOR: Debug
+ Copy
+ Div<MPOR, Output = MPOR>
+ Mul<MPOR, Output = MPOR>
+ NumCast
+ One
+ PartialOrd
+ Pow<MPOR, Output = MPOR>
+ Send
+ Sub<MPOR, Output = MPOR>
+ Sync
+ Zero,
{
pub fn new(archive_size: Pct, gap: GeneticAlgorithmParams<GAPC, GAPM, GAPMS>) -> Self {
Spea2Adapter {
partial: Some((archive_size, gap)),
spea2: None,
}
}
}
impl<'a, GAPC, GAPM, GAPMS, MPC, MPD, MPO, MPOR, MPS> Solver
for Spea2Adapter<GAPC, GAPM, GAPMS, MPC, MPD, MPO, MPOR, MPS>
where
GAPC: Crossover<OptProblemResults<MPOR, MPS>>,
GAPM: Mutation<MPD, OptProblemResults<MPOR, MPS>>,
GAPMS: MatingSelection<[MPO], OptProblemResults<MPOR, MPS>>,
MPC: BorrowAsRef<dyn Cstr<MPS> + 'a>,
MPD: Send + Sync,
MPO: BorrowAsRef<dyn Obj<MPOR, MPS> + 'a>,
MPOR: Copy
+ Debug
+ Div<MPOR, Output = MPOR>
+ Mul<MPOR, Output = MPOR>
+ NumCast
+ One
+ PartialOrd
+ Pow<MPOR, Output = MPOR>
+ SampleUniform
+ Send
+ Sub<MPOR, Output = MPOR>
+ Sync
+ Zero,
MPS: Copy + Send + Sync,
{
type Rslt = OptProblem<MPC, MPD, MPO, MPOR, MPS>;
fn do_work_after(&mut self) {
self.spea2.as_mut().unwrap().do_work_after();
}
fn do_work_before(&mut self) {
self.spea2.as_mut().unwrap().do_work_before();
}
fn initialize(&mut self) {
self.spea2.as_mut().unwrap().initialize();
}
fn into_result(self) -> Self::Rslt {
self.spea2.unwrap().into_result()
}
fn result(&self) -> &Self::Rslt {
self.spea2.as_ref().unwrap().result()
}
fn terminate(&mut self) {
self.spea2.as_mut().unwrap().terminate()
}
}
impl<'a, GAPC, GAPM, GAPMS, MPC, MPD, MPO, MPOR, MPS> OptFacadeSolver<MPC, MPD, MPO, MPOR, MPS>
for Spea2Adapter<GAPC, GAPM, GAPMS, MPC, MPD, MPO, MPOR, MPS>
where
GAPC: Crossover<OptProblemResults<MPOR, MPS>>,
GAPM: Mutation<MPD, OptProblemResults<MPOR, MPS>>,
GAPMS: MatingSelection<[MPO], OptProblemResults<MPOR, MPS>>,
MPC: BorrowAsRef<dyn Cstr<MPS> + 'a>,
MPD: Send + Sync,
MPO: BorrowAsRef<dyn Obj<MPOR, MPS> + 'a>,
MPOR: Copy
+ Debug
+ Div<MPOR, Output = MPOR>
+ Mul<MPOR, Output = MPOR>
+ NumCast
+ One
+ PartialOrd
+ Pow<MPOR, Output = MPOR>
+ SampleUniform
+ Send
+ Sub<MPOR, Output = MPOR>
+ Sync
+ Zero,
MPS: Copy + Send + Sync,
{
fn set_opt_problem(&mut self, op: OptProblem<MPC, MPD, MPO, MPOR, MPS>) {
let (archive_size, spea2) = self.partial.take().unwrap();
self.spea2 = Some(Spea2::new(archive_size, spea2, op))
}
}