You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
2.1 KiB

  1. use rand::Rng;
  2. use rayon::prelude::*;
  3. pub struct Arena<T: Genetic> {
  4. pub keep: usize,
  5. pub mutate: usize,
  6. pub crossover: usize,
  7. pub set: Vec<T>,
  8. pub config: T::Configuration,
  9. }
  10. impl<T: Genetic> Arena<T> {
  11. pub fn new<R: Rng>(rng: &mut R, keep: usize, mutate: usize, crossover: usize, config: T::Configuration) -> Self {
  12. let mut set = Vec::new();
  13. for _ in 0..keep {
  14. set.push(T::generate(rng, &config));
  15. }
  16. Arena {
  17. keep,
  18. mutate,
  19. crossover,
  20. set,
  21. config,
  22. }
  23. }
  24. pub fn generate<R: Rng>(&mut self, rng: &mut R) {
  25. let n = self.set.len();
  26. for _ in 0..self.mutate {
  27. let which = rng.gen_range(0..n);
  28. let mutant = self.set[which].mutate(rng, &self.config);
  29. self.set.push(mutant);
  30. }
  31. for _ in 0..self.crossover {
  32. let p1 = rng.gen_range(0..n);
  33. let p2 = rng.gen_range(0..n);
  34. let child = self.set[p1].crossover(rng, &self.set[p2], &self.config);
  35. self.set.push(child);
  36. }
  37. }
  38. pub fn cull<R: Rng>(&mut self, rng: &mut R) {
  39. let config = &self.config;
  40. let set = &mut self.set;
  41. set.sort_by(|a, b| a.compare(rng, b, config));
  42. self.set.truncate(self.keep);
  43. }
  44. }
  45. impl <T: Genetic> Arena<T> where
  46. T: Send + Sync,
  47. T::Configuration: Sync,
  48. {
  49. pub fn par_process<F: Fn(&mut T, &T::Configuration) + Sync>(&mut self, f: F) {
  50. let config = &self.config;
  51. self.set.par_iter_mut().for_each(|x| f(x, config));
  52. }
  53. }
  54. impl<T: Genetic> Arena<T> where
  55. T: Send,
  56. T::Configuration: Sync,
  57. {
  58. pub fn par_cull(&mut self) {
  59. let config = &self.config;
  60. let set = &mut self.set;
  61. set.par_sort_unstable_by(|a, b| a.compare(&mut rand::thread_rng(), b, config));
  62. self.set.truncate(self.keep);
  63. }
  64. }
  65. pub trait Genetic {
  66. type Configuration;
  67. fn generate<R: Rng>(rng: &mut R, config: &Self::Configuration) -> Self;
  68. fn mutate<R: Rng>(&self, rng: &mut R, config: &Self::Configuration) -> Self;
  69. fn crossover<R: Rng>(&self, rng: &mut R, other: &Self, config: &Self::Configuration) -> Self;
  70. fn compare<R: Rng>(&self, rng: &mut R, other: &Self, config: &Self::Configuration) -> std::cmp::Ordering;
  71. }