use ndarray::Array1;
use crate::{operators::SamplingOperator, random::RandomGenerator};
#[derive(Debug, Clone)]
pub struct PermutationSampling;
impl PermutationSampling {
pub fn new() -> Self {
Self
}
}
impl SamplingOperator for PermutationSampling {
fn sample_individual(&self, num_vars: usize, rng: &mut impl RandomGenerator) -> Array1<f64> {
let mut indices: Vec<f64> = (0..num_vars).map(|i| i as f64).collect();
rng.shuffle_vec(&mut indices);
Array1::from_vec(indices)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::random::{RandomGenerator, TestDummyRng};
struct FakeRandomGenerator {
dummy: TestDummyRng,
}
impl FakeRandomGenerator {
fn new() -> Self {
Self {
dummy: TestDummyRng,
}
}
}
impl RandomGenerator for FakeRandomGenerator {
type R = TestDummyRng;
fn rng(&mut self) -> &mut TestDummyRng {
&mut self.dummy
}
fn shuffle_vec(&mut self, vector: &mut Vec<f64>) {
vector.reverse();
}
}
#[test]
fn test_permutation_sampling_controlled() {
let sampler = PermutationSampling;
let mut rng = FakeRandomGenerator::new();
let population_size = 5;
let num_vars = 4;
let population = sampler.operate(population_size, num_vars, &mut rng);
assert_eq!(population.nrows(), population_size);
assert_eq!(population.ncols(), num_vars);
let expected = vec![3.0, 2.0, 1.0, 0.0];
for row in population.outer_iter() {
let perm: Vec<f64> = row.to_vec();
assert_eq!(
perm, expected,
"The permutation did not match the expected value."
);
}
}
}