Fmt.
Clippy.
This commit is contained in:
@@ -44,9 +44,7 @@ impl Individual for Parabole {
|
|||||||
type Fitness = Fitness;
|
type Fitness = Fitness;
|
||||||
|
|
||||||
fn mate(&self, other: &Parabole) -> Parabole {
|
fn mate(&self, other: &Parabole) -> Parabole {
|
||||||
Parabole {
|
Parabole { x: (self.x + other.x) / 2.0 }
|
||||||
x: (self.x + other.x) / 2.0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mutate(&mut self) {
|
fn mutate(&mut self) {
|
||||||
@@ -93,13 +91,13 @@ fn main() {
|
|||||||
.take(5),
|
.take(5),
|
||||||
)
|
)
|
||||||
.map(|(a, b)| a.individual.mate(&b.individual))
|
.map(|(a, b)| a.individual.mate(&b.individual))
|
||||||
.map(|individual| Wrapper {
|
.map(|individual| {
|
||||||
individual: individual,
|
Wrapper {
|
||||||
fitness: None,
|
individual: individual,
|
||||||
|
fitness: None,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.for_each(|wrapper| {
|
.for_each(|wrapper| { population.push(wrapper); });
|
||||||
population.push(wrapper);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Mutate all to get new children.
|
// Mutate all to get new children.
|
||||||
parents
|
parents
|
||||||
@@ -124,7 +122,8 @@ fn main() {
|
|||||||
|
|
||||||
println!(
|
println!(
|
||||||
"{:#?}",
|
"{:#?}",
|
||||||
simulation.population
|
simulation
|
||||||
|
.population
|
||||||
.iter()
|
.iter()
|
||||||
.take(10)
|
.take(10)
|
||||||
.map(|individual| &individual.individual)
|
.map(|individual| &individual.individual)
|
||||||
|
|||||||
134
examples/parabole.rs.bk
Normal file
134
examples/parabole.rs.bk
Normal 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!();
|
||||||
|
}
|
||||||
44
src/lib.rs
44
src/lib.rs
@@ -16,7 +16,7 @@ pub trait Individual: Send {
|
|||||||
|
|
||||||
pub trait Select<T>: Send
|
pub trait Select<T>: Send
|
||||||
where
|
where
|
||||||
T: Individual
|
T: Individual,
|
||||||
{
|
{
|
||||||
fn select(&self, population: Vec<Wrapper<T>>) -> Vec<Wrapper<T>>;
|
fn select(&self, population: Vec<Wrapper<T>>) -> Vec<Wrapper<T>>;
|
||||||
}
|
}
|
||||||
@@ -28,18 +28,16 @@ pub struct MaximizeSelector {
|
|||||||
|
|
||||||
impl MaximizeSelector {
|
impl MaximizeSelector {
|
||||||
pub fn new(count: usize) -> Self {
|
pub fn new(count: usize) -> Self {
|
||||||
MaximizeSelector {
|
MaximizeSelector { count: count }
|
||||||
count: count,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Select<T> for MaximizeSelector
|
impl<T> Select<T> for MaximizeSelector
|
||||||
where
|
where
|
||||||
T: Individual
|
T: Individual,
|
||||||
{
|
{
|
||||||
fn select(&self, mut population: Vec<Wrapper<T>>) -> Vec<Wrapper<T>> {
|
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()
|
population.into_iter().take(self.count).collect()
|
||||||
}
|
}
|
||||||
@@ -52,18 +50,16 @@ pub struct MinimizeSelector {
|
|||||||
|
|
||||||
impl MinimizeSelector {
|
impl MinimizeSelector {
|
||||||
pub fn new(count: usize) -> Self {
|
pub fn new(count: usize) -> Self {
|
||||||
MinimizeSelector {
|
MinimizeSelector { count: count }
|
||||||
count: count,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Select<T> for MinimizeSelector
|
impl<T> Select<T> for MinimizeSelector
|
||||||
where
|
where
|
||||||
T: Individual
|
T: Individual,
|
||||||
{
|
{
|
||||||
fn select(&self, mut population: Vec<Wrapper<T>>) -> Vec<Wrapper<T>> {
|
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()
|
population.into_iter().take(self.count).collect()
|
||||||
}
|
}
|
||||||
@@ -96,28 +92,34 @@ where
|
|||||||
|
|
||||||
initial
|
initial
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|individual| Wrapper {
|
.map(|individual| {
|
||||||
individual: individual,
|
Wrapper {
|
||||||
fitness: None,
|
individual: individual,
|
||||||
|
fitness: None,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect_into(&mut population);
|
.collect_into(&mut population);
|
||||||
|
|
||||||
Simulation {
|
Simulation { population: population }
|
||||||
population: population,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn calculate(&mut self) {
|
pub fn calculate(&mut self) {
|
||||||
self.population.par_iter_mut()
|
self.population
|
||||||
|
.par_iter_mut()
|
||||||
.filter(|wrapper| wrapper.fitness.is_none())
|
.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)
|
pub fn evolve<F>(&mut self, func: F)
|
||||||
where
|
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());
|
let mut population = Vec::with_capacity(self.population.len());
|
||||||
|
|
||||||
|
|||||||
131
src/lib.rs.bk
Normal file
131
src/lib.rs.bk
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user