Skip to main content

rlevo_evolution/
genome.rs

1//! Genome category trait and its zero-sized marker types.
2//!
3//! [`GenomeKind`] tags genome representations at the type level so operators
4//! can specialize on the element semantics (real-valued, binary, integer,
5//! or tree). Strategies take a marker type as a const generic to pick the
6//! right operator set.
7//!
8//! The markers themselves carry no data — they exist purely to discriminate
9//! trait impls.
10
11use std::fmt::Debug;
12
13/// Shape-erased genome kind.
14///
15/// `GenomeKind` is a zero-sized marker that strategies parameterize on to
16/// pick operators. Concrete kinds (`Real`, `Binary`, `Integer`, `Tree`,
17/// `Permutation`) live below; new kinds can be added by implementing this
18/// trait on a fresh marker type.
19///
20/// The associated constant [`DIM`](GenomeKind::DIM) records the genome
21/// dimensionality at the type level when it is compile-time known (for
22/// variable-length representations like trees, impls set it to `0`).
23pub trait GenomeKind: Debug + Copy + Send + Sync + 'static {
24    /// Compile-time genome dimensionality, or `0` for variable-length kinds.
25    const DIM: usize;
26
27    /// Element type of the genome (typically `f32`, `i32`, or `bool`).
28    type Element: Copy + Debug + Send + Sync + 'static;
29}
30
31/// Real-valued genome (each gene is an `f32`).
32///
33/// Populations are stored as `Tensor<B, 2>` of shape `(pop_size, dim)`.
34/// All classical ES variants, real-coded GA, EP, and DE use this kind.
35#[derive(Debug, Clone, Copy, Default)]
36pub struct Real;
37
38impl GenomeKind for Real {
39    const DIM: usize = 0;
40    type Element = f32;
41}
42
43/// Binary genome (each gene is a bit, stored as `i32` 0/1 on device).
44///
45/// Populations are stored as `Tensor<B, 2, Int>` of shape
46/// `(pop_size, dim)`. Binary-coded GA uses this kind.
47#[derive(Debug, Clone, Copy, Default)]
48pub struct Binary;
49
50impl GenomeKind for Binary {
51    const DIM: usize = 0;
52    type Element = i32;
53}
54
55/// Integer-valued genome (each gene is a non-negative integer index).
56///
57/// Populations are stored as `Tensor<B, 2, Int>` of shape
58/// `(pop_size, dim)`. Permutation-coded GA and Cartesian GP use this kind.
59#[derive(Debug, Clone, Copy, Default)]
60pub struct Integer;
61
62/// Tree-based genome (variable-length AST, stored host-side).
63///
64/// Reserved for classical Koza-style GP in a future release. Tree
65/// genomes cannot be batched on a GPU and therefore have no tensor
66/// representation in this crate.
67#[derive(Debug, Clone, Copy, Default)]
68pub struct Tree;
69
70/// Permutation genome (each row is a permutation of `0..n_nodes`).
71///
72/// Populations are stored as `Tensor<B, 2, Int>` of shape
73/// `(pop_size, n_nodes)` where every row is a valid permutation. Used by
74/// Ant Colony Optimization over combinatorial domains (TSP, QAP, …);
75/// only a stubbed consumer ships in this release — a full implementation
76/// is planned for a future release.
77#[derive(Debug, Clone, Copy, Default)]
78pub struct Permutation;
79
80impl GenomeKind for Integer {
81    const DIM: usize = 0;
82    type Element = i32;
83}
84
85impl GenomeKind for Tree {
86    const DIM: usize = 0;
87    type Element = i32;
88}
89
90impl GenomeKind for Permutation {
91    const DIM: usize = 0;
92    type Element = i32;
93}
94
95#[cfg(test)]
96mod tests {
97    use super::*;
98
99    #[test]
100    fn real_has_f32_element() {
101        let _: <Real as GenomeKind>::Element = 0.0_f32;
102    }
103
104    #[test]
105    fn binary_has_i32_element() {
106        let _: <Binary as GenomeKind>::Element = 1_i32;
107    }
108
109    #[test]
110    fn integer_has_i32_element() {
111        let _: <Integer as GenomeKind>::Element = 5_i32;
112    }
113
114    #[test]
115    fn permutation_has_i32_element() {
116        let _: <Permutation as GenomeKind>::Element = 7_i32;
117    }
118
119    #[test]
120    fn markers_are_debug() {
121        let _ = format!(
122            "{Real:?} {Binary:?} {Integer:?} {Tree:?} {Permutation:?}"
123        );
124    }
125}