Clippy.
This commit is contained in:
2017-12-25 22:32:48 +01:00
parent be38bf5bd7
commit 22ace4415e
4 changed files with 297 additions and 31 deletions

View File

@@ -44,9 +44,7 @@ impl Individual for Parabole {
type Fitness = Fitness;
fn mate(&self, other: &Parabole) -> Parabole {
Parabole {
x: (self.x + other.x) / 2.0,
}
Parabole { x: (self.x + other.x) / 2.0 }
}
fn mutate(&mut self) {
@@ -93,13 +91,13 @@ fn main() {
.take(5),
)
.map(|(a, b)| a.individual.mate(&b.individual))
.map(|individual| Wrapper {
individual: individual,
fitness: None,
.map(|individual| {
Wrapper {
individual: individual,
fitness: None,
}
})
.for_each(|wrapper| {
population.push(wrapper);
});
.for_each(|wrapper| { population.push(wrapper); });
// Mutate all to get new children.
parents
@@ -124,7 +122,8 @@ fn main() {
println!(
"{:#?}",
simulation.population
simulation
.population
.iter()
.take(10)
.map(|individual| &individual.individual)

134
examples/parabole.rs.bk Normal file
View File

@@ -0,0 +1,134 @@
extern crate rand;
extern crate rayon;
extern crate genetisk;
use std::cmp::Ordering;
use rand::distributions::{IndependentSample, Range};
use rayon::prelude::*;
use genetisk::{Individual, Wrapper, MaximizeSelector, MinimizeSelector, Select, Simulation};
#[derive(Clone, Copy, Debug)]
struct Fitness(f64);
impl PartialEq for Fitness {
fn eq(&self, other: &Fitness) -> bool {
(self.0 - other.0).abs() < 0.0001
}
}
impl Eq for Fitness {}
impl PartialOrd for Fitness {
fn partial_cmp(&self, other: &Fitness) -> Option<Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl Ord for Fitness {
fn cmp(&self, other: &Fitness) -> Ordering {
self.0.partial_cmp(&other.0).unwrap_or(Ordering::Equal)
}
}
#[derive(Clone, Debug)]
struct Parabole {
x: f64,
}
impl Individual for Parabole {
type Fitness = Fitness;
fn mate(&self, other: &Parabole) -> Parabole {
Parabole {
x: (self.x + other.x) / 2.0,
}
}
fn mutate(&mut self) {
let between = Range::new(-1.0, 1.0);
let mut rng = rand::thread_rng();
let offset = between.ind_sample(&mut rng);
self.x += offset;
}
fn fitness(&self) -> Self::Fitness {
Fitness(10.0 - ((self.x + 3.0) * (self.x + 3.0)))
}
}
fn main() {
let initial = (0..300)
.map(|i| Parabole { x: i as f64 })
.collect::<Vec<_>>();
let population_size = initial.len();
let mut simulation = Simulation::with_population(initial);
simulation.calculate();
for _ in 0..250_000 {
simulation.evolve(|parents, population| {
// Mate top 10 to get 5 children.
parents
.iter()
.enumerate()
.filter(|&(n, _)| n % 2 == 0)
.map(|(_, wrapper)| wrapper)
.take(5)
.zip(
parents
.iter()
.enumerate()
.filter(|&(n, _)| n % 2 == 1)
.map(|(_, wrapper)| wrapper)
.take(5),
)
.map(|(a, b)| a.individual.mate(&b.individual))
.map(|individual| Wrapper {
individual: individual,
fitness: None,
})
.for_each(|wrapper| {
population.push(wrapper);
});
// Mutate all to get new children.
parents
.par_iter()
.map(|wrapper| wrapper.individual.clone())
.map(|mut individual| {
individual.mutate();
Wrapper {
individual: individual,
fitness: None,
}
})
.collect_into(population);
// Add all parents again.
population.extend(parents.iter().cloned());
});
simulation.population.truncate(population_size);
}
println!(
"{:#?}",
simulation.population
.iter()
.take(10)
.map(|individual| &individual.individual)
.collect::<Vec<_>>()
);
println!();
}

View File

@@ -16,7 +16,7 @@ pub trait Individual: Send {
pub trait Select<T>: Send
where
T: Individual
T: Individual,
{
fn select(&self, population: Vec<Wrapper<T>>) -> Vec<Wrapper<T>>;
}
@@ -28,18 +28,16 @@ pub struct MaximizeSelector {
impl MaximizeSelector {
pub fn new(count: usize) -> Self {
MaximizeSelector {
count: count,
}
MaximizeSelector { count: count }
}
}
impl<T> Select<T> for MaximizeSelector
where
T: Individual
T: Individual,
{
fn select(&self, mut population: Vec<Wrapper<T>>) -> Vec<Wrapper<T>> {
population.par_sort_unstable_by(|a, b| b.fitness.cmp(&a.fitness));
population.sort_unstable_by(|a, b| b.fitness.cmp(&a.fitness));
population.into_iter().take(self.count).collect()
}
@@ -52,18 +50,16 @@ pub struct MinimizeSelector {
impl MinimizeSelector {
pub fn new(count: usize) -> Self {
MinimizeSelector {
count: count,
}
MinimizeSelector { count: count }
}
}
impl<T> Select<T> for MinimizeSelector
where
T: Individual
T: Individual,
{
fn select(&self, mut population: Vec<Wrapper<T>>) -> Vec<Wrapper<T>> {
population.par_sort_unstable_by(|a, b| a.fitness.cmp(&b.fitness));
population.sort_unstable_by(|a, b| a.fitness.cmp(&b.fitness));
population.into_iter().take(self.count).collect()
}
@@ -96,28 +92,34 @@ where
initial
.into_par_iter()
.map(|individual| Wrapper {
individual: individual,
fitness: None,
.map(|individual| {
Wrapper {
individual: individual,
fitness: None,
}
})
.collect_into(&mut population);
Simulation {
population: population,
}
Simulation { population: population }
}
#[inline]
pub fn calculate(&mut self) {
self.population.par_iter_mut()
self.population
.par_iter_mut()
.filter(|wrapper| wrapper.fitness.is_none())
.for_each(|wrapper| wrapper.fitness = Some(wrapper.individual.fitness()));
.for_each(|wrapper| {
wrapper.fitness = Some(wrapper.individual.fitness())
});
self.population.par_sort_unstable_by(|a, b| b.fitness.cmp(&a.fitness));
self.population.par_sort_unstable_by(
|a, b| b.fitness.cmp(&a.fitness),
);
}
pub fn evolve<F>(&mut self, func: F)
where
F: Fn(&[Wrapper<T>], &mut Vec<Wrapper<T>>)
F: Fn(&[Wrapper<T>], &mut Vec<Wrapper<T>>),
{
let mut population = Vec::with_capacity(self.population.len());

131
src/lib.rs.bk Normal file
View File

@@ -0,0 +1,131 @@
extern crate rayon;
use rayon::prelude::*;
pub trait Individual: Send {
type Fitness: Send + Ord;
fn fitness(&self) -> Self::Fitness;
fn mate(&self, other: &Self) -> Self;
fn mutate(&mut self);
}
pub trait Select<T>: Send
where
T: Individual
{
fn select(&self, population: Vec<Wrapper<T>>) -> Vec<Wrapper<T>>;
}
pub struct MaximizeSelector {
count: usize,
}
impl MaximizeSelector {
pub fn new(count: usize) -> Self {
MaximizeSelector {
count: count,
}
}
}
impl<T> Select<T> for MaximizeSelector
where
T: Individual
{
fn select(&self, mut population: Vec<Wrapper<T>>) -> Vec<Wrapper<T>> {
population.sort_unstable_by(|a, b| b.fitness.cmp(&a.fitness));
population.into_iter().take(self.count).collect()
}
}
pub struct MinimizeSelector {
count: usize,
}
impl MinimizeSelector {
pub fn new(count: usize) -> Self {
MinimizeSelector {
count: count,
}
}
}
impl<T> Select<T> for MinimizeSelector
where
T: Individual
{
fn select(&self, mut population: Vec<Wrapper<T>>) -> Vec<Wrapper<T>> {
population.sort_unstable_by(|a, b| a.fitness.cmp(&b.fitness));
population.into_iter().take(self.count).collect()
}
}
#[derive(Clone)]
pub struct Wrapper<T>
where
T: Individual,
{
pub individual: T,
pub fitness: Option<T::Fitness>,
}
pub struct Simulation<T>
where
T: Individual,
{
pub population: Vec<Wrapper<T>>,
}
impl<T> Simulation<T>
where
T: Individual,
{
pub fn with_population(initial: Vec<T>) -> Self {
let mut population = Vec::with_capacity(initial.len() * 2);
initial
.into_par_iter()
.map(|individual| Wrapper {
individual: individual,
fitness: None,
})
.collect_into(&mut population);
Simulation {
population: population,
}
}
#[inline]
pub fn calculate(&mut self) {
self.population.par_iter_mut()
.filter(|wrapper| wrapper.fitness.is_none())
.for_each(|wrapper| wrapper.fitness = Some(wrapper.individual.fitness()));
self.population.par_sort_unstable_by(|a, b| b.fitness.cmp(&a.fitness));
}
pub fn evolve<F>(&mut self, func: F)
where
F: Fn(&[Wrapper<T>], &mut Vec<Wrapper<T>>)
{
let mut population = Vec::with_capacity(self.population.len());
func(&self.population, &mut population);
self.population = population;
self.calculate();
}
}