use std::io;
use ew::genetic::{self, creation, cross, mutation, pairing, pre_birth, selection};
use ew::tools::logging;
use ew::tools::stopchecker;
use ew::{GoalFromFunction, Optimizer};
use ew_testfunc;
type Gene = f32;
type Chromosomes = Vec<Gene>;
fn main() {
let minval: Gene = -500.0;
let maxval: Gene = 500.0;
let population_size = 500;
let chromo_count = 15;
let intervals = vec![(minval, maxval); chromo_count];
let goal = GoalFromFunction::new(ew_testfunc::schwefel);
let creator = creation::vec_float::RandomCreator::new(population_size, intervals.clone());
let families_count = population_size / 2;
let rounds_count = 5;
let pairing = pairing::Tournament::new(families_count).rounds_count(rounds_count);
let single_cross = cross::FloatCrossExp::new();
let cross = cross::VecCrossAllGenes::new(Box::new(single_cross));
let mutation_probability = 15.0;
let mutation_gene_count = 3;
let single_mutation = mutation::BitwiseMutation::new(mutation_gene_count);
let mutation = mutation::VecMutation::new(mutation_probability, Box::new(single_mutation));
let pre_births: Vec<Box<dyn genetic::PreBirth<Chromosomes>>> = vec![Box::new(
pre_birth::vec_float::CheckChromoInterval::new(intervals.clone()),
)];
let stop_checker = stopchecker::CompositeAny::new(vec![
Box::new(stopchecker::Threshold::new(1e-4)),
Box::new(stopchecker::MaxIterations::new(3000)),
]);
let selections: Vec<Box<dyn genetic::Selection<Chromosomes>>> = vec![
Box::new(selection::KillFitnessNaN::new()),
Box::new(selection::LimitPopulation::new(population_size)),
];
let mut stdout_result = io::stdout();
let mut stdout_time = io::stdout();
let loggers: Vec<Box<dyn logging::Logger<Chromosomes>>> = vec![
Box::new(logging::ResultOnlyLogger::new(&mut stdout_result, 15)),
Box::new(logging::TimeLogger::new(&mut stdout_time)),
];
let mut optimizer = genetic::GeneticOptimizer::new(
Box::new(goal),
Box::new(stop_checker),
Box::new(creator),
Box::new(pairing),
Box::new(cross),
Box::new(mutation),
selections,
pre_births,
);
optimizer.set_loggers(loggers);
optimizer.find_min();
}