~ruther/ctu-fee-eoa

f6dd4b7e68a4e55fdf897e35fe6c69afc4eeff53 — Rutherther 2 months ago a52b682
tests: move all tests to separate submodules
M env/src/binary_string.rs => env/src/binary_string.rs +153 -147
@@ 1,7 1,4 @@
use std::str::FromStr;
#[cfg(test)]
use crate::test_infra::{load_test_file, DataArrOfReals};

use rand::Rng;

#[derive(Debug, Clone, PartialEq)]


@@ 123,165 120,174 @@ impl<'a> IntoIterator for &'a BinaryString {
    }
}

#[test]
fn test_binary_string_to_real_single() {
    assert_eq!(
        BinaryString::new(vec![1])
            .to_real_single(0.0, 32.0),
        32.0
    );
    assert_eq!(
        BinaryString::new(vec![1, 1])
            .to_real_single(0.0, 32.0),
        32.0
    );
    assert_eq!(
        BinaryString::new(vec![0, 1])
            .to_real_single(0.0, 32.0),
        32.0 / 3.0
    );
    assert_eq!(
        BinaryString::new(vec![0, 0])
            .to_real_single(-16.0, 16.0),
        -16.0
    );
    assert_eq!(
        BinaryString::new(vec![0, 0, 0, 0, 1])
            .to_real_single(0.0, 31.0),
        1.0
    );
    assert_eq!(
        BinaryString::new(vec![1, 1, 1, 1, 1])
            .to_real_single(0.0, 31.0),
        31.0
    );
    assert_eq!(
        BinaryString::new(vec![0, 0, 0, 1, 0])
            .to_real_single(0.0, 31.0),
        2.0
    );

    assert_eq!(
        BinaryString::new(vec![1; 512])
            .to_real_single(0.0, 31.0),
        31.0
    );
}

#[cfg(test)]
fn test_binary_string_to_real(file_name: &str, bounds: Vec<Bounds>) {
    let data = load_test_file::<i8, DataArrOfReals>(file_name);
pub mod tests {
    use crate::{binary_string::BinaryString, test_infra::{load_test_file, DataArrOfReals}};

    use super::Bounds;

    #[test]
    fn test_binary_string_to_real_single() {
        assert_eq!(
            BinaryString::new(vec![1])
                .to_real_single(0.0, 32.0),
            32.0
        );
        assert_eq!(
            BinaryString::new(vec![1, 1])
                .to_real_single(0.0, 32.0),
            32.0
        );
        assert_eq!(
            BinaryString::new(vec![0, 1])
                .to_real_single(0.0, 32.0),
            32.0 / 3.0
        );
        assert_eq!(
            BinaryString::new(vec![0, 0])
                .to_real_single(-16.0, 16.0),
            -16.0
        );
        assert_eq!(
            BinaryString::new(vec![0, 0, 0, 0, 1])
                .to_real_single(0.0, 31.0),
            1.0
        );
        assert_eq!(
            BinaryString::new(vec![1, 1, 1, 1, 1])
                .to_real_single(0.0, 31.0),
            31.0
        );
        assert_eq!(
            BinaryString::new(vec![0, 0, 0, 1, 0])
                .to_real_single(0.0, 31.0),
            2.0
        );

        assert_eq!(
            BinaryString::new(vec![1; 512])
                .to_real_single(0.0, 31.0),
            31.0
        );
    }

    #[cfg(test)]
    fn test_binary_string_to_real(file_name: &str, bounds: Vec<Bounds>) {
        use crate::binary_string::BinaryStringConversionError;

    for test in data {
        let res = BinaryString::new(test.inp)
        let data = load_test_file::<i8, DataArrOfReals>(file_name);

        for test in data {
            let res = BinaryString::new(test.inp)
                .to_real(&bounds);
        if !test.out.valid {
            assert_eq!(
                res,
                Err(BinaryStringConversionError::DimensionMismatch)
            );
        }
        else {
          assert_eq!(
              res.unwrap(),
              test.out.vec
          );
            if !test.out.valid {
                assert_eq!(
                    res,
                    Err(BinaryStringConversionError::DimensionMismatch)
                );
            }
            else {
                assert_eq!(
                    res.unwrap(),
                    test.out.vec
                );
            }
        }
    }
}

#[test]
fn test_binary_string_to_real_1d_1() {
    test_binary_string_to_real(
        "tests/Bin2Real_1D_1.txt",
        vec![Bounds::new(0.0, 1.0)]
    );
}
    #[test]
    fn test_binary_string_to_real_1d_1() {
        test_binary_string_to_real(
            "tests/Bin2Real_1D_1.txt",
            vec![Bounds::new(0.0, 1.0)]
        );
    }

#[test]
fn test_binary_string_to_real_1d_2() {
    test_binary_string_to_real(
        "tests/Bin2Real_1D_2.txt",
        vec![Bounds::new(0.0, 4095.0)]
    );
}
    #[test]
    fn test_binary_string_to_real_1d_2() {
        test_binary_string_to_real(
            "tests/Bin2Real_1D_2.txt",
            vec![Bounds::new(0.0, 4095.0)]
        );
    }

#[test]
fn test_binary_string_to_real_1d_3() {
    test_binary_string_to_real(
        "tests/Bin2Real_1D_3.txt",
        vec![Bounds::new(-5.0, 5.0)]
    );
}
    #[test]
    fn test_binary_string_to_real_1d_3() {
        test_binary_string_to_real(
            "tests/Bin2Real_1D_3.txt",
            vec![Bounds::new(-5.0, 5.0)]
        );
    }

#[test]
fn test_binary_string_to_real_2d_1() {
    test_binary_string_to_real(
        "tests/Bin2Real_2D_1.txt",
        vec![Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0)]
    );
}
    #[test]
    fn test_binary_string_to_real_2d_1() {
        test_binary_string_to_real(
            "tests/Bin2Real_2D_1.txt",
            vec![Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0)]
        );
    }

#[test]
fn test_binary_string_to_real_2d_2() {
    test_binary_string_to_real(
        "tests/Bin2Real_2D_2.txt",
        vec![Bounds::new(0.0, 63.0), Bounds::new(-32.0, 31.0)]
    );
}
    #[test]
    fn test_binary_string_to_real_2d_2() {
        test_binary_string_to_real(
            "tests/Bin2Real_2D_2.txt",
            vec![Bounds::new(0.0, 63.0), Bounds::new(-32.0, 31.0)]
        );
    }

#[test]
fn test_binary_string_to_real_2d_3() {
    test_binary_string_to_real(
        "tests/Bin2Real_2D_3.txt",
        vec![Bounds::new(-5.0, 5.0), Bounds::new(0.0, 10.0)]
    );
}
    #[test]
    fn test_binary_string_to_real_2d_3() {
        test_binary_string_to_real(
            "tests/Bin2Real_2D_3.txt",
            vec![Bounds::new(-5.0, 5.0), Bounds::new(0.0, 10.0)]
        );
    }

#[test]
fn test_binary_string_to_real_3d_1() {
    test_binary_string_to_real(
        "tests/Bin2Real_3D_1.txt",
        vec![Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0)]
    );
}
    #[test]
    fn test_binary_string_to_real_3d_1() {
        test_binary_string_to_real(
            "tests/Bin2Real_3D_1.txt",
            vec![Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0)]
        );
    }

#[test]
fn test_binary_string_to_real_3d_2() {
    test_binary_string_to_real(
        "tests/Bin2Real_3D_2.txt",
        vec![Bounds::new(0.0, 15.0), Bounds::new(-8.0, 7.0), Bounds::new(-8.0, 8.0)]
    );
}
    #[test]
    fn test_binary_string_to_real_3d_2() {
        test_binary_string_to_real(
            "tests/Bin2Real_3D_2.txt",
            vec![Bounds::new(0.0, 15.0), Bounds::new(-8.0, 7.0), Bounds::new(-8.0, 8.0)]
        );
    }

#[test]
fn test_binary_string_to_real_4d_1() {
    test_binary_string_to_real(
        "tests/Bin2Real_4D_1.txt",
        vec![Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0)]
    );
}
    #[test]
    fn test_binary_string_to_real_4d_1() {
        test_binary_string_to_real(
            "tests/Bin2Real_4D_1.txt",
            vec![Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0)]
        );
    }

#[test]
fn test_binary_string_to_real_4d_2() {
    test_binary_string_to_real(
        "tests/Bin2Real_4D_2.txt",
        vec![Bounds::new(0.0, 7.0), Bounds::new(-4.0, 3.0), Bounds::new(-4.0, 4.0), Bounds::new(-8.0, 0.0)]
    );
}
    #[test]
    fn test_binary_string_to_real_4d_2() {
        test_binary_string_to_real(
            "tests/Bin2Real_4D_2.txt",
            vec![Bounds::new(0.0, 7.0), Bounds::new(-4.0, 3.0), Bounds::new(-4.0, 4.0), Bounds::new(-8.0, 0.0)]
        );
    }

#[test]
fn test_binary_string_to_real_6d_1() {
    test_binary_string_to_real(
        "tests/Bin2Real_6D_1.txt",
        vec![Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0)]
    );
}
    #[test]
    fn test_binary_string_to_real_6d_1() {
        test_binary_string_to_real(
            "tests/Bin2Real_6D_1.txt",
            vec![Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0), Bounds::new(0.0, 1.0)]
        );
    }

#[test]
fn test_binary_string_to_real_6d_2() {
    test_binary_string_to_real(
        "tests/Bin2Real_6D_2.txt",
        (0..=5).map(|x| Bounds::new(x as f64, (2 * (x + 1)) as f64)).collect::<Vec<_>>()
    );
    #[test]
    fn test_binary_string_to_real_6d_2() {
        test_binary_string_to_real(
            "tests/Bin2Real_6D_2.txt",
            (0..=5).map(|x| Bounds::new(x as f64, (2 * (x + 1)) as f64)).collect::<Vec<_>>()
        );
    }
}

M env/src/fitness/labs.rs => env/src/fitness/labs.rs +19 -16
@@ 1,6 1,4 @@
use std::convert::Infallible;
#[cfg(test)]
use crate::test_infra::load_test_file;
use crate::binary_string::BinaryString;
use super::FitnessFunction;



@@ 39,18 37,23 @@ impl FitnessFunction for LABS {
    }
}

#[test]
fn test_labs() {
    let data = load_test_file::<i8, i32>("tests/labs.txt");

    for test in data {
        println!("Test vector {}", test.inp.iter()
            .map(|x| x.to_string())
            .collect::<Vec<String>>()
            .join(", "));
        assert_eq!(
            LABS::new().fit(&BinaryString::new(test.inp)).unwrap(),
            test.out
        )
     }
#[cfg(test)]
pub mod tests {
    use crate::{binary_string::BinaryString, fitness::{labs::LABS, FitnessFunction}, test_infra::load_test_file};

    #[test]
    fn test_labs() {
        let data = load_test_file::<i8, i32>("tests/labs.txt");

        for test in data {
            println!("Test vector {}", test.inp.iter()
                     .map(|x| x.to_string())
                     .collect::<Vec<String>>()
                     .join(", "));
            assert_eq!(
                LABS::new().fit(&BinaryString::new(test.inp)).unwrap(),
                test.out
            )
        }
    }
}

M env/src/fitness/one_max.rs => env/src/fitness/one_max.rs +15 -12
@@ 1,9 1,5 @@
use std::convert::Infallible;

use crate::binary_string::BinaryString;
#[cfg(test)]
use crate::test_infra::load_test_file;

use super::FitnessFunction;

pub struct OneMax;


@@ 25,14 21,21 @@ impl FitnessFunction for OneMax {
    }
}

#[test]
fn test_one_max() {
    let data = load_test_file::<i8, i32>("tests/onemax.txt");
#[cfg(test)]
pub mod tests {
    use crate::fitness::one_max::OneMax;
    use crate::{binary_string::BinaryString, test_infra::load_test_file};
    use crate::fitness::FitnessFunction;

    #[test]
    fn test_one_max() {
        let data = load_test_file::<i8, i32>("tests/onemax.txt");

    for test in data {
        assert_eq!(
            OneMax::new().fit(&BinaryString::new(test.inp)).unwrap(),
            test.out
        );
        for test in data {
            assert_eq!(
                OneMax::new().fit(&BinaryString::new(test.inp)).unwrap(),
                test.out
            );
        }
    }
}

M env/src/fitness/rosenbrock.rs => env/src/fitness/rosenbrock.rs +13 -11
@@ 1,7 1,4 @@
use std::convert::Infallible;
#[cfg(test)]
use crate::test_infra::load_test_file;

use super::FitnessFunction;

pub struct Rosenbrock;


@@ 24,14 21,19 @@ impl FitnessFunction for Rosenbrock {
    }
}

#[test]
fn test_rosenbrock() {
    let data = load_test_file::<f64, f64>("tests/rosenbrock.txt");
#[cfg(test)]
pub mod tests {
    use crate::{fitness::{rosenbrock::Rosenbrock, FitnessFunction}, test_infra::load_test_file};

    #[test]
    fn test_rosenbrock() {
        let data = load_test_file::<f64, f64>("tests/rosenbrock.txt");

    for test in data {
        assert_eq!(
            Rosenbrock::new().fit(&test.inp).unwrap(),
            test.out
        )
        for test in data {
            assert_eq!(
                Rosenbrock::new().fit(&test.inp).unwrap(),
                test.out
            )
        }
    }
}

M env/src/fitness/sphere.rs => env/src/fitness/sphere.rs +13 -11
@@ 1,7 1,4 @@
use std::convert::Infallible;
#[cfg(test)]
use crate::test_infra::load_test_file;

use super::FitnessFunction;

pub struct Sphere {


@@ 30,14 27,19 @@ impl FitnessFunction for Sphere {
    }
}

#[test]
fn test_sphere() {
    let data = load_test_file::<f64, f64>("tests/sphere.txt");
#[cfg(test)]
pub mod tests {
    use crate::{fitness::{sphere::Sphere, FitnessFunction}, test_infra::load_test_file};

    for test in data {
        assert_eq!(
            Sphere::new(vec![1.0; 10]).fit(&test.inp).unwrap(),
            test.out
        )
    #[test]
    fn test_sphere() {
        let data = load_test_file::<f64, f64>("tests/sphere.txt");

        for test in data {
            assert_eq!(
                Sphere::new(vec![1.0; 10]).fit(&test.inp).unwrap(),
                test.out
            )
        }
    }
}

M env/src/local_search/mod.rs => env/src/local_search/mod.rs +137 -115
@@ 1,20 1,4 @@
use crate::binary_string::BinaryString;
#[cfg(test)]
use crate::binary_string::Bounds;
#[cfg(test)]
use crate::fitness::one_max::OneMax;
#[cfg(test)]
use crate::fitness::rosenbrock::Rosenbrock;
#[cfg(test)]
use crate::fitness::sphere::Sphere;
#[cfg(test)]
use crate::terminating::{AndTerminatingConditions, EqualTerminatingCondition, NoBetterForCyclesTerminatingCondition};
#[cfg(test)]
use crate::perturbation::BinaryStringBitPerturbation;
#[cfg(test)]
use crate::comparison:: MinimizingOperator;
#[cfg(test)]
use crate::fitness::BinaryFitnessWrapper;

use crate::fitness::FitnessFunction;
use crate::terminating::TerminatingCondition;


@@ 93,105 77,143 @@ where
    })
}

#[test]
fn test_local_search_sphere() {
    let optimum = BinaryString::new(vec![0, 0, 1, 0, 0,
                                         0, 0, 1, 0, 0]);
    let bounds = vec![Bounds::new(0.0, 31.0), Bounds::new(0.0, 31.0)];
    let optimum_real = optimum.to_real(&bounds).unwrap();
    let sphere = Sphere::new(optimum_real);
    let sphere_wrapped = BinaryFitnessWrapper::new(sphere, bounds);

    let result = local_search_first_improving(
        &sphere_wrapped,
        &mut
            AndTerminatingConditions::new(
                vec![
                    &mut EqualTerminatingCondition::new_remembered(optimum.clone()),
                    &mut NoBetterForCyclesTerminatingCondition::new(100)
                ]
            ),
        &mut BinaryStringBitPerturbation::new(0.3),
        &MinimizingOperator::new(),
        &BinaryString::new(vec![1; 10]),
    ).unwrap();

    println!("{:?}", result);

    assert_eq!(
        result.best_candidate.fit,
        0.0
    );

    assert_eq!(
        result.best_candidate.pos,
        optimum
    );
}
#[cfg(test)]
pub mod tests {
    use crate::{binary_string::{BinaryString, Bounds}, comparison::MinimizingOperator, fitness::{one_max::OneMax, rosenbrock::Rosenbrock, sphere::Sphere, BinaryFitnessWrapper}, local_search::local_search_first_improving, perturbation::BinaryStringBitPerturbation, terminating::{AndTerminatingConditions, EqualTerminatingCondition, NoBetterForCyclesTerminatingCondition}};

    #[test]
    fn test_local_search_sphere() {
        let optimum = BinaryString::new(vec![0, 0, 1, 0, 0,
                                             0, 0, 1, 0, 0]);
        let bounds = vec![Bounds::new(0.0, 31.0), Bounds::new(0.0, 31.0)];
        let optimum_real = optimum.to_real(&bounds).unwrap();
        let sphere = Sphere::new(optimum_real);
        let sphere_wrapped = BinaryFitnessWrapper::new(sphere, bounds);

        let result = local_search_first_improving(
            &sphere_wrapped,
            &mut
                AndTerminatingConditions::new(
                    vec![
                        &mut EqualTerminatingCondition::new_remembered(optimum.clone()),
                        &mut NoBetterForCyclesTerminatingCondition::new(100)
                    ]
                ),
            &mut BinaryStringBitPerturbation::new(0.3),
            &MinimizingOperator::new(),
            &BinaryString::new(vec![1; 10]),
        ).unwrap();

        println!("{:?}", result);

        assert_eq!(
            result.best_candidate.fit,
            0.0
        );

        assert_eq!(
            result.best_candidate.pos,
            optimum
        );
    }

#[test]
fn test_local_search_one_max() {
    let one_max = OneMax::new();
    let optimum = BinaryString::new(vec![0; 10]);

    let result = local_search_first_improving(
        &one_max,
        &mut
            AndTerminatingConditions::new(
                vec![
                    &mut EqualTerminatingCondition::new_remembered(optimum.clone()),
                    &mut NoBetterForCyclesTerminatingCondition::new(100)
                ]
            ),
        &mut BinaryStringBitPerturbation::new(0.3),
        &MinimizingOperator::new(),
        &BinaryString::new(vec![1; 10]),
    ).unwrap();

    println!("{:?}", result);

    assert_eq!(
        result.best_candidate.fit,
        0
    );

    assert_eq!(
        result.best_candidate.pos,
        optimum
    );
}
    #[test]
    fn test_local_search_one_max() {
        let one_max = OneMax::new();
        let optimum = BinaryString::new(vec![0; 10]);

        let result = local_search_first_improving(
            &one_max,
            &mut
                AndTerminatingConditions::new(
                    vec![
                        &mut EqualTerminatingCondition::new_remembered(optimum.clone()),
                        &mut NoBetterForCyclesTerminatingCondition::new(100)
                    ]
                ),
            &mut BinaryStringBitPerturbation::new(0.3),
            &MinimizingOperator::new(),
            &BinaryString::new(vec![1; 10]),
        ).unwrap();

        println!("{:?}", result);

        assert_eq!(
            result.best_candidate.fit,
            0
        );

        assert_eq!(
            result.best_candidate.pos,
            optimum
        );
    }

    // #[test]
    // fn test_local_search_labs() {
    //     let labs = LABS::new();
    //     let optimum = BinaryString::new(vec![0; 20]);

    //     let result = local_search_first_improving(
    //         &labs,
    //         &mut
    //             AndTerminatingConditions::new(
    //                 vec![
    //                     // &mut EqualTerminatingCondition::new_remembered(optimum.clone()),
    //                     &mut NoBetterForCyclesTerminatingCondition::new(1000)
    //                 ]
    //             ),
    //         &mut BinaryStringBitPerturbation::new(0.1),
    //         &MinimizingOperator::new(),
    //         &BinaryString::new(vec![0; 20]),
    //     ).unwrap();

    //     println!("{:?}", result);

    //     assert_eq!(
    //         result.best_candidate.fit,
    //         0
    //     );

    //     assert_eq!(
    //         result.best_candidate.pos,
    //         optimum
    //     );
    // }

    #[test]
    fn test_local_search_rosenbrock() {
        let rosenbrock = Rosenbrock::new();
        let optimum = BinaryString::new(vec![1, 0, 0, 0, 1, 1, 0, 0, 0, 1]);

        let bounds = vec![Bounds::new(-16.0, 15.0), Bounds::new(-16.0, 15.0)];
        let rosenbrock_wrapped = BinaryFitnessWrapper::new(rosenbrock, bounds);

        let result = local_search_first_improving(
            &rosenbrock_wrapped,
            &mut
                AndTerminatingConditions::new(
                    vec![
                        &mut EqualTerminatingCondition::new_remembered(optimum.clone()),
                        &mut NoBetterForCyclesTerminatingCondition::new(100)
                    ]
                ),
            &mut BinaryStringBitPerturbation::new(0.3),
            &MinimizingOperator::new(),
            &BinaryString::new(vec![0; 10]),
        ).unwrap();

        println!("{:?}", result);

        assert_eq!(
            result.best_candidate.fit,
            0.0
        );

        assert_eq!(
            result.best_candidate.pos,
            optimum
        );
    }

#[test]
fn test_local_search_rosenbrock() {
    let rosenbrock = Rosenbrock::new();
    let optimum = BinaryString::new(vec![1, 0, 0, 0, 1, 1, 0, 0, 0, 1]);

    let bounds = vec![Bounds::new(-16.0, 15.0), Bounds::new(-16.0, 15.0)];
    let rosenbrock_wrapped = BinaryFitnessWrapper::new(rosenbrock, bounds);

    let result = local_search_first_improving(
        &rosenbrock_wrapped,
        &mut
            AndTerminatingConditions::new(
                vec![
                    &mut EqualTerminatingCondition::new_remembered(optimum.clone()),
                    &mut NoBetterForCyclesTerminatingCondition::new(100)
                ]
            ),
        &mut BinaryStringBitPerturbation::new(0.3),
        &MinimizingOperator::new(),
        &BinaryString::new(vec![0; 10]),
    ).unwrap();

    println!("{:?}", result);

    assert_eq!(
        result.best_candidate.fit,
        0.0
    );

    assert_eq!(
        result.best_candidate.pos,
        optimum
    );
}

M env/src/perturbation/mod.rs => env/src/perturbation/mod.rs +22 -17
@@ 30,21 30,26 @@ impl<TRng: Rng> PerturbationOperator for BinaryStringBitPerturbation<TRng> {
    }
}

#[test]
fn test_perturb() {
    let mut rng = rand::rng();

    assert_eq!(
        *BinaryString::new(vec![1, 1, 0, 0])
            .perturb(&mut rng, 1.0)
            .vec(),
        vec![0, 0, 1, 1]
    );

    assert_eq!(
        *BinaryString::new(vec![1, 1, 0, 0])
            .perturb(&mut rng, 0.0)
            .vec(),
        vec![1, 1, 0, 0]
    );
#[cfg(test)]
pub mod tests {
    use crate::binary_string::BinaryString;

    #[test]
    fn test_perturb() {
        let mut rng = rand::rng();

        assert_eq!(
            *BinaryString::new(vec![1, 1, 0, 0])
                .perturb(&mut rng, 1.0)
                .vec(),
            vec![0, 0, 1, 1]
        );

        assert_eq!(
            *BinaryString::new(vec![1, 1, 0, 0])
                .perturb(&mut rng, 0.0)
                .vec(),
            vec![1, 1, 0, 0]
        );
    }
}