Created
March 6, 2016 20:11
-
-
Save TilBlechschmidt/3183acd71dc6f0243933 to your computer and use it in GitHub Desktop.
Gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub fn step<R: Rng>(&mut self, rng: &mut R) { | |
let games_per_ref = self.games_per_client / self.score_references.len(); | |
let mut pb = ProgressBar::new(self.current_generation.len()*self.score_references.len()*games_per_ref); | |
let mut avg_scores: Vec<(usize, f32)> = self.current_generation.iter().enumerate().map(|(index, contestant)| { | |
let threads = self.score_references.iter().map(|reference| { // TODO: Run this in multiple threads | |
thread::spawn(move || { | |
let rng = rand::thread_rng(); | |
(0..games_per_ref).map(|game_id| { | |
//TODO: Use the same game field for the same generation. | |
let mut g; | |
//if game_id%2 == 0 { // Change sides for every second game | |
g = Game::new_random(contestant, reference, &mut rng); | |
//} else { | |
// g = Game::new_random(reference, contestant, rng); | |
//} | |
let scores = g.run(); | |
pb.inc(); | |
scores[0] | |
}).collect::<Vec<_>>() | |
}) | |
}); | |
let scores = Vec::new(); | |
for handle in threads { | |
scores.extend(handle.join().unwrap()); // TODO: Remove unwrap | |
} | |
let score_sum = scores.iter().fold(0, |acc, score| score + acc); | |
//.fold(0, |acc, score| score + acc ) | |
// let score_sum = | |
// self.score_references.iter().flat_map(|reference| { // TODO: Run this in multiple threads | |
// (0..games_per_ref).map(|game_id| { | |
// //TODO: Use the same game field for the same generation. | |
// let mut g; | |
// //if game_id%2 == 0 { // Change sides for every second game | |
// g = Game::new_random(contestant, reference, rng); | |
// //} else { | |
// // g = Game::new_random(reference, contestant, rng); | |
// //} | |
// let scores = g.run(); | |
// pb.inc(); | |
// scores[0] | |
// }).collect::<Vec<_>>() | |
// }).fold(0, |acc, score| score + acc ); | |
let avg_score = score_sum as f32 / (games_per_ref * self.score_references.len()) as f32; | |
(index, avg_score) | |
}).collect(); | |
avg_scores.sort_by(|a, b| if a.1 < b.1 {Ordering::Greater} else {Ordering::Less}); | |
let new_score_refs = avg_scores | |
.iter().take(self.score_references.len()) | |
.map(|&(index, _)| self.current_generation[index].clone()) | |
.collect(); | |
let generation_size = self.current_generation.len(); | |
let mutation_per_survivor = (generation_size - self.survivor_count) / self.survivor_count; | |
let new_generation = avg_scores.iter().take(self.survivor_count).flat_map(|&(index, _)| { | |
let survivor = self.current_generation[index].clone(); | |
let mut mutations = (0..mutation_per_survivor).map(|_| { | |
let mut mutation = survivor.clone(); | |
mutation.mutate(self.mutation_amount, self.mutation_strength, rng); | |
mutation | |
}).collect::<Vec<_>>(); | |
mutations.push(survivor); | |
mutations | |
}).collect::<Vec<_>>(); | |
if !(generation_size == new_generation.len()) { | |
println!("GENERATION SIZE CHANGED {} ---> {}", self.current_generation.len(), new_generation.len()); | |
} | |
println!("Best average score of generation is: {}", avg_scores[0].1); | |
self.current_generation = new_generation; | |
self.score_references = new_score_refs; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment