-
Notifications
You must be signed in to change notification settings - Fork 0
/
Representation.go
148 lines (128 loc) · 3.66 KB
/
Representation.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package main
import (
"math/rand"
)
type MatrixIndividual struct {
SegmentMatrix [][]int
DirectionMatrix [][]Direction
SegmentMap map[int][]Vertex
overallDeviation float64
edgeValue float64
Rank int
CrowdingDistance float64
Fitness float64
Dominates []*MatrixIndividual
DominatedBy int
}
func (i *MatrixIndividual) Init(graph Graph) {
randomKValue := rand.Intn((6000 - 5000) + 5000)
_, i.DirectionMatrix = graph.GraphSegmentation(randomKValue)
i.SegmentMatrix, i.SegmentMap = DirectionMatrixToSegmentMatrixAndSegmentMap(i.DirectionMatrix)
i.CalculateFitness()
}
func (i *MatrixIndividual) IsDominating(i2 *MatrixIndividual) bool {
if i.edgeValue == i2.edgeValue && i.overallDeviation == i2.overallDeviation {
return false
}
return i.edgeValue >= i2.edgeValue && i.overallDeviation <= i2.overallDeviation
}
func (i *MatrixIndividual) mutate() {
// Choose a random segment to merge
seg1ID := randomSegmentId(i.SegmentMap)
seg2ID := seg1ID
// Find the second one
visited := make(map[Vertex]bool)
opened := make(map[Vertex]bool)
queue := []Vertex{i.SegmentMap[seg1ID][rand.Intn(len(i.SegmentMap[seg1ID]))]}
for len(queue) > 0 && seg2ID == seg1ID {
n := queue[0]
visited[n] = true
queue = queue[1:]
neighbours := getAllCardinalNeighbours(n)
for neighbour := range neighbours {
if _, visited := visited[neighbours[neighbour]]; visited {
continue
}
if _, o := opened[neighbours[neighbour]]; !o {
queue = append(queue, neighbours[neighbour])
opened[neighbours[neighbour]] = true
segID := i.SegmentMatrix[neighbours[neighbour].X][neighbours[neighbour].Y]
if segID != seg1ID {
seg2ID = segID
continue
}
}
}
}
if seg1ID == seg2ID {
return
}
// Merge them
for _, n := range i.SegmentMap[seg2ID] {
i.SegmentMatrix[n.X][n.Y] = seg1ID
}
i.SegmentMap[seg1ID] = append(i.SegmentMap[seg1ID], i.SegmentMap[seg2ID]...)
delete(i.SegmentMap, seg2ID)
}
func (i *MatrixIndividual) CalculateFitness() {
i.edgeValue = i.EdgeValue()
i.overallDeviation = i.OverallDeviation()
i.Fitness = (i.edgeValue * float64(edgeWeight)) + (i.overallDeviation * float64(deviationWeight))
}
func (i *MatrixIndividual) OverallDeviation() float64 {
deviation := 0.0
for _, segment := range i.SegmentMap {
centeroid := averageSegmentColor(segment, pic)
p2 := rgbaToPixel(centeroid)
for _, node := range segment {
p1 := pic.pixels[node.X][node.Y]
deviation += euclideanDistance(&p1, &p2)
}
}
return deviation / float64(len(i.SegmentMap))
}
func (i *MatrixIndividual) EdgeValue() float64 {
edgeValue := 0.0
for segmentId := range i.SegmentMap {
for _, node := range i.SegmentMap[segmentId] {
p1 := pic.pixels[node.X][node.Y]
neighbours := getAllCardinalNeighbours(node)
for _, neighbour := range neighbours {
if inBounds(neighbour) {
if i.SegmentMatrix[node.X][node.Y] != i.SegmentMatrix[neighbour.X][neighbour.Y] {
p2 := pic.pixels[neighbour.X][neighbour.Y]
edgeValue += euclideanDistance(&p1, &p2)
}
}
}
}
}
return edgeValue / float64(len(i.SegmentMap))
}
func randomSegmentId(segmentMap map[int][]Vertex) int {
seg := rand.Intn(len(segmentMap))
counter := 0
for k := range segmentMap {
if counter == seg {
seg = k
}
counter++
}
return seg
}
//
/* just for converting back to the old repr for drawing */
func (i MatrixIndividual) segMapToDraw() [][]Vertex {
result := make([][]Vertex,0)
for seg := range i.SegmentMap {
result = append(result, i.SegmentMap[seg])
}
return result
}
func (i MatrixIndividual) segMapToIdMapDraw() [][]Vertex {
result := make([][]Vertex,0)
for seg := range i.SegmentMap {
result = append(result, i.SegmentMap[seg])
}
return result
}