Struct neat::GeneticSim
source · pub struct GeneticSim<E> {
pub entities: Vec<E>,
/* private fields */
}Expand description
The simulation controller.
use genetic_rs::prelude::*;
#[derive(Debug, Clone)]
struct MyEntity {
a: f32,
b: f32,
}
impl RandomlyMutable for MyEntity {
fn mutate(&mut self, rate: f32, rng: &mut impl rand::Rng) {
self.a += rng.gen::<f32>() * rate;
self.b += rng.gen::<f32>() * rate;
}
}
impl DivisionReproduction for MyEntity {
fn spawn_child(&self, rng: &mut impl rand::Rng) -> Self {
let mut child = self.clone();
child.mutate(0.25, rng); // you'll generally want to use a constant mutation rate for mutating children.
child
}
}
impl Prunable for MyEntity {} // if we wanted to, we could implement the `despawn` function to run any cleanup code as needed. in this example, though, we do not need it.
impl GenerateRandom for MyEntity {
fn gen_random(rng: &mut impl rand::Rng) -> Self {
Self {
a: rng.gen(),
b: rng.gen(),
}
}
}
fn main() {
let my_fitness_fn = |e: &MyEntity| {
e.a * e.b // should result in entities increasing their value
};
let mut rng = rand::thread_rng();
let mut sim = GeneticSim::new(
Vec::gen_random(&mut rng, 1000),
my_fitness_fn,
division_pruning_nextgen,
);
for _ in 0..100 {
// if this were a more complex simulation, you might test entities in `sim.entities` between `next_generation` calls to provide a more accurate reward.
sim.next_generation();
}
dbg!(sim.entities);
}Fields§
§entities: Vec<E>The current population of entities
Implementations§
source§impl<E> GeneticSim<E>
impl<E> GeneticSim<E>
sourcepub fn new(
starting_entities: Vec<E>,
fitness: impl Fn(&E) -> f32 + Send + Sync + 'static,
next_gen: impl Fn(Vec<(E, f32)>) -> Vec<E> + Send + Sync + 'static
) -> GeneticSim<E>
pub fn new( starting_entities: Vec<E>, fitness: impl Fn(&E) -> f32 + Send + Sync + 'static, next_gen: impl Fn(Vec<(E, f32)>) -> Vec<E> + Send + Sync + 'static ) -> GeneticSim<E>
Creates a GeneticSim with a given population of starting_entities (the size of which will be retained),
a given fitness function, and a given nextgen function.
Examples found in repository?
examples/basic.rs (lines 105-109)
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
fn main() {
let mut rng = rand::thread_rng();
let mut sim = GeneticSim::new(
Vec::gen_random(&mut rng, 100),
fitness,
division_pruning_nextgen,
);
for _ in 0..100 {
sim.next_generation();
}
let fits: Vec<_> = sim.entities.iter().map(fitness).collect();
let maxfit = fits
.iter()
.max_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap();
dbg!(&fits, maxfit);
}sourcepub fn next_generation(&mut self)
pub fn next_generation(&mut self)
Uses the next_gen provided in GeneticSim::new to create the next generation of entities.
Examples found in repository?
examples/basic.rs (line 112)
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
fn main() {
let mut rng = rand::thread_rng();
let mut sim = GeneticSim::new(
Vec::gen_random(&mut rng, 100),
fitness,
division_pruning_nextgen,
);
for _ in 0..100 {
sim.next_generation();
}
let fits: Vec<_> = sim.entities.iter().map(fitness).collect();
let maxfit = fits
.iter()
.max_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap();
dbg!(&fits, maxfit);
}Auto Trait Implementations§
impl<E> !RefUnwindSafe for GeneticSim<E>
impl<E> Send for GeneticSim<E>where
E: Send,
impl<E> Sync for GeneticSim<E>where
E: Sync,
impl<E> Unpin for GeneticSim<E>where
E: Unpin,
impl<E> !UnwindSafe for GeneticSim<E>
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
Mutably borrows from an owned value. Read more