mutation.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package gago
  2. import (
  3. "math/rand"
  4. )
  5. // Type specific mutations for slices
  6. // MutNormalFloat64 modifies a float64 gene if a coin toss is under a defined
  7. // mutation rate. The new gene value is a random value sampled from a normal
  8. // distribution centered on the gene's current value and with a standard
  9. // deviation proportional to the current value. It does so for each gene.
  10. func MutNormalFloat64(genome []float64, rate float64, rng *rand.Rand) {
  11. for i := range genome {
  12. // Flip a coin and decide to mutate or not
  13. if rng.Float64() < rate {
  14. genome[i] += rng.NormFloat64() * genome[i]
  15. }
  16. }
  17. }
  18. // MutUniformString picks a gene at random and replaces it with a random from a
  19. // provided corpus. It repeats this n times.
  20. func MutUniformString(genome []string, corpus []string, n int, rng *rand.Rand) {
  21. for i := 0; i < n; i++ {
  22. var (
  23. element = corpus[rng.Intn(len(corpus))]
  24. pos = rng.Intn(len(genome))
  25. )
  26. genome[pos] = element
  27. }
  28. }
  29. // Generic mutations for slices
  30. // MutPermute permutes two genes at random n times.
  31. func MutPermute(genome Slice, n int, rng *rand.Rand) {
  32. // Nothing to permute
  33. if genome.Len() <= 1 {
  34. return
  35. }
  36. for i := 0; i < n; i++ {
  37. // Choose two points on the genome
  38. var points = randomInts(2, 0, genome.Len(), rng)
  39. genome.Swap(points[0], points[1])
  40. }
  41. }
  42. // MutPermuteInt calls MutPermute on an int slice.
  43. func MutPermuteInt(s []int, n int, rng *rand.Rand) {
  44. MutPermute(IntSlice(s), n, rng)
  45. }
  46. // MutPermuteFloat64 calls MutPermute on a float64 slice.
  47. func MutPermuteFloat64(s []float64, n int, rng *rand.Rand) {
  48. MutPermute(Float64Slice(s), n, rng)
  49. }
  50. // MutPermuteString callsMutPermute on a string slice.
  51. func MutPermuteString(s []string, n int, rng *rand.Rand) {
  52. MutPermute(StringSlice(s), n, rng)
  53. }
  54. // MutSplice splits a genome in 2 and glues the pieces back together in reverse
  55. // order.
  56. func MutSplice(genome Slice, rng *rand.Rand) {
  57. var (
  58. k = rng.Intn(genome.Len()-1) + 1
  59. a, b = genome.Split(k)
  60. )
  61. genome.Replace(b.Append(a))
  62. }
  63. // MutSpliceInt calls MutSplice on an int slice.
  64. func MutSpliceInt(s []int, rng *rand.Rand) {
  65. MutSplice(IntSlice(s), rng)
  66. }
  67. // MutSpliceFloat64 calls MutSplice on a float64 slice.
  68. func MutSpliceFloat64(s []float64, rng *rand.Rand) {
  69. MutSplice(Float64Slice(s), rng)
  70. }
  71. // MutSpliceString calls MutSplice on a string slice.
  72. func MutSpliceString(s []string, rng *rand.Rand) {
  73. MutSplice(StringSlice(s), rng)
  74. }