genx 0.4.0

An easy to use and modular genetic algorithms library.
Documentation
use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng};

use super::check_length;

pub fn multi_point_crossover(
    parent1: &Vec<bool>,
    parent2: &Vec<bool>,
    k: usize,
    seed: Option<u64>,
) -> (Vec<bool>, Vec<bool>) {
    check_length(parent1, parent2);

    let mut prng = match seed {
        Some(seed) => StdRng::seed_from_u64(seed),
        None => StdRng::from_entropy(),
    };


    let n = parent1.len();
    let mut indices = (0..n)
        .collect::<Vec<usize>>()
        .choose_multiple(&mut prng, k)
        .map(|&x| x)
        .collect::<Vec<usize>>();

    indices.sort();
    let (mut child1, mut child2) = (Vec::with_capacity(n), Vec::with_capacity(n));
    let mut child_idx: usize = 0;
    for (i, &idx) in indices.iter().enumerate() {
        if i & 1 == 0 {
            while child_idx < idx {
                child1.push(parent1[child_idx]);
                child2.push(parent2[child_idx]);
                child_idx += 1;
            }
        } else {
            while child_idx < idx {
                child1.push(parent2[child_idx]);
                child2.push(parent1[child_idx]);
                child_idx += 1;
            }
        }
    }

    if child_idx < n {
        while child_idx < n {
            if k & 1 == 0 {
                child1.push(parent1[child_idx]);
                child2.push(parent2[child_idx]);
            } else {
                child1.push(parent2[child_idx]);
                child2.push(parent1[child_idx]);
            }
            child_idx += 1;
        }
    }

    return (child1, child2);
}