Skip to content

Commit

Permalink
integrated neat to the alg enum
Browse files Browse the repository at this point in the history
  • Loading branch information
samyhaff committed Apr 10, 2024
1 parent 952e06b commit b603424
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 128 deletions.
28 changes: 28 additions & 0 deletions src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::neuroevolution_algorithm::*;
pub type LabeledPoint = (Vec<f64>, bool);
pub type LabeledPoints = Vec<LabeledPoint>;

#[derive(Debug)]
pub enum SphereClassificationProblem {
Half(u32),
Quarter(u32),
Expand All @@ -12,6 +13,12 @@ pub enum SphereClassificationProblem {
Cube,
}

#[derive(Debug)]
pub enum ClassificationProblem {
SphereProblem(SphereClassificationProblem),
Xor,
}

pub trait ClassificationProblemEval {
fn get_points(&self) -> LabeledPoints;
fn evaluate(&self, alg: &Algorithm) -> f64 {
Expand All @@ -30,6 +37,27 @@ pub trait ClassificationProblemEval {
}
}

impl ClassificationProblemEval for ClassificationProblem {
fn get_points(&self) -> LabeledPoints {
match self {
ClassificationProblem::SphereProblem(problem) => problem.get_points(),
ClassificationProblem::Xor => vec![
(vec![0., 0.], false),
(vec![0., 1.], true),
(vec![1., 0.], true),
(vec![1., 1.], false),
]
}
}

fn evaluate(&self, alg: &Algorithm) -> f64 {
match self {
ClassificationProblem::SphereProblem(problem) => problem.evaluate(alg),
ClassificationProblem::Xor => unimplemented!()
}
}
}

impl ClassificationProblemEval for SphereClassificationProblem {
fn get_points(&self) -> LabeledPoints {
match self {
Expand Down
6 changes: 3 additions & 3 deletions src/bin/bna.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use neuroevolution::neuroevolution_algorithm::*;
use neuroevolution::constants::*;

fn main() {
let half = SphereClassificationProblem::Half(UNIT_CIRCLE_STEPS);
let quarter = SphereClassificationProblem::Quarter(UNIT_CIRCLE_STEPS);
let two_quarters = SphereClassificationProblem::TwoQuarters(UNIT_CIRCLE_STEPS);
let half = ClassificationProblem::SphereProblem(SphereClassificationProblem::Half(UNIT_CIRCLE_STEPS));
let quarter = ClassificationProblem::SphereProblem(SphereClassificationProblem::Quarter(UNIT_CIRCLE_STEPS));
let two_quarters = ClassificationProblem::SphereProblem(SphereClassificationProblem::TwoQuarters(UNIT_CIRCLE_STEPS));

let vneuron = VNeuron::new(2);
let mut alg = Algorithm::ContinuousBNA(vneuron);
Expand Down
2 changes: 1 addition & 1 deletion src/bin/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn main() {
let vneuron = DiscreteVNeuron::new(RESOLUTION, 2);
let alg = Algorithm::DiscreteBNA(vneuron);

let quarter = SphereClassificationProblem::Quarter(UNIT_CIRCLE_STEPS);
let quarter = ClassificationProblem::SphereProblem(SphereClassificationProblem::Quarter(UNIT_CIRCLE_STEPS));

let state = State::new(alg, quarter, N_ITERATIONS);

Expand Down
6 changes: 3 additions & 3 deletions src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ fn main() {
let dim = 2;

let problem = match cli.problem {
Problem::Half => SphereClassificationProblem::Half(UNIT_CIRCLE_STEPS),
Problem::Quarter => SphereClassificationProblem::Quarter(UNIT_CIRCLE_STEPS),
Problem::TwoQuarters => SphereClassificationProblem::TwoQuarters(UNIT_CIRCLE_STEPS),
Problem::Half => ClassificationProblem::SphereProblem(SphereClassificationProblem::Half(UNIT_CIRCLE_STEPS)),
Problem::Quarter => ClassificationProblem::SphereProblem(SphereClassificationProblem::Quarter(UNIT_CIRCLE_STEPS)),
Problem::TwoQuarters => ClassificationProblem::SphereProblem(SphereClassificationProblem::TwoQuarters(UNIT_CIRCLE_STEPS)),
};

match cli.algorithm {
Expand Down
26 changes: 8 additions & 18 deletions src/bin/neat.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
use neuroevolution::neat::*;

fn xor(individual: &Individual) -> f32 {
let inputs = vec![vec![0., 0.], vec![0., 1.], vec![1., 0.], vec![1., 1.]];
let outputs = vec![0., 1., 1., 0.];

let mut distance_sum = 0.;
for (input, output) in inputs.iter().zip(outputs.iter()) {
let result = individual.evaluate(input)[0];
distance_sum += (result - output).abs();
}

4. - distance_sum
}
use neuroevolution::benchmarks::ClassificationProblem;
use neuroevolution::neuroevolution_algorithm::*;

fn main() {
let config = Config {
population_size: 150,
n_inputs: 2,
n_outputs: 1,
n_generations: 1500,
evaluation_function: xor,
problem: ClassificationProblem::Xor,
weights_mean: 0.,
weights_stddev: 0.8,
perturbation_stddev: 0.2,
Expand All @@ -29,14 +18,15 @@ fn main() {
connection_mutation_rate: 0.3,
node_mutation_rate: 0.03,
weight_mutation_rate: 0.8,
similarity_threshold: 4.5,
similarity_threshold: 15.0,
excess_weight: 1.,
disjoint_weight: 1.,
matching_weight: 0.2,
matching_weight: 0.3,
champion_copy_threshold: 5,
stagnation_threshold: 150,
stagnation_threshold: 1500,
};

let mut neat = Neat::new(config);
neat.run();
neat.optimize(&ClassificationProblem::Xor, 1500);
println!("Fitness: {:.2}", neat.get_best_individual_fitness());
}
10 changes: 5 additions & 5 deletions src/bin/oneplusone_na.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ use neuroevolution::neuroevolution_algorithm::*;
use neuroevolution::constants::*;

fn main() {
let half = SphereClassificationProblem::Half(UNIT_CIRCLE_STEPS);
let quarter = SphereClassificationProblem::Quarter(UNIT_CIRCLE_STEPS);
let two_quarters = SphereClassificationProblem::TwoQuarters(UNIT_CIRCLE_STEPS);
let square = SphereClassificationProblem::Square;
let cube = SphereClassificationProblem::Cube;
let half = ClassificationProblem::SphereProblem(SphereClassificationProblem::Half(UNIT_CIRCLE_STEPS));
let quarter = ClassificationProblem::SphereProblem(SphereClassificationProblem::Quarter(UNIT_CIRCLE_STEPS));
let two_quarters = ClassificationProblem::SphereProblem(SphereClassificationProblem::TwoQuarters(UNIT_CIRCLE_STEPS));
let square = ClassificationProblem::SphereProblem(SphereClassificationProblem::Square);
let cube = ClassificationProblem::SphereProblem(SphereClassificationProblem::Cube);

let network = Network::new(2, 2);
let mut alg = Algorithm::ContinuousOneplusoneNA(network);
Expand Down
6 changes: 3 additions & 3 deletions src/discrete_network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rand::prelude::*;
use crate::benchmarks::ClassificationProblemEval;
use crate::utils::*;
use crate::neuroevolution_algorithm::*;
use crate::benchmarks::SphereClassificationProblem;
use crate::benchmarks::ClassificationProblem;

#[derive(Debug, Clone)]
pub struct DiscreteNetwork {
Expand Down Expand Up @@ -77,7 +77,7 @@ impl DiscreteNetwork {
}

impl NeuroevolutionAlgorithm for DiscreteNetwork {
fn optimization_step(&mut self, problem: &SphereClassificationProblem) {
fn optimization_step(&mut self, problem: &ClassificationProblem) {
let mut new_network = self.clone();
for i in 0..self.n_neurons {
new_network.biases[i] = DiscreteNetwork::mutate_component(self.biases[i], self.resolution + 1);
Expand All @@ -92,7 +92,7 @@ impl NeuroevolutionAlgorithm for DiscreteNetwork {
}

#[allow(unused_variables)]
fn optimize_cmaes(&mut self, problem: &SphereClassificationProblem) {
fn optimize_cmaes(&mut self, problem: &ClassificationProblem) {
unimplemented!()
}

Expand Down
6 changes: 3 additions & 3 deletions src/discrete_vneuron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rand::prelude::*;
use crate::benchmarks::ClassificationProblemEval;
use crate::utils::*;
use crate::neuroevolution_algorithm::*;
use crate::benchmarks::SphereClassificationProblem;
use crate::benchmarks::ClassificationProblem;

#[derive(Debug, Clone)]
pub struct DiscreteVNeuron {
Expand Down Expand Up @@ -67,7 +67,7 @@ impl DiscreteVNeuron {
}

impl NeuroevolutionAlgorithm for DiscreteVNeuron {
fn optimization_step(&mut self, problem: &SphereClassificationProblem) {
fn optimization_step(&mut self, problem: &ClassificationProblem) {
let mut new_vneuron = self.clone();
if random::<f64>() < 1. / (self.dim + 1) as f64 {
new_vneuron.bend = DiscreteVNeuron::mutate_component(self.bend, self.resolution);
Expand All @@ -87,7 +87,7 @@ impl NeuroevolutionAlgorithm for DiscreteVNeuron {
}

#[allow(unused_variables)]
fn optimize_cmaes(&mut self, problem: &SphereClassificationProblem) {
fn optimize_cmaes(&mut self, problem: &ClassificationProblem) {
unimplemented!()
}

Expand Down
7 changes: 4 additions & 3 deletions src/gui.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use std::f64::consts::PI;
use ggez::*;
use crate::neuroevolution_algorithm::*;
use crate::benchmarks::{SphereClassificationProblem, ClassificationProblemEval};
use crate::benchmarks::{ClassificationProblem, ClassificationProblemEval};

pub struct State {
alg: Algorithm,
problem: SphereClassificationProblem,
problem: ClassificationProblem,
n_iters: u32,
iteration: u32,
}

impl State {
pub fn new(alg: Algorithm, problem: SphereClassificationProblem, n_iters: u32) -> Self {
pub fn new(alg: Algorithm, problem: ClassificationProblem, n_iters: u32) -> Self {
State {
alg,
problem,
Expand Down Expand Up @@ -208,6 +208,7 @@ impl ggez::event::EventHandler<GameError> for State {

self.get_bend_decision_mesh(mesh, bias, angle, d_normal, d_bend, bend)?;
}
Algorithm::Neat(_neat) => { }
}

let mut text = graphics::Text::new(format!("Iteration: {}\nFitness: {}", self.iteration, self.problem.evaluate(&self.alg)));
Expand Down
Loading

0 comments on commit b603424

Please sign in to comment.