ga-scheduler 0.1.0

A Genetic Algorithm optimizer designed for scheduling and similar tasks
Documentation
pub mod mutate;
pub mod null;
pub mod rotate;

use crate::chromosone::Gene;

#[mockall_double::double]
use crate::rando::Rando;

pub trait Mutation<const N: usize, const NSYMS: usize> {
    fn run(&self, candidate: &[Gene; N], rng: &mut Rando) -> [Gene; N];
}

pub struct MutationIter<'a, const N: usize, const NSYMS: usize> {
    i: usize,
    config: &'a MutationConfig<N, NSYMS>,
}

impl<'a, const N: usize, const NSYMS: usize> Iterator for MutationIter<'a, N, NSYMS> {
    type Item = &'a Box<dyn Mutation<N, NSYMS> + Sync + Send>;

    fn next(&mut self) -> Option<&'a Box<dyn Mutation<N, NSYMS> + Sync + Send>> {
        self.i += 1;
        if self.i >= self.config.indices.len() {
            self.i = 0;
        }
        Some(&self.config.mutations_with_weights[self.config.indices[self.i]].1)
    }
}

pub struct MutationConfig<const N: usize, const NSYMS: usize> {
    mutations_with_weights: Vec<(usize, Box<dyn Mutation<N, NSYMS> + Sync + Send>)>,
    indices: Vec<usize>,
}

impl<const N: usize, const NSYMS: usize> MutationConfig<N, NSYMS> {
    pub fn new(
        mutations_with_weights: Vec<(usize, Box<dyn Mutation<N, NSYMS> + Sync + Send>)>,
    ) -> MutationConfig<N, NSYMS> {
        let weights = mutations_with_weights
            .iter()
            .map(|c| c.0)
            .collect::<Vec<usize>>();
        let indices = crate::helpers::multidimensional_bresenhams(&weights);
        MutationConfig {
            indices,
            mutations_with_weights,
        }
    }

    pub fn iter(&self) -> MutationIter<N, NSYMS> {
        MutationIter {
            i: self.indices.len(),
            config: self,
        }
    }
}