1use gut::prelude::*;
17
18#[macro_use]
21extern crate lazy_static;
22
23pub mod common {
24 pub use gut::prelude::*;
25
26 macro_rules! local_float_cmp {
28 ($fi:ident, $fj:ident) => {
29 match ($fi.is_nan(), $fj.is_nan()) {
30 (true, false) => std::cmp::Ordering::Greater,
31 (false, true) => std::cmp::Ordering::Less,
32 (true, true) => std::cmp::Ordering::Equal,
33 (false, false) => unreachable!(),
34 }
35 };
36 }
37
38 pub trait FloatIteratorExt
40 where
41 Self: std::marker::Sized,
42 {
43 fn fmax(mut self) -> Option<f64> {
44 todo!()
45 }
46 fn fmin(mut self) -> Option<f64> {
47 todo!()
48 }
49 fn imax(mut self) -> Option<(usize, f64)> {
50 todo!()
51 }
52 fn imin(mut self) -> Option<(usize, f64)> {
53 todo!()
54 }
55 }
56
57 impl<F, T> FloatIteratorExt for T
58 where
59 T: Iterator<Item = F>,
60 F: std::borrow::Borrow<f64>,
61 Self: std::marker::Sized,
62 {
63 fn fmax(mut self) -> Option<f64> {
66 if let Some(value) = self.next() {
67 let f = self.fold(*value.borrow(), |a, b| a.max(*b.borrow()));
68 Some(f)
69 } else {
70 None
71 }
72 }
73
74 fn fmin(mut self) -> Option<f64> {
75 if let Some(value) = self.next() {
76 let f = self.fold(*value.borrow(), |a, b| a.min(*b.borrow()));
77 Some(f)
78 } else {
79 None
80 }
81 }
82
83 fn imax(mut self) -> Option<(usize, f64)> {
86 if let Some(value) = self.next() {
87 let value = *value.borrow();
88 let value = (1..).zip(self).fold((0, value), |a, b| {
89 let (ia, fa) = a;
90 let (ib, fb) = b;
91 let fb = *fb.borrow();
92
93 if fb > fa {
94 (ib, fb)
95 } else {
96 (ia, fa)
97 }
98 });
99 Some(value)
100 } else {
101 None
102 }
103 }
104
105 fn imin(mut self) -> Option<(usize, f64)> {
108 if let Some(value) = self.next() {
109 let value = *value.borrow();
110 let value = (1..).zip(self).fold((0, value), |a, b| {
111 let (ia, fa) = a;
112 let (ib, fb) = b;
113 let fb = *fb.borrow();
114
115 if fb < fa {
116 (ib, fb)
117 } else {
118 (ia, fa)
119 }
120 });
121 Some(value)
122 } else {
123 None
124 }
125 }
126 }
127
128 pub fn float_ordering_maximize(fi: &f64, fj: &f64) -> std::cmp::Ordering {
130 fj.partial_cmp(&fi).unwrap_or_else(|| local_float_cmp!(fi, fj))
131 }
132
133 pub fn float_ordering_minimize(fi: &f64, fj: &f64) -> std::cmp::Ordering {
135 fi.partial_cmp(&fj).unwrap_or_else(|| local_float_cmp!(fi, fj))
136 }
137
138 #[test]
139 fn test_float_ordering() {
140 let mut values = vec![1.0, -1.0, std::f64::NAN, 0.5, 2.0];
141 let m = values.iter().fmax();
142 assert_eq!(m, Some(2.0));
143
144 let m = values.iter().fmin();
145 assert_eq!(m, Some(-1.0));
146
147 let m = values.iter().imax();
148 assert_eq!(m, Some((4, 2.0)));
149
150 let m = values.iter().imin();
151 assert_eq!(m, Some((1, -1.0)));
152
153 values.sort_by(|a, b| float_ordering_maximize(&a, &b));
154 assert_eq!(values[0], 2.0);
155 assert!(values[4].is_nan());
156
157 values.sort_by(|a, b| float_ordering_minimize(&a, &b));
158 assert_eq!(values[0], -1.0);
159 assert!(values[4].is_nan());
160 }
161}
162#[macro_use]
166pub mod random; pub mod encoding;
169pub mod engine;
170pub mod fitness;
171pub mod gears;
172pub mod individual;
173pub mod operators;
174pub mod population;
175pub mod termination;
176
177mod annealing;
178mod fingerprint;
179mod graph6;
180mod vars;
181pub mod prelude {
185 pub use crate::engine::Evolve;
186 pub use crate::fitness::EvaluateFitness;
187 pub use crate::gears::Breed;
188 pub use crate::gears::Survive;
189 pub use crate::individual::EvaluateObjectiveValue;
190 pub use crate::operators::*;
191 pub use crate::population::SortMember;
192 pub use crate::random::*;
193
194 pub use crate::encoding::Mutate;
195 pub use crate::fingerprint::FingerPrintExt;
196}
197pub use crate::engine::{Engine, EvolutionAlgorithm};
201pub use crate::gears::GeneticBreeder;
202pub use crate::gears::Survivor;
203pub use crate::gears::Valuer;
204pub use crate::individual::{Genome, Individual};
205pub use crate::population::Population;
206