-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfitness.lua
More file actions
148 lines (122 loc) · 3.33 KB
/
fitness.lua
File metadata and controls
148 lines (122 loc) · 3.33 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
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
function EvaluateNetwork(network, inputs)
table.insert(inputs, 1)
if #inputs ~= Inputs then
print("Incorrect number of neural network inputs.")
return {}
end
for i = 1, Inputs do
network.neurons[i].value = inputs[i]
end
for _, neuron in pairs(network.neurons) do
local sum = 0
for j = 1, #neuron.incoming do
local incoming = neuron.incoming[j]
local other = network.neurons[incoming.input]
sum = sum + incoming.weight * other.value
end
if #neuron.incoming > 0 then
neuron.value = ActFunc[UsedActivationFunction](sum)
end
end
local outputs = {}
for o = 1, Outputs do
local button = "P1 " .. ButtonNames[o]
if network.neurons[MaxNodes + o].value > 0 then
outputs[button] = true
else
outputs[button] = false
end
end
return outputs
end
function EvaluateCurrent()
local species = Pool.species[Pool.currentSpecies]
local genome = species.genomes[Pool.currentGenome]
inputs = GetInputs()
Controller = EvaluateNetwork(genome.network, inputs)
if Controller["P1 Left"] and Controller["P1 Right"] then
Controller["P1 Left"] = false
Controller["P1 Right"] = false
end
if Controller["P1 Up"] and Controller["P1 Down"] then
Controller["P1 Up"] = false
Controller["P1 Down"] = false
end
joypad.set(Controller)
end
function FitnessAlreadyMeasured()
local species = Pool.species[Pool.currentSpecies]
local genome = species.genomes[Pool.currentGenome]
return genome.fitness ~= 0
end
function RankGlobally()
local global = {}
for s = 1, #Pool.species do
local species = Pool.species[s]
for g = 1, #species.genomes do
table.insert(global, species.genomes[g])
end
end
table.sort(global, function (a, b) return (a.fitness < b.fitness) end)
for g = 1, #global do
global[g].globalRank = g
end
end
function CalculateAverageFitness(species)
local total = 0
for g = 1, #species.genomes do
local genome = species.genomes[g]
total = total + genome.globalRank
end
species.averageFitness = total / #species.genomes
end
function TotalAverageFitness()
local total = 0
for s = 1, #Pool.species do
local species = Pool.species[s]
total = total + species.averageFitness
end
return total
end
function CullSpecies(cutToOne)
for s = 1, #Pool.species do
local species = Pool.species[s]
table.sort(species.genomes, function (a, b) return (a.fitness > b.fitness) end)
local remaining = math.ceil(#species.genomes / 2)
if cutToOne then
remaining = 1
end
while #species.genomes > remaining do
table.remove(species.genomes)
end
end
end
function RemoveStaleSpecies()
local survived = {}
for s = 1, #Pool.species do
local species = Pool.species[s]
table.sort(species.genomes, function (a, b) return (a.fitness > b.fitness) end)
if species.genomes[1].fitness > species.topFitness then
species.topFitness = species.genomes[1].fitness
species.staleness = 0
else
species.staleness = species.staleness + 1
end
if species.staleness < StaleSpecies or species.topFitness >= Pool.maxFitness then
table.insert(survived, species)
end
end
Pool.species = survived
end
function RemoveWeakSpecies()
local survived = {}
local sum = TotalAverageFitness()
for s = 1, #Pool.species do
local species = Pool.species[s]
local breed = math.floor(species.averageFitness / sum * Population)
if breed >= 1 then
table.insert(survived, species)
end
end
Pool.species = survived
end