pub struct EdaStrategy<B: Backend, M> { /* private fields */ }Expand description
Generic estimation-of-distribution strategy.
Drives the fit → sample loop of any ProbabilityModel. The strategy
itself is stateless (the model is held by value; all mutable generation
state lives in the returned EdaState), so it slots straight into
EvolutionaryHarness.
Type parameter M must implement ProbabilityModel<B>; in practice
this is one of UnivariateGaussian, UnivariateBernoulli,
CompactGenetic, DependencyChain, or BayesianNetwork.
§Example
use burn::backend::Flex;
use rlevo_evolution::algorithms::eda::{EdaParams, EdaStrategy, UnivariateGaussian};
use rlevo_evolution::algorithms::eda::univariate_gaussian::UnivariateGaussianParams;
use rlevo_core::bounds::Bounds;
let strategy = EdaStrategy::<Flex, _>::new(UnivariateGaussian);
let params = EdaParams {
pop_size: 32,
selection_ratio: 0.5,
bounds: Some(Bounds::new(-5.12, 5.12)),
model: UnivariateGaussianParams::default_for(8),
};
let _ = (strategy, params);Implementations§
Trait Implementations§
Source§impl<B: Backend, M: ProbabilityModel<B>> Strategy<B> for EdaStrategy<B, M>
impl<B: Backend, M: ProbabilityModel<B>> Strategy<B> for EdaStrategy<B, M>
Source§fn init(
&self,
params: &Self::Params,
rng: &mut dyn Rng,
device: &<B as BackendTypes>::Device,
) -> Self::State
fn init( &self, params: &Self::Params, rng: &mut dyn Rng, device: &<B as BackendTypes>::Device, ) -> Self::State
Build the initial state.
Fits the model’s prior from params.model (passing prev = None and
empty 0 × 0 / length-0 population and fitness tensors, per the
ProbabilityModel invariants). The rng is unused — the prior is
deterministic. The best-so-far trackers start empty.
§Panics
Debug-asserts that params.selection_ratio lies strictly in (0, 1).
A ratio of 0.0 would select no parents and a ratio of 1.0 would
defeat truncation selection entirely.
Source§fn ask(
&self,
params: &Self::Params,
state: &Self::State,
rng: &mut dyn Rng,
device: &<B as BackendTypes>::Device,
) -> (Self::Genome, Self::State)
fn ask( &self, params: &Self::Params, state: &Self::State, rng: &mut dyn Rng, device: &<B as BackendTypes>::Device, ) -> (Self::Genome, Self::State)
Sample the next candidate population from the current model.
Draws exactly one u64 from rng to seed a per-generation
SeedPurpose::EdaSampling stream, samples params.pop_size
individuals from the model through that host stream, and applies the
optional params.bounds clamp. The state is returned unchanged.
Source§fn tell(
&self,
params: &Self::Params,
population: Self::Genome,
fitness: Tensor<B, 1>,
state: Self::State,
_rng: &mut dyn Rng,
) -> (Self::State, StrategyMetrics)
fn tell( &self, params: &Self::Params, population: Self::Genome, fitness: Tensor<B, 1>, state: Self::State, _rng: &mut dyn Rng, ) -> (Self::State, StrategyMetrics)
Consume the population’s fitness and refit the model.
Pulls fitness to host, sanitizes NaN → −inf (worst under the
maximise convention) via the crate’s sanitize_fitness helper,
updates the best-so-far tracker, truncation-selects the best k rows
(descending fitness order, with
k = ceil(selection_ratio · pop_size) clamped to [2, pop_size]),
and refits the model to them (passing prev = Some(model_state)).
The selected population is also sanitized before the refit as a coarse
backstop: non-finite genome values are mapped NaN → 0.0 and ±inf
clamped to ±f32::MAX, so a single divergent gene cannot poison a
model’s fitted statistics. Each model’s fit keeps its own precise
finite-guards (which also protect direct trait callers that bypass this
path).
The fitness tensor is forwarded to ProbabilityModel::fit; models
that weight or rank their selected individuals can use it. The five
built-in models (UnivariateGaussian, UnivariateBernoulli,
CompactGenetic, DependencyChain, BayesianNetwork) all perform
an unweighted fit and ignore it.
Source§fn best(&self, state: &Self::State) -> Option<(Self::Genome, f32)>
fn best(&self, state: &Self::State) -> Option<(Self::Genome, f32)>
Return the best-so-far genome (shape (1, D)) and its fitness.
Returns None before the first tell call. The genome is
stored internally as a (D,) vector and unsqueezed to (1, D) here to
match the Genome = Tensor<B, 2> container.
Auto Trait Implementations§
impl<B, M> Freeze for EdaStrategy<B, M>where
M: Freeze,
impl<B, M> RefUnwindSafe for EdaStrategy<B, M>where
M: RefUnwindSafe,
impl<B, M> Send for EdaStrategy<B, M>where
M: Send,
impl<B, M> Sync for EdaStrategy<B, M>where
M: Sync,
impl<B, M> Unpin for EdaStrategy<B, M>where
M: Unpin,
impl<B, M> UnsafeUnpin for EdaStrategy<B, M>where
M: UnsafeUnpin,
impl<B, M> UnwindSafe for EdaStrategy<B, M>where
M: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more