use gut::prelude::*;
#[macro_use]
extern crate lazy_static;
pub mod common {
pub use gut::prelude::*;
macro_rules! local_float_cmp {
($fi:ident, $fj:ident) => {
match ($fi.is_nan(), $fj.is_nan()) {
(true, false) => std::cmp::Ordering::Greater,
(false, true) => std::cmp::Ordering::Less,
(true, true) => std::cmp::Ordering::Equal,
(false, false) => unreachable!(),
}
};
}
pub trait FloatIteratorExt
where
Self: std::marker::Sized,
{
fn fmax(mut self) -> Option<f64> {
todo!()
}
fn fmin(mut self) -> Option<f64> {
todo!()
}
fn imax(mut self) -> Option<(usize, f64)> {
todo!()
}
fn imin(mut self) -> Option<(usize, f64)> {
todo!()
}
}
impl<F, T> FloatIteratorExt for T
where
T: Iterator<Item = F>,
F: std::borrow::Borrow<f64>,
Self: std::marker::Sized,
{
fn fmax(mut self) -> Option<f64> {
if let Some(value) = self.next() {
let f = self.fold(*value.borrow(), |a, b| a.max(*b.borrow()));
Some(f)
} else {
None
}
}
fn fmin(mut self) -> Option<f64> {
if let Some(value) = self.next() {
let f = self.fold(*value.borrow(), |a, b| a.min(*b.borrow()));
Some(f)
} else {
None
}
}
fn imax(mut self) -> Option<(usize, f64)> {
if let Some(value) = self.next() {
let value = *value.borrow();
let value = (1..).zip(self).fold((0, value), |a, b| {
let (ia, fa) = a;
let (ib, fb) = b;
let fb = *fb.borrow();
if fb > fa {
(ib, fb)
} else {
(ia, fa)
}
});
Some(value)
} else {
None
}
}
fn imin(mut self) -> Option<(usize, f64)> {
if let Some(value) = self.next() {
let value = *value.borrow();
let value = (1..).zip(self).fold((0, value), |a, b| {
let (ia, fa) = a;
let (ib, fb) = b;
let fb = *fb.borrow();
if fb < fa {
(ib, fb)
} else {
(ia, fa)
}
});
Some(value)
} else {
None
}
}
}
pub fn float_ordering_maximize(fi: &f64, fj: &f64) -> std::cmp::Ordering {
fj.partial_cmp(&fi).unwrap_or_else(|| local_float_cmp!(fi, fj))
}
pub fn float_ordering_minimize(fi: &f64, fj: &f64) -> std::cmp::Ordering {
fi.partial_cmp(&fj).unwrap_or_else(|| local_float_cmp!(fi, fj))
}
#[test]
fn test_float_ordering() {
let mut values = vec![1.0, -1.0, std::f64::NAN, 0.5, 2.0];
let m = values.iter().fmax();
assert_eq!(m, Some(2.0));
let m = values.iter().fmin();
assert_eq!(m, Some(-1.0));
let m = values.iter().imax();
assert_eq!(m, Some((4, 2.0)));
let m = values.iter().imin();
assert_eq!(m, Some((1, -1.0)));
values.sort_by(|a, b| float_ordering_maximize(&a, &b));
assert_eq!(values[0], 2.0);
assert!(values[4].is_nan());
values.sort_by(|a, b| float_ordering_minimize(&a, &b));
assert_eq!(values[0], -1.0);
assert!(values[4].is_nan());
}
}
#[macro_use]
pub mod random;
pub mod encoding;
pub mod engine;
pub mod fitness;
pub mod gears;
pub mod individual;
pub mod operators;
pub mod population;
pub mod termination;
mod annealing;
mod fingerprint;
mod graph6;
mod vars;
pub mod prelude {
pub use crate::engine::Evolve;
pub use crate::fitness::EvaluateFitness;
pub use crate::gears::Breed;
pub use crate::gears::Survive;
pub use crate::individual::EvaluateObjectiveValue;
pub use crate::operators::*;
pub use crate::population::SortMember;
pub use crate::random::*;
pub use crate::encoding::Mutate;
pub use crate::fingerprint::FingerPrintExt;
}
pub use crate::engine::{Engine, EvolutionAlgorithm};
pub use crate::gears::GeneticBreeder;
pub use crate::gears::Survivor;
pub use crate::gears::Valuer;
pub use crate::individual::{Genome, Individual};
pub use crate::population::Population;