Skip to main content

GeneticEngine

Struct GeneticEngine 

Source
pub struct GeneticEngine<C, T>
where C: Chromosome, T: Clone + Send + Sync + 'static,
{ /* private fields */ }
Expand description

The GeneticEngine is the core component of the Radiate library’s genetic algorithm implementation. The engine is designed to be fast, flexible and extensible, allowing users to customize various aspects of the genetic algorithm to suit their specific needs.

Essentially, it is a high-level abstraction that orchestrates all aspects of the genetic algorithm. It is responsible for managing the population of individuals, evaluating the fitness of each individual, selecting the individuals that will survive to the next generation, and creating the next generation through crossover and mutation.

§Examples

use radiate_engines::*;

// Define a codec that encodes and decodes individuals in the population, in this case using floats.
let codec = FloatCodec::matrix(vec![5], 0.0..100.0);
// This codec will encode Genotype instances with 1 Chromosome and 5 FloatGenes,
// with random alleles between 0.0 and 100.0. It will decode into a Vec<Vec<f32>>.
// eg: [[1.0, 2.0, 3.0, 4.0, 5.0]]

// Create a new instance of the genetic engine with the given codec.
let mut engine = GeneticEngine::builder()
    .codec(codec)
    .minimizing()
    .population_size(150)
    .max_age(15)
    .offspring_fraction(0.5)
    .offspring_selector(BoltzmannSelector::new(4_f32))
    .survivor_selector(TournamentSelector::new(3))
    .alter(alters![
        ArithmeticMutator::new(0.01),
        MeanCrossover::new(0.5)
    ])
    .fitness_fn(|genotype: Vec<Vec<f32>>| {
        genotype.iter().fold(0.0, |acc, chromosome| {
            acc + chromosome.iter().sum::<f32>()
        })
   })
  .build();

// Run the genetic algorithm until the score of the best individual is 0, then return the result.
let result = engine.run(|output| output.score().as_i32() == 0);

§Type Parameters

  • C: The type of the chromosome used in the genotype, which must implement the Chromosome trait.
  • T: The type of the phenotype produced by the genetic algorithm, which must be Clone, Send, and static.

Implementations§

Source§

impl<C, T> GeneticEngine<C, T>
where C: Chromosome + Clone, T: Clone + Send + Sync + 'static,

Source

pub fn builder() -> GeneticEngineBuilder<C, T>

Creates a new builder for configuring and constructing a genetic engine.

The builder pattern provides a fluent interface for configuring all aspects of the genetic algorithm, including population settings, selection strategies, evolutionary operators, and fitness functions.

Source

pub fn control(&mut self) -> ThreadSync

Returns a clone of the engine’s control interface.

The control interface allows for pausing, resuming, and stopping the engine’s execution from external contexts. If the control interface has not been initialized yet, this method will create a new instance.

Source

pub fn iter(self) -> EngineRuntime<Self>
where C: 'static,

Converts the engine into an iterator that yields generations.

This method allows you to iterate over the evolutionary process manually, giving you fine-grained control over when and how generations are processed. The iterator yields Generation objects containing the current state and statistics for each generation.

§Use Cases

Manual iteration is useful when you need to:

  • Implement custom termination logic
  • Monitor progress between generations
  • Apply external control or adaptation
  • Integrate with custom monitoring systems
  • Implement interactive evolutionary algorithms
§Note

The iterator consumes the engine, so you can only iterate once. If you need to run the engine multiple times, create a new instance using the builder.

Source

pub fn subscribe<E: Event>(&self, handler: impl Handler<E>) -> Subscription

Subscribes to events of type E emitted by the engine.

This method returns a Subscription that allows you to define how to handle events of type E. You can use this to listen for events such as epoch completions, improvements, or custom messages emitted during the evolutionary process.

Trait Implementations§

Source§

impl<C, T> Engine for GeneticEngine<C, T>
where C: Chromosome + Clone + 'static, T: Clone + Send + Sync + 'static,

Implementation of the Engine trait for GeneticEngine.

This implementation provides the core evolutionary logic, advancing the population through one complete generation cycle. Each call to next() represents one generation of evolution, including fitness evaluation, selection, reproduction, and population replacement.

§Evolutionary Cycle

Each generation follows this sequence:

  1. Event Emission: Start of epoch events
  2. Pipeline Execution: Run evolutionary operators
  3. Metrics Collection: Record timing and performance data
  4. Best Individual Update: Track improvements and best solutions
  5. Event Completion: End of epoch events
  6. Generation Advancement: Increment generation counter

§Performance Optimizations

  • Efficient Metrics: Metrics are updated incrementally to minimize overhead
  • Event Batching: Events are emitted efficiently without blocking execution
  • Pipeline Optimization: Evolutionary operators are executed in optimized sequences
Source§

type Epoch = Generation<C, T>

The type representing a single epoch or generation in the evolutionary process. Read more
Source§

type Ctx = EvolutionContext<C, T>

The type representing the context of the engine, which may include configuration, state, and other relevant information. This allows external systems to inspect the engine’s state without needing to clone or modify it.
Source§

fn context(&self) -> &Self::Ctx

Returns a reference to the current context of the engine. This is meant to provide a read-only view of the engine’s internal state, to allow external systems close to the engine level, to inspect the engine without cloning anything.
Source§

fn epoch(&self) -> Self::Epoch

Returns an epoch of the engine, which is intended to be a snapshot of the current state, or the current context. The Epoch here can be given to iterators, callers, or anyone else who needs it. Essentially to say, this shouldn’t borrow anything from the engine, but instead be an owned snapshot of the engine
Source§

fn state(&self) -> EngineState

Returns the current state of the engine. This allows external systems to query the engine’s status without modifying it. This lets the Engine act as a state machine, while external systems can query the current state of the engine.
Source§

fn start(&mut self)

Starts the engine, initializing any necessary state or resources. This is typically called before entering the main execution loop.
Source§

fn stop(&mut self)

Stops the engine, performing any necessary cleanup or finalization. This is typically called after exiting the main execution loop.
Source§

fn step(&mut self) -> Result<()>

Advances the engine by one step, performing the necessary computations to progress the evolutionary algorithm. This may include evaluating fitness, selecting individuals, applying genetic operators, and updating the population. This intentionally does not return anything, that is left up to the epoch() method or the next() method. It’s done this way so we can advance the engine without having to clone or create any new data, and possibly perform operations outside of the engine which don’t require a snapshot of the engine state.
Source§

impl<C, T> EngineStream for GeneticEngine<C, T>
where C: Chromosome + Clone + 'static, T: Clone + Send + Sync,

Implementation of the EngineStream trait for GeneticEngine.

Source§

type View<'a> = GenerationView<'a, C, T> where Self: 'a

Source§

fn run<F>(self, limit: F) -> Result<Self::Epoch>
where F: Fn(Self::View<'_>) -> bool + 'static,

Auto Trait Implementations§

§

impl<C, T> !RefUnwindSafe for GeneticEngine<C, T>

§

impl<C, T> !UnwindSafe for GeneticEngine<C, T>

§

impl<C, T> Freeze for GeneticEngine<C, T>
where EvolutionContext<C, T>: Freeze, Pipeline<C>: Freeze,

§

impl<C, T> Send for GeneticEngine<C, T>
where EvolutionContext<C, T>: Send, Pipeline<C>: Send,

§

impl<C, T> Sync for GeneticEngine<C, T>
where EvolutionContext<C, T>: Sync, Pipeline<C>: Sync,

§

impl<C, T> Unpin for GeneticEngine<C, T>
where EvolutionContext<C, T>: Unpin, Pipeline<C>: Unpin,

§

impl<C, T> UnsafeUnpin for GeneticEngine<C, T>
where EvolutionContext<C, T>: UnsafeUnpin, Pipeline<C>: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<E> EngineExt<E> for E
where E: Engine,

Source§

fn run<F>(&mut self, limit: F) -> <E as Engine>::Epoch
where F: Fn(&<E as Engine>::Epoch) -> bool,

👎Deprecated since 1.3.1:

Use the EngineStream trait impl instead, which provides a more flexible and efficient way to run engines with custom termination conditions. Instead of an E::Epoch being given to the fn, a GenerationView<'a, C, T> is provided instead which is much more efficient.

Runs the engine until the specified termination condition is met. Read more
Source§

impl<T> Event for T
where T: Send + Sync + 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more