-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathalgorithms.go
More file actions
93 lines (79 loc) · 2.3 KB
/
algorithms.go
File metadata and controls
93 lines (79 loc) · 2.3 KB
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
88
89
90
91
92
93
package main
import (
"fmt"
"math/rand"
"os"
)
func CxOnePoint(ind1 []Polygon, ind2 []Polygon) ([]Polygon, []Polygon) {
size := len(ind1)
if len(ind2) < size {
size = len(ind2)
}
cxpoint := rand.Intn(size-2) + 1
temp := ind1[cxpoint:]
ind1 = append(ind1[:cxpoint], ind2[cxpoint:]...)
ind2 = append(ind2[:cxpoint], temp...)
return ind1, ind2
}
func BestSel(individuals []Individual) Individual {
best := Individual{fitness: 0}
for _, ind := range individuals {
if ind.fitness > best.fitness {
best = ind
}
}
return best
}
func TournSel(individuals []Individual, k int, tournsize int) []Individual {
var chosen []Individual
for i := 0; i < k; i++ {
var aspirant []Individual
for j := 0; j < tournsize; j++ {
aspirant = append(aspirant, individuals[rand.Intn(len(individuals))])
}
chosen = append(chosen, BestSel(aspirant))
}
return chosen
}
func clonePolygonSlice(ind *[]Polygon) []Polygon {
newInd := make([]Polygon, len(*ind))
for idx, elem := range *ind {
newInd[idx].color = elem.color
for _, point := range elem.vertices {
newInd[idx].vertices = append(newInd[idx].vertices, Point{point.x, point.y})
}
}
return newInd
}
func varOr(population []Individual, lambda int, cxpb float64, mutpb float64) []Individual {
if cxpb+mutpb > 1 {
fmt.Println("cx and mutation probabilities must sum < 1")
os.Exit(1)
}
var offspring []Individual
for i := 0; i < lambda; i++ {
choice := rand.Float64()
if choice < cxpb { // Apply crossover
idx1 := rand.Intn(len(population))
var idx2 = idx1
for idx2 == idx1 {
idx2 = rand.Intn(len(population))
}
ind1 := clonePolygonSlice(&population[idx1].elements)
ind2 := clonePolygonSlice(&population[idx2].elements)
ind1, ind2 = CxOnePoint(ind1, ind2)
if len(ind1) > 0 {
offspring = append(offspring, Individual{elements: ind1, fitness: -1})
}
} else if choice < cxpb+mutpb { // apply mutation
ind := clonePolygonSlice(&population[rand.Intn(len(population))].elements)
ind = mutate(ind)
offspring = append(offspring, Individual{elements: ind, fitness: -1})
} else { // Apply reproduction
idx := rand.Intn(len(population))
ind := clonePolygonSlice(&population[idx].elements)
offspring = append(offspring, Individual{elements: ind, fitness: population[idx].fitness})
}
}
return offspring
}