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