Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
pkalivas committed Nov 23, 2024
2 parents 3317dd8 + 119888a commit cd766ee
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 5 deletions.
19 changes: 14 additions & 5 deletions radiate/src/engines/genome/genes/gene.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
/// A `Valid` type is a type that can be checked for validity. This is used for checking if a gene
/// or a chromosome is valid. For example, a gene that represents a number between 0 and 1 can be checked
/// for validity by ensuring that the allele is between 0 and 1.
///
/// The `GeneticEngine` will check the validity of the `Chromosome` and `Phenotype` and remove any
/// invalid individuals from the population, replacing them with new individuals at the given generation.
pub trait Valid {
fn is_valid(&self) -> bool {
true
}
}

/// A gene is a single unit of information in a chromosome.
/// A `Gene` is a single unit of information in a `Chromosome`.
/// This is the most basic building block of this entire library.
///
/// Any type that implements this trait can be used as a gene in a chromosome, as such
/// it can be used in any genetic algorithm that uses this library.
pub trait Gene<G, A>: Clone + PartialEq + Valid
where
G: Gene<G, A>,
{
/// Get the allele of the gene. This is the value that the gene represents.
/// Get the `allele` of the `Gene`. This is the value that the `Gene` represents or "expresses".
fn allele(&self) -> &A;

/// Create a new instance of the gene.
/// Create a new instance of the `Gene`.
fn new_instance(&self) -> G;

/// Create a new gene with the given allele.
/// Create a new `Gene` with the given `allele`.
fn from_allele(&self, allele: &A) -> G;
}

/// A gene that has bounds. This is useful for genes that represent numbers or other values that have
/// A `Gene` that has bounds. This is useful for genes that represent numbers or other values that have
/// a range of valid values. For example, a gene that represents a number between 0 and 1.
pub trait BoundGene<G, A>: Gene<G, A>
where
Expand Down
42 changes: 42 additions & 0 deletions radiate/src/engines/genome/genes/int_gene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,37 @@ use super::{
Integer,
};

/// A `Gene` that represents an integer value. This gene just wraps an integer value and provides
/// functionality for it to be used in a genetic algorithm. In this `Gene` implementation, the
/// `allele` is the integer value itself, the min and max values are the minimum and maximum values
/// that the integer can be generated from, and the upper and lower bounds are the upper and lower bounds the gene will
/// be subject to during crossover and mutation. If the `allele` exceedes the bounds, the `Gene` will be considered invalid.
///
/// `IntGene` is generic over `T` - the type of integer. The `Integer` trait is implemented for `i8`, `i16`, `i32`, `i64`, and `i128`.
///
/// # Example
/// ``` rust
/// use radiate::*;
///
/// // Create a new IntGene with an allele of 5, the min value will be i32::MIN
/// // and the max value will be i32::MAX - same for the upper and lower bounds.
/// let gene: IntGene<i32> = 5.into();
///
/// // Create the same gene, but with a different method
/// let gene = IntGene::new(5);
///
/// // Create a gene, but with a min value of 0 and a max value of 10. In this case,
/// // the allele will be a random value between 0 and 10. The min and max values will
/// // be set to 0 and 10, and the upper and lower bounds will be set to i32::MAX and i32::MIN.
/// let gene = IntGene::from_min_max(0, 10);
///
/// // Create a gene with a min value of 0 and a max value of 10, but with upper and lower bounds of 10 and 0.
/// // In this case, the allele will be a random value between 0 and 10, but the upper and lower bounds will be 10 and 0.
/// let gene = IntGene::from_min_max(0, 10).with_bounds(10, 0);
/// ```
///
/// # Type Parameters
/// - `T`: The type of integer used in the gene.
pub struct IntGene<T: Integer<T>>
where
Standard: rand::distributions::Distribution<T>,
Expand All @@ -22,6 +53,9 @@ impl<T: Integer<T>> IntGene<T>
where
Standard: rand::distributions::Distribution<T>,
{
/// Create a new instance of the `IntGene` with the given allele. The min and max values will be set
/// to the minimum and maximum values of the integer type `T`, and the upper and lower
/// bounds will be set to the maximum and minimum values of the integer type `T`.
pub fn new(allele: T) -> Self {
IntGene {
allele,
Expand All @@ -32,6 +66,8 @@ where
}
}

/// Create a new instance of the `IntGene` with a random allele between the given min and max values.
/// The upper and lower bounds will be set to the maximum and minimum values of the integer type `T`.
pub fn from_min_max(min: T, max: T) -> Self {
let (min, max) = if min > max { (max, min) } else { (min, max) };

Expand All @@ -45,6 +81,7 @@ where
}
}

/// Implement the `Gene` trait for `IntGene`. This allows the `IntGene` to be used in a genetic algorithm.
impl<T: Integer<T>> Gene<IntGene<T>, T> for IntGene<T>
where
Standard: rand::distributions::Distribution<T>,
Expand All @@ -53,6 +90,7 @@ where
&self.allele
}

/// Create a new instance of the `IntGene` with a random allele between the min and max values.
fn new_instance(&self) -> IntGene<T> {
IntGene {
allele: RandomProvider::gen_range(self.min..self.max),
Expand All @@ -74,6 +112,10 @@ where
}
}

/// Implement the `Valid` trait for `IntGene`. This allows the `IntGene` to be checked for validity.
/// An `IntGene` is valid if the `allele` is between the `min` and `max` values.
///
/// Note: the bounds are used for crossover and mutation.
impl<T: Integer<T>> Valid for IntGene<T>
where
Standard: rand::distributions::Distribution<T>,
Expand Down

0 comments on commit cd766ee

Please sign in to comment.