mop-adapters 0.0.4

Solver adapters for MOP
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))
    }
}