Permalink
Browse files

introduce Individual struct

  • Loading branch information...
1 parent aba9987 commit e45d60445c587285c1a07afd1711f9b17ead4150 @handcraftsman committed Jun 2, 2015
Showing with 38 additions and 30 deletions.
  1. +28 −19 src/lib.rs
  2. +5 −6 tests/lib_8_queens_tests.rs
  3. +5 −5 tests/lib_duplicate_string_tests.rs
View
@@ -9,19 +9,16 @@ pub mod genetic {
display: D,
length: usize,
optimal_fitness_value: usize,
- gene_set: &str) -> String
+ gene_set: &str) -> Individual
where F : Fn(&String)->usize,
- D : Fn(&String)
+ D : Fn(&Individual)
{
- let mut best_parent = generate_parent(gene_set, length);
- let mut best_fitness = get_fitness(&best_parent);
+ let mut best_parent = generate_parent(&get_fitness, gene_set, length);
display(&best_parent);
- while best_fitness < optimal_fitness_value {
- let child = mutate_parent(&best_parent, gene_set);
- let fitness = get_fitness(&child);
- if fitness > best_fitness {
- best_fitness = fitness;
+ while best_parent.fitness < optimal_fitness_value {
+ let child = mutate_parent(&best_parent, &get_fitness, gene_set);
+ if child.fitness > best_parent.fitness {
best_parent = child;
display(&best_parent);
}
@@ -30,25 +27,37 @@ pub mod genetic {
best_parent
}
- fn generate_parent(gene_set: &str, length: usize) -> String {
+ fn generate_parent<F>(get_fitness: F, gene_set: &str, length: usize) -> Individual
+ where F : Fn(&String)->usize
+ {
let mut rng = thread_rng();
let sample = sample(&mut rng, gene_set.chars(), length);
- sample.into_iter().collect()
+ let genes = sample.into_iter().collect();
+ let fitness = get_fitness(&genes);
+ Individual {genes: genes, fitness: fitness }
}
- fn mutate_parent(parent: &String, gene_set: &str) -> String {
+ fn mutate_parent<F>(parent1: &Individual, get_fitness: F, gene_set: &str) -> Individual
+ where F : Fn(&String)->usize
+ {
let mut rng = thread_rng();
let gene_index = rng.gen::<usize>() % gene_set.len();
- let parent_index = rng.gen::<usize>() % parent.len();
- let mut candidate = String::with_capacity(parent.len());
+ let parent_index = rng.gen::<usize>() % parent1.genes.len();
+ let mut candidate = String::with_capacity(parent1.genes.len());
if parent_index > 0 {
- candidate.push_str(&parent[..parent_index]);
+ candidate.push_str(&parent1.genes[..parent_index]);
}
candidate.push_str(&gene_set[gene_index..(1+gene_index)]);
- if parent_index+1 < parent.len() {
- candidate.push_str(&parent[parent_index+1..]);
+ if parent_index+1 < parent1.genes.len() {
+ candidate.push_str(&parent1.genes[parent_index+1..]);
}
- candidate
+ let fitness = get_fitness(&candidate);
+ Individual { genes: candidate, fitness: fitness }
+ }
+
+ pub struct Individual {
+ pub genes: String,
+ pub fitness: usize
}
-}
+}
@@ -12,19 +12,18 @@ mod tests {
let start = PreciseTime::now();
let gene_set = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#";
- let wrapped_display = |candidate: &String| {display_8_queens(&candidate, gene_set, start);};
+ let wrapped_display = |candidate: &genetic::Individual| {display_8_queens(&candidate, gene_set, start);};
let wrapped_get_fitness = |candidate: &String| -> usize {get_8_queens_fitness(&candidate, gene_set)};
let best = genetic::get_best(wrapped_get_fitness, wrapped_display, 8, 8*8*8*8, gene_set);
println!("Total time: {}", start.to(PreciseTime::now()));
- let best_fitness = get_8_queens_fitness(&best, gene_set);
- assert_eq!(best_fitness,8*8*8*8);
+ assert_eq!(best.fitness, 8*8*8*8);
}
- fn display_8_queens(candidate: &String, gene_set: &str, start: PreciseTime) {
+ fn display_8_queens(candidate: &genetic::Individual, gene_set: &str, start: PreciseTime) {
let now = PreciseTime::now();
let elapsed = start.to(now);
- let board:[[char; 8]; 8] = get_board(candidate, gene_set);
+ let board:[[char; 8]; 8] = get_board(&candidate.genes, gene_set);
for i in 0..8 {
let mut row = "".to_string();
for j in 0..8 {
@@ -34,7 +33,7 @@ mod tests {
println!("{}", row);
}
- println!("{}\t{}\t{}", candidate, get_8_queens_fitness(&candidate, gene_set), elapsed);
+ println!("{}\t{}\t{}", candidate.genes, candidate.fitness, elapsed);
}
fn get_8_queens_fitness(candidate: &String, gene_set: &str) -> usize {
@@ -13,19 +13,19 @@ mod tests {
let gene_set = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!.";
let target = "Not all those who wander are lost.";
- let wrapped_display = |candidate: &String| {display_duplicate_string(&candidate, target, start);};
+ let wrapped_display = |candidate: &genetic::Individual| {display_duplicate_string(&candidate, target, start);};
let wrapped_get_fitness = |candidate: &String| -> usize {get_duplicate_string_fitness(&candidate, target)};
let best = genetic::get_best(wrapped_get_fitness, wrapped_display, target.len(), target.len(), gene_set);
- println!("{}", best);
+ display_duplicate_string(&best, target, start);
println!("Total time: {}", start.to(PreciseTime::now()));
- assert_eq!(best,target);
+ assert_eq!(best.genes, target);
}
- fn display_duplicate_string(candidate: &String, target: &str, start: PreciseTime) {
+ fn display_duplicate_string(candidate: &genetic::Individual, target: &str, start: PreciseTime) {
let now = PreciseTime::now();
let elapsed = start.to(now);
- println!("{}\t{}\t{}", candidate, get_duplicate_string_fitness(&candidate, target),elapsed);
+ println!("{}\t{}\t{}", candidate.genes, candidate.fitness, elapsed);
}
fn get_duplicate_string_fitness(candidate: &String, target: &str) -> usize {

0 comments on commit e45d604

Please sign in to comment.