rsgenetic/lib.rs
1// file: lib.rs
2//
3// Copyright 2015-2017 The RsGenetic Developers
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17//! # `RsGenetic`
18//!
19//! `RsGenetic` provides a simple framework for genetic algorithms.
20//! You need to provide the definition of a Phenotype (also known as an Individual),
21//! define how crossover and mutation work, present a fitness function, choose some settings
22//! and this library takes care of the rest.
23//!
24//! # Installation
25//!
26//! You can use this library by adding the following lines to your `Cargo.toml` file:
27//!
28//! ```ignore
29//! [dependencies]
30//! rsgenetic = "^1.8.0"
31//! ```
32//!
33//! and adding `extern crate rsgenetic;` to your crate root.
34//!
35//! # Features
36//! ## Available Simulators
37//!
38//! There is currently only one, sequential, simulator. This simulator will run
39//! the genetic algorithm on a single thread.
40//!
41//! ## Available Selection Types
42//!
43//! There are currently four selection types available:
44//!
45//! * Maximize
46//! * Tournament
47//! * Stochastic
48//!
49//! There is a short explanation for each of these below. For more information, look at the
50//! documentation of individual selectors.
51//!
52//! ### Maximize
53//!
54//! Maximize takes 1 parameter: the count. This is half the number of parents
55//! that will be selected. Selection happens by taking the top `count` individuals,
56//! ranked by fitness. The resulting number of parents is `count`.
57//!
58//! ### Tournament
59//!
60//! Tournament takes 2 parameters: the number of tournaments (`count`) and `participators`,
61//! which indicates how many phenotypes participate in a tournament.
62//! The resulting number of parents is `count`.
63//!
64//! ### Stochastic
65//!
66//! Stochastic takes 1 parameter: the count. The resulting number of parents is `count`.
67//!
68//! ## Early Stopping
69//!
70//! If you wish, you can stop early if the fitness value of the best performing Phenotype
71//! doesn't improve by a large amount for a number of iterations. This can be done by calling the
72//! `set_early_stop(delta: Fitness, n_iters: u32)` function on the `SimulatorBuilder`.
73//!
74//! # Examples
75//!
76//! ## Implementing the `Fitness` trait
77//!
78//! Note that, if your fitness type is an integer type, you
79//! do not need to write a wrapper struct around this integer. See
80//! the `types` module documentation for more details.
81//!
82//! ```
83//! use rsgenetic::pheno::*;
84//! use std::cmp::Ordering;
85//!
86//! #[derive(Eq, PartialEq, PartialOrd, Ord)]
87//! struct MyFitness {
88//! value: i32,
89//! }
90//!
91//! impl Fitness for MyFitness {
92//! // The zero value for our custom type
93//! fn zero() -> MyFitness {
94//! MyFitness { value: 0 }
95//! }
96//!
97//! // The absolute difference between two instances
98//! fn abs_diff(&self, other: &MyFitness) -> MyFitness {
99//! MyFitness {
100//! value: (self.value - other.value).abs()
101//! }
102//! }
103//! }
104//! ```
105//!
106//! ## Implementing the `Phenotype` trait
107//!
108//! Note that we use an integer type as the fitness type parameter
109//! to make this example more simple. Replace it with your custom type
110//! if needed. In this example, we try to find individuals with
111//! two integer components that sum to a target value.
112//!
113//! This example is far-fetched, but simplified to show how
114//! easy it is to define new individuals and implement
115//! the `Phenotype` trait.
116//!
117//! ```
118//! use rsgenetic::pheno::*;
119//!
120//! const TARGET: i32 = 100;
121//!
122//! #[derive(Copy, Clone)]
123//! struct MyPheno {
124//! x: i32,
125//! y: i32,
126//! }
127//!
128//! impl Phenotype<i32> for MyPheno {
129//! // How fit is this individual?
130//! fn fitness(&self) -> i32 {
131//! TARGET - (self.x + self.y)
132//! }
133//!
134//! // Have two individuals create a new individual
135//! fn crossover(&self, other: &MyPheno) -> MyPheno {
136//! MyPheno {
137//! x: self.x,
138//! y: other.y,
139//! }
140//! }
141//!
142//! // Mutate an individual, changing its state
143//! fn mutate(&self) -> MyPheno {
144//! MyPheno {
145//! x: self.x + 1,
146//! y: self.y - 1,
147//! }
148//! }
149//! }
150//! ```
151//!
152//! ## Creating and running a `Simulator`
153//!
154//! ```ignore
155//!
156//! use rsgenetic::sim::*;
157//! use rsgenetic::sim::seq::Simulator;
158//! use rsgenetic::sim::select::*;
159//!
160//! // (Assuming the above definition of `MyPheno` is in scope)
161//! // [ ... ]
162//!
163//! fn main() {
164//! let mut population = (0..100).map(|i| MyPheno { x: i, y: 100 - i }).collect();
165//! let mut s = Simulator::builder(&mut population)
166//! .set_selector(Box::new(StochasticSelector::new(10)))
167//! .set_max_iters(50)
168//! .build();
169//! s.run();
170//! let result = s.get().unwrap(); // The best individual
171//! }
172//! ```
173//!
174//! See the `examples` directory in the repository for more elaborate examples.
175
176#![deny(
177 missing_docs,
178 missing_debug_implementations,
179 missing_copy_implementations,
180 trivial_casts,
181 trivial_numeric_casts,
182 unsafe_code,
183 unstable_features,
184 unused_import_braces,
185 unused_qualifications
186)]
187
188extern crate rand;
189extern crate rayon;
190
191/// Contains the definition of a Phenotype.
192pub mod pheno;
193/// Contains implementations of Simulators, which can run genetic algorithms.
194pub mod sim;
195/// Contains code used by unit tests.
196#[cfg(test)]
197mod test;