abc/lib.rs
1#![crate_name = "abc"]
2#![crate_type = "lib"]
3#![doc(html_root_url = "https://daviddonna.github.io/abc-rs/")]
4
5#![warn(missing_docs)]
6
7//! Runs Karaboga's Artificial Bee Colony algorithm in parallel.
8//!
9//! To take advantage of this crate, the user must implement the
10//! [`Solution`](trait.Solution.html) trait for a type of their creation.
11//! A [`Hive`](struct.Hive.html) of the appropriate type can then be built,
12//! which will search the solution space for the fittest candidate.
13//!
14//! # Examples
15//!
16//! ```
17//! // ABC algorithm with canonical (proportionate) fitness scaling
18//! // to minimize the 10-dimensional Rastrigin function.
19//!
20//! extern crate abc;
21//! extern crate rand;
22//!
23//! use std::f32::consts::PI;
24//! use rand::{random, Closed01, thread_rng, Rng};
25//! use abc::{Context, Candidate, HiveBuilder};
26//!
27//! const SIZE: usize = 10;
28//!
29//! #[derive(Clone, Debug)]
30//! struct S([f32;SIZE]);
31//!
32//! // Not really necessary; we're using this mostly to demonstrate usage.
33//! struct SBuilder {
34//! min: f32,
35//! max: f32,
36//! a: f32,
37//! p_min: f32,
38//! p_max: f32,
39//! }
40//!
41//! impl Context for SBuilder {
42//! type Solution = [f32;SIZE];
43//!
44//! fn make(&self) -> [f32;SIZE] {
45//! let mut new = [0.0;SIZE];
46//! for i in 0..SIZE {
47//! let Closed01(x) = random::<Closed01<f32>>();
48//! new[i] = (x * (self.max - self.min)) + self.min;
49//! }
50//! new
51//! }
52//!
53//! fn evaluate_fitness(&self, solution: &[f32;10]) -> f64 {
54//! let sum = solution.iter()
55//! .map(|x| x.powf(2.0) - self.a * (*x * 2.0 * PI).cos())
56//! .fold(0.0, |total, next| total + next);
57//! let rastrigin = ((self.a * SIZE as f32) + sum) as f64;
58//!
59//! // Minimize.
60//! if rastrigin >= 0.0 {
61//! 1.0 / (1.0 + rastrigin)
62//! } else {
63//! 1.0 + rastrigin.abs()
64//! }
65//! }
66//!
67//! fn explore(&self, field: &[Candidate<[f32;SIZE]>], index: usize) -> [f32;SIZE] {
68//! // new[i] = current[i] + Φ * (current[i] - other[i]), where:
69//! // phi_min <= Φ <= phi_max
70//! // other is a solution, other than current, chosen at random
71//!
72//! let ref current = field[index].solution;
73//! let mut new = [0_f32;SIZE];
74//!
75//! for i in 0..SIZE {
76//! // Choose a different vector at random.
77//! let mut rng = thread_rng();
78//! let mut index2 = rng.gen_range(0, current.len() - 1);
79//! if index2 >= index { index2 += 1; }
80//! let ref other = field[index2].solution;
81//!
82//! let phi = random::<Closed01<f32>>().0 * (self.p_max - self.p_min) + self.p_min;
83//! new[i] = current[i] + (phi * (current[i] - other[i]));
84//! }
85//!
86//! new
87//! }
88//! }
89//!
90//! fn main() {
91//! let mut builder = SBuilder {
92//! min: -5.12,
93//! max: 5.12,
94//! a: 10.0,
95//! p_min: -1.0,
96//! p_max: 1.0
97//! };
98//! let hive_builder = HiveBuilder::new(builder, 10);
99//! let hive = hive_builder.build().unwrap();
100//!
101//! // Once built, the hive can be run for a number of rounds.
102//! let best_after_10 = hive.run_for_rounds(10).unwrap();
103//!
104//! // As long as it's run some rounds at a time, you can keep running it.
105//! let best_after_20 = hive.run_for_rounds(10).unwrap();
106//!
107//! // The algorithm doesn't guarantee improvement in any number of rounds,
108//! // but it always keeps its all-time best.
109//! assert!(best_after_20.fitness >= best_after_10.fitness);
110//!
111//! // The hive can be consumed to create a Receiver object. This can be
112//! // iterated over indefinitely, and will receive successive improvements
113//! // on the best candidate so far.
114//! let mut current_best_fitness = best_after_20.fitness;
115//! for new_best in hive.stream().iter().take(3) {
116//! // The iterator will start with the best result so far; after that,
117//! // each new candidate will be an improvement.
118//! assert!(new_best.fitness >= current_best_fitness);
119//! current_best_fitness = new_best.fitness;
120//! }
121//! }
122//! ```
123
124mod result;
125mod task;
126mod context;
127mod candidate;
128mod hive;
129
130pub mod scaling;
131
132pub use result::{Error, Result};
133pub use context::Context;
134pub use candidate::Candidate;
135pub use hive::{HiveBuilder, Hive};