use rand::{Rng, seq::IndexedRandom};
use vecpool::PoolVec;
use crate::{
core::{individual::Individual, offspring::Offspring},
fitness::{FitnessComparator, FitnessEvaluator},
};
use std::slice::ChunksExact;
#[derive(Debug)]
pub struct Population<G, F> {
individuals: PoolVec<Individual<G, F>>,
}
impl<G, F> Population<G, F> {
pub fn new() -> Self {
Self {
individuals: PoolVec::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
individuals: vecpool::with_capacity(capacity),
}
}
pub fn from_individuals(individuals: Vec<Individual<G, F>>) -> Self {
Self {
individuals: PoolVec::from(individuals),
}
}
pub fn extend(&mut self, individuals: impl IntoIterator<Item = Individual<G, F>>) {
self.individuals.extend(individuals);
}
pub fn len(&self) -> usize {
self.individuals.len()
}
pub fn is_empty(&self) -> bool {
self.individuals.is_empty()
}
pub fn iter(&self) -> std::slice::Iter<'_, Individual<G, F>> {
self.individuals.iter()
}
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, Individual<G, F>> {
self.individuals.iter_mut()
}
pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, Individual<G, F>> {
self.individuals.chunks_exact(chunk_size)
}
pub fn as_slice(&self) -> &[Individual<G, F>] {
&self.individuals
}
pub fn as_mut_slice(&mut self) -> &mut [Individual<G, F>] {
&mut self.individuals
}
pub fn into_vec(self) -> Vec<Individual<G, F>> {
self.individuals.into_vec()
}
pub fn choose<R: Rng>(&self, rng: &mut R) -> Option<&Individual<G, F>> {
self.individuals.choose(rng)
}
pub fn best<Fe, C>(&self, fitness_evaluator: &Fe, comparator: &C) -> &Individual<G, F>
where
F: PartialOrd,
Fe: FitnessEvaluator<G, F>,
C: FitnessComparator<F>,
{
self.individuals
.iter()
.reduce(|a, b| {
if comparator.is_better(a.fitness(fitness_evaluator), b.fitness(fitness_evaluator))
{
a
} else {
b
}
})
.expect("population cannot be empty")
}
pub fn add(&mut self, individual: Individual<G, F>) {
self.individuals.push(individual);
}
pub fn merge(&mut self, population: Population<G, F>) {
self.individuals.extend(population.individuals.into_vec());
}
pub fn add_offspring(&mut self, offspring: Offspring<G, F>) {
match offspring {
Offspring::Single(individual) => self.add(individual),
Offspring::Multiple(population) => self.merge(population),
}
}
pub fn cull(&mut self, target_size: usize) {
self.individuals.truncate(target_size);
}
}
impl<G, F> From<Vec<Individual<G, F>>> for Population<G, F> {
fn from(value: Vec<Individual<G, F>>) -> Self {
Self::from_individuals(value)
}
}
impl<G, F> From<Offspring<G, F>> for Population<G, F> {
fn from(value: Offspring<G, F>) -> Self {
value.into_population()
}
}
impl<G, F> IntoIterator for Population<G, F> {
type Item = Individual<G, F>;
type IntoIter = std::vec::IntoIter<Individual<G, F>>;
fn into_iter(self) -> Self::IntoIter {
self.individuals.into_iter()
}
}
impl<'a, G, F> IntoIterator for &'a Population<G, F> {
type Item = &'a Individual<G, F>;
type IntoIter = std::slice::Iter<'a, Individual<G, F>>;
fn into_iter(self) -> Self::IntoIter {
self.individuals.iter()
}
}
impl<'a, G, F> IntoIterator for &'a mut Population<G, F> {
type Item = &'a mut Individual<G, F>;
type IntoIter = std::slice::IterMut<'a, Individual<G, F>>;
fn into_iter(self) -> Self::IntoIter {
self.individuals.iter_mut()
}
}
impl<G, F> FromIterator<Individual<G, F>> for Population<G, F> {
fn from_iter<T: IntoIterator<Item = Individual<G, F>>>(iter: T) -> Self {
Self {
individuals: iter.into_iter().collect(),
}
}
}
impl<G, F> Default for Population<G, F> {
fn default() -> Self {
Self::new()
}
}
impl<G: Clone, F: Clone> Clone for Population<G, F> {
fn clone(&self) -> Self {
Self {
individuals: self.individuals.iter().cloned().collect(),
}
}
}