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