pub trait Strategy<B: Backend>: Send + Sync {
type Params: Clone + Debug + Send + Sync;
type State: Clone + Debug + Send;
type Genome: Clone + Send;
// Required methods
fn init(
&self,
params: &Self::Params,
rng: &mut dyn Rng,
device: &B::Device,
) -> Self::State;
fn ask(
&self,
params: &Self::Params,
state: &Self::State,
rng: &mut dyn Rng,
device: &B::Device,
) -> (Self::Genome, Self::State);
fn tell(
&self,
params: &Self::Params,
population: Self::Genome,
fitness: Tensor<B, 1>,
state: Self::State,
rng: &mut dyn Rng,
) -> (Self::State, StrategyMetrics);
fn best(&self, state: &Self::State) -> Option<(Self::Genome, f32)>;
}Expand description
Central evolutionary-strategy abstraction.
The trait is intentionally pure — ask and
tell return a new State rather than mutating
through &mut self. That keeps strategies free of interior
mutability (so many instances can run in parallel without locks) and
makes Clone-based checkpointing straightforward.
§Example
use burn::backend::NdArray;
use rlevo_evolution::algorithms::ga::{GaConfig, GeneticAlgorithm};
use rlevo_evolution::Strategy;
use rand::{rngs::StdRng, SeedableRng};
let device = Default::default();
let strategy = GeneticAlgorithm::<NdArray>::new();
let params = GaConfig::default_for(64, 10);
let mut rng = StdRng::seed_from_u64(0);
let state = strategy.init(¶ms, &mut rng, &device);
assert_eq!(state.population.shape().dims, vec![64, 10]);§Type Parameters
B: Burn backend.
§Associated Types
Params: Static configuration for a run (population size, σ, F, CR, …). Adaptive algorithms mutate their adaptive quantities insideState, notParams.State: Generation-to-generation state (current population, σ, best-so-far, RNG-free sub-statistics). Must be clonable so the harness can snapshot before a risky step if needed.Genome: Genome container produced byaskand consumed bytell. Typically aTensor<B, 2>for real-valued strategies or aTensor<B, 2, Int>for binary/integer kinds.
Required Associated Types§
Required Methods§
Sourcefn init(
&self,
params: &Self::Params,
rng: &mut dyn Rng,
device: &B::Device,
) -> Self::State
fn init( &self, params: &Self::Params, rng: &mut dyn Rng, device: &B::Device, ) -> Self::State
Build the initial state.
Samples the initial population, primes adaptive quantities, and sets the generation counter to zero.
Sourcefn ask(
&self,
params: &Self::Params,
state: &Self::State,
rng: &mut dyn Rng,
device: &B::Device,
) -> (Self::Genome, Self::State)
fn ask( &self, params: &Self::Params, state: &Self::State, rng: &mut dyn Rng, device: &B::Device, ) -> (Self::Genome, Self::State)
Propose the next population.
Takes the current state and returns the genome to evaluate
together with an updated state. The returned state typically
carries pre-computed bookkeeping (e.g. the parent indices a
tournament-based GA sampled) so tell can reuse
them without re-sampling.
Sourcefn 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 fitness values and produce the next state.
fitness has shape (pop_size,) on the same device as the
population. Strategies pull it to host only if they need to —
e.g. for tournament index lookups.