💿🐜 Antkeeper source code https://antkeeper.com
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.

83 lines
2.7 KiB

  1. /*
  2. * Copyright (C) 2020 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef ANTKEEPER_DNA_MUTATE_HPP
  20. #define ANTKEEPER_DNA_MUTATE_HPP
  21. #include <algorithm>
  22. #include <iterator>
  23. #include <random>
  24. namespace dna
  25. {
  26. /**
  27. * Applies the given function to a randomly selected element in a range.
  28. *
  29. * @param first,last Range of elements to mutate.
  30. * @param unary_op Unary operation function object that will be applied.
  31. * @param g Uniform random bit generator.
  32. * @return Iterator to the mutated element.
  33. */
  34. template <class ForwardIt, class UnaryOperation, class URBG>
  35. ForwardIt mutate(ForwardIt first, ForwardIt last, UnaryOperation unary_op, URBG&& g);
  36. /**
  37. * Applies the given function to a random selection of elements in a range.
  38. *
  39. * @param first,last Range of elements to mutate.
  40. * @param count Number of elements to mutate.
  41. * @param unary_op Unary operation function object that will be applied.
  42. * @param g Uniform random bit generator.
  43. */
  44. template <class ForwardIt, class Size, class UnaryOperation, class URBG>
  45. void mutate_n(ForwardIt first, ForwardIt last, Size count, UnaryOperation unary_op, URBG&& g);
  46. template <class ForwardIt, class UnaryOperation, class URBG>
  47. ForwardIt mutate(ForwardIt first, ForwardIt last, UnaryOperation unary_op, URBG&& g)
  48. {
  49. typedef typename std::iterator_traits<ForwardIt>::difference_type difference_t;
  50. std::uniform_int_distribution<difference_t> distribution(0, std::distance(first, last) - 1);
  51. std::advance(first, distribution(g));
  52. *first = unary_op(*first);
  53. return first;
  54. }
  55. template <class ForwardIt, class Size, class UnaryOperation, class URBG>
  56. void mutate_n(ForwardIt first, ForwardIt last, Size count, UnaryOperation unary_op, URBG&& g)
  57. {
  58. typedef typename std::iterator_traits<ForwardIt>::difference_type difference_t;
  59. std::uniform_int_distribution<difference_t> distribution(0, std::distance(first, last) - 1);
  60. ForwardIt mutation;
  61. while (count)
  62. {
  63. mutation = first;
  64. std::advance(mutation, distribution(g));
  65. *mutation = unary_op(*mutation);
  66. --count;
  67. }
  68. }
  69. } // namespace dna
  70. #endif // ANTKEEPER_DNA_MUTATE_HPP