use crate::{
components::{
boundary, initialization, misc, mutation, recombination, selection, utils, Block,
},
conditions::{self, LessThanN, RandomChance},
configuration::ConfigurationBuilder,
identifier::{Global, Identifier, A, B},
lens::common::PopulationSizeLens,
logging::Logger,
problems::LimitedVectorProblem,
Component, Condition, Configuration, ExecResult, SingleObjectiveProblem,
};
pub struct RealProblemParameters {
pub initial_population_size: u32,
pub mole_coll: f64,
pub kinetic_energy_lr: f64,
pub alpha: u32,
pub beta: f64,
pub initial_kinetic_energy: f64,
pub buffer: f64,
pub on_wall_deviation: f64,
pub decomposition_deviation: f64,
}
pub fn real_cro<P>(
params: RealProblemParameters,
condition: Box<dyn Condition<P>>,
) -> ExecResult<Configuration<P>>
where
P: SingleObjectiveProblem + LimitedVectorProblem<Element = f64>,
{
let RealProblemParameters {
initial_population_size,
mole_coll,
kinetic_energy_lr,
alpha,
beta,
initial_kinetic_energy,
buffer,
on_wall_deviation,
decomposition_deviation,
} = params;
Ok(Configuration::builder()
.do_(initialization::RandomSpread::new(initial_population_size))
.evaluate()
.update_best_individual()
.do_(cro::<P, Global>(
Parameters {
mole_coll,
kinetic_energy_lr,
initial_kinetic_energy,
buffer,
single_mole_selection: selection::RandomWithoutRepetition::new(1),
decomposition_criterion: conditions::cro::DecompositionCriterion::new(alpha),
decomposition: Block::new([
utils::populations::DuplicatePopulation::new(),
mutation::NormalMutation::<A>::new_with_id(decomposition_deviation, 0.5),
]),
on_wall_ineffective_collision: mutation::NormalMutation::<B>::new_with_id(
on_wall_deviation,
1.0,
),
double_mole_selection: selection::RandomWithoutRepetition::new(2),
synthesis_criterion: conditions::cro::SynthesisCriterion::new(beta),
synthesis: recombination::UniformCrossover::new_insert_single(1.),
intermolecular_ineffective_collision: mutation::UniformMutation::new_bound(1.),
constraints: boundary::Saturation::new(),
},
condition,
))
.build())
}
pub struct Parameters<P> {
pub mole_coll: f64,
pub kinetic_energy_lr: f64,
pub initial_kinetic_energy: f64,
pub buffer: f64,
pub single_mole_selection: Box<dyn Component<P>>,
pub decomposition_criterion: Box<dyn Condition<P>>,
pub decomposition: Box<dyn Component<P>>,
pub on_wall_ineffective_collision: Box<dyn Component<P>>,
pub double_mole_selection: Box<dyn Component<P>>,
pub synthesis_criterion: Box<dyn Condition<P>>,
pub synthesis: Box<dyn Component<P>>,
pub intermolecular_ineffective_collision: Box<dyn Component<P>>,
pub constraints: Box<dyn Component<P>>,
}
pub fn cro<P, I>(params: Parameters<P>, condition: Box<dyn Condition<P>>) -> Box<dyn Component<P>>
where
P: SingleObjectiveProblem,
I: Identifier,
{
let Parameters {
mole_coll,
kinetic_energy_lr,
initial_kinetic_energy,
buffer,
single_mole_selection,
decomposition_criterion,
decomposition,
on_wall_ineffective_collision,
double_mole_selection,
synthesis_criterion,
synthesis,
intermolecular_ineffective_collision,
constraints,
} = params;
let elementary_reaction = |builder: ConfigurationBuilder<P>, reaction, update| {
builder
.do_(reaction)
.do_(constraints.clone())
.evaluate_with::<I>()
.update_best_individual()
.do_(update)
};
Configuration::builder()
.do_(misc::cro::ChemicalReactionInit::new(
initial_kinetic_energy,
buffer,
))
.while_(condition, |builder| {
builder
.if_else_(
RandomChance::new(mole_coll)
| LessThanN::new(2, PopulationSizeLens::<P>::new()),
|builder| {
builder
.do_(single_mole_selection)
.do_(selection::All::new())
.if_else_(
decomposition_criterion,
|builder| {
elementary_reaction(
builder,
decomposition,
misc::cro::DecompositionUpdate::new(),
)
},
|builder| {
elementary_reaction(
builder,
on_wall_ineffective_collision,
misc::cro::OnWallIneffectiveCollisionUpdate::new(
kinetic_energy_lr,
),
)
},
)
},
|builder| {
builder
.do_(double_mole_selection)
.do_(selection::All::new())
.if_else_(
synthesis_criterion,
|builder| {
elementary_reaction(
builder,
synthesis,
misc::cro::SynthesisUpdate::new(),
)
},
|builder| {
elementary_reaction(
builder,
intermolecular_ineffective_collision,
misc::cro::IntermolecularIneffectiveCollisionUpdate::new(),
)
},
)
},
)
.do_(Logger::new())
})
.build_component()
}