-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmutation.go
52 lines (42 loc) · 1.02 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
package main
func (indiv *individual) swap2OptIfOptimal(i, j int) bool {
n := len(indiv.tour)
k := (i + 1) % n
l := (j + 1) % n
oldPartialDist := dist(indiv.tour[i], indiv.tour[k]) + dist(indiv.tour[j], indiv.tour[l])
newPartialDist := dist(indiv.tour[i], indiv.tour[j]) + dist(indiv.tour[k], indiv.tour[l])
if newPartialDist < oldPartialDist {
// swap tour section
mid := (j - k + 1) / 2
for m := 0; m < mid; m++ {
indiv.tour[k+m], indiv.tour[j-m] = indiv.tour[j-m], indiv.tour[k+m]
}
// update fitness
indiv.fitness += newPartialDist - oldPartialDist
return true
}
return false
}
func (indiv *individual) optimize2OptOnce() bool {
n := len(indiv.tour)
for i := 0; i < n-2; i++ {
maxJ := n
if i == 0 {
maxJ = n - 1
}
for j := i + 2; j < maxJ; j++ {
if indiv.swap2OptIfOptimal(i, j) {
return true
}
}
}
return false
}
const num2OptForMutation = 1
func (indiv *individual) mutation() {
for i := 0; i < num2OptForMutation; i++ {
if !indiv.optimize2OptOnce() {
return
}
}
}