Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 0 additions & 44 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions genetic-rs-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ crossover = ["builtin"]
speciation = ["crossover"]
genrand = ["dep:rand"]
rayon = ["dep:rayon"]
tracing = ["dep:tracing"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand All @@ -29,4 +28,3 @@ rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
rand = { version = "0.9.2", optional = true }
rayon = { version = "1.10.0", optional = true }
tracing = { version = "0.1.41", optional = true }
65 changes: 7 additions & 58 deletions genetic-rs-common/src/builtin/repopulator.rs
Original file line number Diff line number Diff line change
@@ -1,54 +1,29 @@
use rand::Rng as RandRng;

use crate::{Repopulator, Rng};

#[cfg(feature = "tracing")]
use tracing::*;
use crate::Repopulator;

/// Used in other traits to randomly mutate genomes a given amount
pub trait RandomlyMutable {
/// Mutate the genome with a given mutation rate (0..1)
fn mutate(&mut self, rate: f32, rng: &mut impl Rng);
fn mutate(&mut self, rate: f32, rng: &mut impl rand::Rng);
}

/// Internal trait that simply deals with the trait bounds of features to avoid duplicate code.
/// It is blanket implemented, so you should never have to reference this directly.
#[cfg(not(feature = "tracing"))]
pub trait FeatureBoundedRandomlyMutable: RandomlyMutable {}
#[cfg(not(feature = "tracing"))]
impl<T: RandomlyMutable> FeatureBoundedRandomlyMutable for T {}

/// Internal trait that simply deals with the trait bounds of features to avoid duplicate code.
/// It is blanket implemented, so you should never have to reference this directly.
#[cfg(feature = "tracing")]
pub trait FeatureBoundedRandomlyMutable: RandomlyMutable + std::fmt::Debug {}
#[cfg(feature = "tracing")]
impl<T: RandomlyMutable + std::fmt::Debug> FeatureBoundedRandomlyMutable for T {}

/// Used in dividually-reproducing [`Repopulator`]s
pub trait Mitosis: Clone + FeatureBoundedRandomlyMutable {
pub trait Mitosis: Clone + RandomlyMutable {
/// Create a new child with mutation. Similar to [RandomlyMutable::mutate], but returns a new instance instead of modifying the original.
fn divide(&self, rate: f32, rng: &mut impl Rng) -> Self {
fn divide(&self, rate: f32, rng: &mut impl rand::Rng) -> Self {
let mut child = self.clone();
child.mutate(rate, rng);
child
}
}

/// Used in crossover-reproducing [`Repopulator`]s
#[cfg(all(feature = "crossover", not(feature = "tracing")))]
#[cfg(feature = "crossover")]
#[cfg_attr(docsrs, doc(cfg(feature = "crossover")))]
pub trait Crossover: Clone + PartialEq {
pub trait Crossover: Clone {
/// Use crossover reproduction to create a new genome.
fn crossover(&self, other: &Self, rate: f32, rng: &mut impl Rng) -> Self;
}

/// Used in crossover-reproducing [`next_gen`]s
#[cfg(all(feature = "crossover", feature = "tracing"))]
#[cfg_attr(docsrs, doc(cfg(feature = "crossover")))]
pub trait Crossover: Clone + std::fmt::Debug {
/// Use crossover reproduction to create a new genome.
fn crossover(&self, other: &Self, rate: f32, rng: &mut impl Rng) -> Self;
fn crossover(&self, other: &Self, rate: f32, rng: &mut impl rand::Rng) -> Self;
}

/// Used in speciated crossover nextgens. Allows for genomes to avoid crossover with ones that are too different.
Expand Down Expand Up @@ -134,21 +109,8 @@ where
}
let parent2 = &genomes[j];

#[cfg(feature = "tracing")]
let span = span!(
Level::DEBUG,
"crossover",
a = tracing::field::debug(parent1),
b = tracing::field::debug(parent2)
);
#[cfg(feature = "tracing")]
let enter = span.enter();

let child = parent1.crossover(parent2, self.mutation_rate, &mut rng);

#[cfg(feature = "tracing")]
drop(enter);

genomes.push(child);
}
}
Expand Down Expand Up @@ -193,21 +155,8 @@ where
parent2 = &champions[rng.random_range(0..champions.len() - 1)];
}

#[cfg(feature = "tracing")]
let span = span!(
Level::DEBUG,
"crossover",
a = tracing::field::debug(parent1),
b = tracing::field::debug(parent2)
);
#[cfg(feature = "tracing")]
let enter = span.enter();

let child = parent1.crossover(parent2, self.mutation_rate, &mut rng);

#[cfg(feature = "tracing")]
drop(enter);

genomes.push(child);
}
}
Expand Down
34 changes: 3 additions & 31 deletions genetic-rs-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,6 @@ pub mod prelude;
#[cfg(feature = "rayon")]
use rayon::prelude::*;

#[cfg(feature = "tracing")]
use tracing::*;

#[cfg(feature = "tracing")]
#[allow(missing_docs)]
pub trait Rng: rand::Rng + std::fmt::Debug {}

#[cfg(feature = "tracing")]
impl<T: rand::Rng + std::fmt::Debug> Rng for T {}

#[cfg(not(feature = "tracing"))]
#[allow(missing_docs)]
pub trait Rng: rand::Rng {}

#[cfg(not(feature = "tracing"))]
impl<T: rand::Rng> Rng for T {}

/// Tests and eliminates the unfit from the simulation.
pub trait Eliminator<G> {
/// Tests and eliminates the unfit from the simulation.
Expand Down Expand Up @@ -118,20 +101,11 @@ where

/// Uses the [`Eliminator`] and [`Repopulator`] provided in [`GeneticSim::new`] to create the next generation of genomes.
pub fn next_generation(&mut self) {
#[cfg(feature = "tracing")]
let span = span!(Level::TRACE, "next_generation");

#[cfg(feature = "tracing")]
let enter = span.enter();

let genomes = std::mem::take(&mut self.genomes);

let target_size = genomes.len();
self.genomes = self.eliminator.eliminate(genomes);
self.repopulator.repopulate(&mut self.genomes, target_size);

#[cfg(feature = "tracing")]
drop(enter);
}

/// Calls [`next_generation`][GeneticSim::next_generation] `count` number of times.
Expand All @@ -147,7 +121,7 @@ where
#[cfg_attr(docsrs, doc(cfg(feature = "genrand")))]
pub trait GenerateRandom {
/// Create a completely random instance of the genome
fn gen_random(rng: &mut impl Rng) -> Self;
fn gen_random(rng: &mut impl rand::Rng) -> Self;
}

/// Blanket trait used on collections that contain objects implementing [`GenerateRandom`]
Expand All @@ -158,7 +132,7 @@ where
T: GenerateRandom,
{
/// Generate a random collection of the inner objects with a given amount
fn gen_random(rng: &mut impl Rng, amount: usize) -> Self;
fn gen_random(rng: &mut impl rand::Rng, amount: usize) -> Self;
}

/// Rayon version of the [`GenerateRandomCollection`] trait
Expand All @@ -177,8 +151,7 @@ where
C: FromIterator<T>,
T: GenerateRandom,
{
#[cfg_attr(feature = "tracing", instrument)]
fn gen_random(rng: &mut impl Rng, amount: usize) -> Self {
fn gen_random(rng: &mut impl rand::Rng, amount: usize) -> Self {
(0..amount).map(|_| T::gen_random(rng)).collect()
}
}
Expand All @@ -189,7 +162,6 @@ where
C: FromParallelIterator<T>,
T: GenerateRandom + Send,
{
#[cfg_attr(feature = "tracing", instrument)]
fn gen_random(amount: usize) -> Self {
(0..amount)
.into_par_iter()
Expand Down
2 changes: 1 addition & 1 deletion genetic-rs-common/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ pub use crate::*;
#[cfg(feature = "builtin")]
pub use crate::builtin::{eliminator::*, repopulator::*};

pub use rand::Rng as RandRng;
pub use rand::prelude::*;
10 changes: 5 additions & 5 deletions genetic-rs-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn randmut_derive(input: TokenStream) -> TokenStream {

quote! {
impl genetic_rs_common::prelude::RandomlyMutable for #name {
fn mutate(&mut self, rate: f32, rng: &mut impl genetic_rs_common::Rng) {
fn mutate(&mut self, rate: f32, rng: &mut impl rand::Rng) {
#inner
}
}
Expand Down Expand Up @@ -95,15 +95,15 @@ pub fn crossover_derive(input: TokenStream) -> TokenStream {
if tuple_struct {
quote! {
impl genetic_rs_common::prelude::Crossover for #name {
fn crossover(&self, other: &Self, rate: f32, rng: &mut impl genetic_rs_common::Rng) -> Self {
fn crossover(&self, other: &Self, rate: f32, rng: &mut impl rand::Rng) -> Self {
Self(#inner)
}
}
}.into()
} else {
quote! {
impl genetic_rs_common::prelude::Crossover for #name {
fn crossover(&self, other: &Self, rate: f32, rng: &mut impl genetic_rs_common::Rng) -> Self {
fn crossover(&self, other: &Self, rate: f32, rng: &mut impl rand::Rng) -> Self {
Self {
#inner
}
Expand Down Expand Up @@ -153,7 +153,7 @@ pub fn genrand_derive(input: TokenStream) -> TokenStream {
if tuple_struct {
quote! {
impl genetic_rs_common::prelude::GenerateRandom for #name {
fn gen_random(rng: &mut impl genetic_rs_common::Rng) -> Self {
fn gen_random(rng: &mut impl rand::Rng) -> Self {
Self(#inner)
}
}
Expand All @@ -162,7 +162,7 @@ pub fn genrand_derive(input: TokenStream) -> TokenStream {
} else {
quote! {
impl genetic_rs_common::prelude::GenerateRandom for #name {
fn gen_random(rng: &mut impl genetic_rs_common::Rng) -> Self {
fn gen_random(rng: &mut impl rand::Rng) -> Self {
Self {
#inner
}
Expand Down
1 change: 0 additions & 1 deletion genetic-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ speciation = ["crossover", "genetic-rs-common/speciation"]
genrand = ["genetic-rs-common/genrand"]
rayon = ["genetic-rs-common/rayon"]
derive = ["dep:genetic-rs-macros", "genetic-rs-common/builtin"]
tracing = ["genetic-rs-common/tracing"]

[dependencies]
genetic-rs-common = { path = "../genetic-rs-common", version = "1.0.0" }
Expand Down