pub struct Mutation { /* private fields */ }Expand description
Genetic Program mutation. Configures crossover (mating) on GP individuals.
Implementations§
Source§impl Mutation
impl Mutation
Sourcepub fn uniform() -> Mutation
pub fn uniform() -> Mutation
Perform mutation by randomly replacing a node with a new subtree.
Examples found in repository?
examples/snake.rs (line 272)
251fn main() {
252 let mut rng = OsRng::new().unwrap();
253 let mut tree_gen = TreeGen::full(&mut rng, 1, 4);
254
255 let mut indv1: Individual<SnakeTree> = Individual::new(&mut tree_gen);
256 let mut indv2: Individual<SnakeTree> = Individual::new(&mut tree_gen);
257
258 let mut rng = OsRng::new().unwrap();
259 let crossover = Crossover::one_point();
260 println!("---");
261 println!("{}", indv1);
262 println!("{}", indv2);
263 println!("---");
264 crossover.mate(&mut indv1, &mut indv2, &mut rng);
265 println!("{}", indv1);
266 println!("{}", indv2);
267 println!("---");
268
269 println!("{}", indv1);
270 let mut mutate_rng = OsRng::new().unwrap();
271 let mut tree_gen = TreeGen::full(&mut mutate_rng, 1, 2);
272 let mutation = Mutation::uniform();
273 mutation.mutate(&mut indv1, &mut tree_gen);
274 println!("{}", indv1);
275
276 let mut env = SnakeEnvironment {
277 size: Vector { x: 10, y: 10 },
278 food: Vector { x: 9, y: 9 },
279 snake: vec![Vector { x: 3, y: 3 }, Vector { x: 4, y: 3 }],
280 };
281
282 for _ in 0..200 {
283 let indv: Individual<SnakeTree> = Individual::new(&mut tree_gen);
284
285 let mut score1 = 0;
286 let mut score2 = 0;
287 let mut tick = 100;
288 while tick > 0 {
289 //println!("{:?} {:?}", tick, env.snake);
290 let move_ = indv.tree.evaluate(&env);
291 if env.sense_danger(move_) {
292 break;
293 }
294 if env.sense_food(move_) {
295 score2 += 1;
296 tick += 100;
297 env.food = Vector {
298 x: rng.gen_range(0, 11),
299 y: rng.gen_range(0, 11),
300 };
301 }
302 env.perform_movement(move_);
303 score1 += 1;
304 tick -= 1;
305 }
306 if score2 >= 1 {
307 println!("lived={:?} ate={:?}", score1, score2);
308 println!("{}", indv);
309 }
310 }
311}More examples
examples/symbolic_regression.rs (line 159)
150fn main() {
151 let mut rng = OsRng::new().unwrap();
152 let mut tree_gen = TreeGen::full(&mut rng, 1, 4);
153
154 let mut rng = OsRng::new().unwrap();
155 let crossover = Crossover::one_point();
156
157 let mut mutate_rng = OsRng::new().unwrap();
158 let mut mut_tree_gen = TreeGen::full(&mut mutate_rng, 1, 2);
159 let mutation = Mutation::uniform();
160
161 let inputs: Vec<f64> = (-10..11).map(|i| (i as f64) / 10.0).collect();
162 let expecteds: Vec<f64> = inputs.iter()
163 .cloned()
164 .map(|i| i.powi(4) + i.powi(3) + i.powi(2) + i)
165 .collect();
166
167 let mut population: Vec<Individual<Equation>> =
168 (0..200).map(|_| Individual::new(&mut tree_gen)).collect();
169 for round in 0..40 {
170 let mut ranking = BinaryHeap::new();
171 for individual in population.drain(..) {
172 let mut sum_of_squared_errors = 0.0;
173 for i in 0..inputs.len() {
174 let input = inputs[i];
175 let expected = expecteds[i];
176 let output = individual.tree.evaluate(&input);
177 let squared_error = (output - expected).powi(2);
178 sum_of_squared_errors += squared_error;
179 }
180 if !sum_of_squared_errors.is_finite() {
181 sum_of_squared_errors = 100000000000.0;
182 }
183 ranking.push(RankedIndividual(sum_of_squared_errors, individual));
184 }
185
186 let ranking = ranking.into_sorted_vec();
187 //println!("{:?}", ranking);
188
189 println!("=== ROUND {} ===", round);
190 for i in 0..3 {
191 println!("Rank {:?}\n Range = [-1.0, 1.0] Step = +0.1\n Comparing to x^4 + x^3 \
192 + x^2 + x\n Sum of squared error = {}\n Equation = {}",
193 i,
194 ranking[i].0,
195 ranking[i].1);
196 }
197
198 for i in 0..100 {
199 let RankedIndividual(_, mut indv1) = ranking[i].clone();
200 let RankedIndividual(_, mut indv2) = ranking[i + 1].clone();
201
202 population.push(indv1.clone());
203 population.push(indv2.clone());
204
205 crossover.mate(&mut indv1, &mut indv2, &mut rng);
206
207 if rng.gen() {
208 mutation.mutate(&mut indv1, &mut mut_tree_gen);
209 }
210 if rng.gen() {
211 mutation.mutate(&mut indv2, &mut mut_tree_gen);
212 }
213
214 population.push(indv1);
215 population.push(indv2);
216 }
217
218 println!();
219 }
220}Sourcepub fn mutate<T, R>(&self, indv: &mut Individual<T>, tg: &mut TreeGen<'_, R>)
pub fn mutate<T, R>(&self, indv: &mut Individual<T>, tg: &mut TreeGen<'_, R>)
Mutate an individual according to the configured mutation mode.
Examples found in repository?
examples/snake.rs (line 273)
251fn main() {
252 let mut rng = OsRng::new().unwrap();
253 let mut tree_gen = TreeGen::full(&mut rng, 1, 4);
254
255 let mut indv1: Individual<SnakeTree> = Individual::new(&mut tree_gen);
256 let mut indv2: Individual<SnakeTree> = Individual::new(&mut tree_gen);
257
258 let mut rng = OsRng::new().unwrap();
259 let crossover = Crossover::one_point();
260 println!("---");
261 println!("{}", indv1);
262 println!("{}", indv2);
263 println!("---");
264 crossover.mate(&mut indv1, &mut indv2, &mut rng);
265 println!("{}", indv1);
266 println!("{}", indv2);
267 println!("---");
268
269 println!("{}", indv1);
270 let mut mutate_rng = OsRng::new().unwrap();
271 let mut tree_gen = TreeGen::full(&mut mutate_rng, 1, 2);
272 let mutation = Mutation::uniform();
273 mutation.mutate(&mut indv1, &mut tree_gen);
274 println!("{}", indv1);
275
276 let mut env = SnakeEnvironment {
277 size: Vector { x: 10, y: 10 },
278 food: Vector { x: 9, y: 9 },
279 snake: vec![Vector { x: 3, y: 3 }, Vector { x: 4, y: 3 }],
280 };
281
282 for _ in 0..200 {
283 let indv: Individual<SnakeTree> = Individual::new(&mut tree_gen);
284
285 let mut score1 = 0;
286 let mut score2 = 0;
287 let mut tick = 100;
288 while tick > 0 {
289 //println!("{:?} {:?}", tick, env.snake);
290 let move_ = indv.tree.evaluate(&env);
291 if env.sense_danger(move_) {
292 break;
293 }
294 if env.sense_food(move_) {
295 score2 += 1;
296 tick += 100;
297 env.food = Vector {
298 x: rng.gen_range(0, 11),
299 y: rng.gen_range(0, 11),
300 };
301 }
302 env.perform_movement(move_);
303 score1 += 1;
304 tick -= 1;
305 }
306 if score2 >= 1 {
307 println!("lived={:?} ate={:?}", score1, score2);
308 println!("{}", indv);
309 }
310 }
311}More examples
examples/symbolic_regression.rs (line 208)
150fn main() {
151 let mut rng = OsRng::new().unwrap();
152 let mut tree_gen = TreeGen::full(&mut rng, 1, 4);
153
154 let mut rng = OsRng::new().unwrap();
155 let crossover = Crossover::one_point();
156
157 let mut mutate_rng = OsRng::new().unwrap();
158 let mut mut_tree_gen = TreeGen::full(&mut mutate_rng, 1, 2);
159 let mutation = Mutation::uniform();
160
161 let inputs: Vec<f64> = (-10..11).map(|i| (i as f64) / 10.0).collect();
162 let expecteds: Vec<f64> = inputs.iter()
163 .cloned()
164 .map(|i| i.powi(4) + i.powi(3) + i.powi(2) + i)
165 .collect();
166
167 let mut population: Vec<Individual<Equation>> =
168 (0..200).map(|_| Individual::new(&mut tree_gen)).collect();
169 for round in 0..40 {
170 let mut ranking = BinaryHeap::new();
171 for individual in population.drain(..) {
172 let mut sum_of_squared_errors = 0.0;
173 for i in 0..inputs.len() {
174 let input = inputs[i];
175 let expected = expecteds[i];
176 let output = individual.tree.evaluate(&input);
177 let squared_error = (output - expected).powi(2);
178 sum_of_squared_errors += squared_error;
179 }
180 if !sum_of_squared_errors.is_finite() {
181 sum_of_squared_errors = 100000000000.0;
182 }
183 ranking.push(RankedIndividual(sum_of_squared_errors, individual));
184 }
185
186 let ranking = ranking.into_sorted_vec();
187 //println!("{:?}", ranking);
188
189 println!("=== ROUND {} ===", round);
190 for i in 0..3 {
191 println!("Rank {:?}\n Range = [-1.0, 1.0] Step = +0.1\n Comparing to x^4 + x^3 \
192 + x^2 + x\n Sum of squared error = {}\n Equation = {}",
193 i,
194 ranking[i].0,
195 ranking[i].1);
196 }
197
198 for i in 0..100 {
199 let RankedIndividual(_, mut indv1) = ranking[i].clone();
200 let RankedIndividual(_, mut indv2) = ranking[i + 1].clone();
201
202 population.push(indv1.clone());
203 population.push(indv2.clone());
204
205 crossover.mate(&mut indv1, &mut indv2, &mut rng);
206
207 if rng.gen() {
208 mutation.mutate(&mut indv1, &mut mut_tree_gen);
209 }
210 if rng.gen() {
211 mutation.mutate(&mut indv2, &mut mut_tree_gen);
212 }
213
214 population.push(indv1);
215 population.push(indv2);
216 }
217
218 println!();
219 }
220}Trait Implementations§
impl Copy for Mutation
impl StructuralPartialEq for Mutation
Auto Trait Implementations§
impl Freeze for Mutation
impl RefUnwindSafe for Mutation
impl Send for Mutation
impl Sync for Mutation
impl Unpin for Mutation
impl UnwindSafe for Mutation
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more