Sort species by number of genomes to speed up parallelization. Add
constant ID to species.
This commit is contained in:
parent
16a5aab443
commit
bdc3ccaad7
5 changed files with 42 additions and 25 deletions
8
pool.lua
8
pool.lua
|
@ -276,6 +276,7 @@ end
|
|||
|
||||
local function newPool()
|
||||
local pool = {}
|
||||
pool.speciesId = 1
|
||||
pool.species = {}
|
||||
pool.generation = 0
|
||||
pool.innovation = Outputs
|
||||
|
@ -286,6 +287,8 @@ end
|
|||
|
||||
local function newSpecies()
|
||||
local species = {}
|
||||
species.id = pool.speciesId
|
||||
pool.speciesId = pool.speciesId + 1
|
||||
species.topFitness = 0
|
||||
species.staleness = 0
|
||||
species.genomes = {}
|
||||
|
@ -627,6 +630,10 @@ local function newGeneration()
|
|||
addToSpecies(child)
|
||||
end
|
||||
|
||||
table.sort(pool.species, function(a,b)
|
||||
return (#a.genomes < #b.genomes)
|
||||
end)
|
||||
|
||||
pool.generation = pool.generation + 1
|
||||
|
||||
writeFile(_M.saveLoadFile .. ".gen" .. pool.generation .. ".pool")
|
||||
|
@ -687,7 +694,6 @@ local function mainLoop(currentSpecies)
|
|||
runner.run(
|
||||
slice,
|
||||
pool.generation,
|
||||
currentSpecies,
|
||||
function()
|
||||
-- Genome callback
|
||||
end,
|
||||
|
|
|
@ -15,9 +15,13 @@ end
|
|||
|
||||
runnerData = runnerData()
|
||||
|
||||
local speciesIndex = runnerData[3]
|
||||
local species = runnerData[1]
|
||||
|
||||
local filename = runnerData[4]
|
||||
local speciesId = species.id
|
||||
|
||||
local generationIndex = runnerData[2]
|
||||
|
||||
local filename = runnerData[3]
|
||||
|
||||
local outFile = io.open(filename, "w")
|
||||
|
||||
|
@ -35,7 +39,7 @@ runner.onMessage(function(msg, color)
|
|||
outContents,
|
||||
serpent.dump({
|
||||
type = 'onMessage',
|
||||
speciesIndex = speciesIndex,
|
||||
speciesId = speciesId,
|
||||
msg = msg,
|
||||
color = color,
|
||||
})
|
||||
|
@ -66,7 +70,7 @@ runner.onSave(function(filename)
|
|||
serpent.dump({
|
||||
type = 'onSave',
|
||||
filename = filename,
|
||||
speciesIndex = speciesIndex,
|
||||
speciesId = speciesId,
|
||||
})
|
||||
)
|
||||
end)
|
||||
|
@ -77,15 +81,14 @@ runner.onLoad(function(filename)
|
|||
serpent.dump({
|
||||
type = 'onLoad',
|
||||
filename = filename,
|
||||
speciesIndex = speciesIndex,
|
||||
speciesId = speciesId,
|
||||
})
|
||||
)
|
||||
end)
|
||||
|
||||
runner.run(
|
||||
runnerData[1],
|
||||
runnerData[2],
|
||||
speciesIndex,
|
||||
species,
|
||||
generationIndex,
|
||||
function(genome, index)
|
||||
table.insert(
|
||||
outContents,
|
||||
|
@ -93,7 +96,7 @@ runner.run(
|
|||
type = 'onGenome',
|
||||
genome = genome,
|
||||
genomeIndex = index,
|
||||
speciesIndex = speciesIndex,
|
||||
speciesId = speciesId,
|
||||
})
|
||||
)
|
||||
end,
|
||||
|
@ -102,7 +105,7 @@ runner.run(
|
|||
outContents,
|
||||
serpent.dump({
|
||||
type = 'onFinish',
|
||||
speciesIndex = speciesIndex,
|
||||
speciesId = speciesId,
|
||||
})
|
||||
)
|
||||
outFile:write(table.concat(outContents, "\n"))
|
||||
|
|
|
@ -64,14 +64,14 @@ return function()
|
|||
onLoad(_M, handler)
|
||||
end
|
||||
|
||||
_M.run = function(species, generationIdx, speciesIdx, genomeCallback, finishCallback)
|
||||
_M.run = function(species, generationIdx, genomeCallback, finishCallback)
|
||||
local poppets = {}
|
||||
for i=1,#species,1 do
|
||||
local outputFileName = tmpFileName..'_output_'..i
|
||||
|
||||
local inputFileName = tmpFileName.."_input_"..i
|
||||
local inputFile = io.open(inputFileName, 'w')
|
||||
inputFile:write(serpent.dump({species[i], generationIdx, speciesIdx + i - 1, outputFileName}))
|
||||
inputFile:write(serpent.dump({species[i], generationIdx, outputFileName}))
|
||||
inputFile:close()
|
||||
|
||||
local cmd = "RUNNER_DATA=\""..inputFileName.."\" lsnes \"--rom="..config.ROM.."\" --unpause \"--lua="..base.."/runner-process.lua\""
|
||||
|
@ -109,7 +109,13 @@ return function()
|
|||
elseif obj.type == 'onSave' then
|
||||
save(_M, obj.filename)
|
||||
elseif obj.type == 'onGenome' then
|
||||
species[obj.speciesIndex - speciesIdx + 1].genomes[obj.genomeIndex] = obj.genome
|
||||
for i=1,#species,1 do
|
||||
local s = species[i]
|
||||
if s.id == obj.speciesId then
|
||||
s.genomes[obj.genomeIndex] = obj.genome
|
||||
break
|
||||
end
|
||||
end
|
||||
genomeCallback(obj.genome, obj.index)
|
||||
elseif obj.type == 'onFinish' then
|
||||
finishCallback()
|
||||
|
|
16
runner.lua
16
runner.lua
|
@ -258,7 +258,7 @@ function displayForm(_M)
|
|||
|
||||
gui.text(5, 30, "Timeout: " .. _M.timeout)
|
||||
gui.text(5, 5, "Generation: " .. _M.currentGenerationIndex)
|
||||
gui.text(130, 5, "Species: " .. _M.currentSpeciesIndex)
|
||||
gui.text(130, 5, "Species: " .. _M.currentSpecies.id)
|
||||
gui.text(230, 5, "Genome: " .. _M.currentGenomeIndex)
|
||||
gui.text(130, 30, "Max: " .. math.floor(_M.maxFitness))
|
||||
--gui.text(330, 5, "Measured: " .. math.floor(measured/total*100) .. "%")
|
||||
|
@ -302,7 +302,7 @@ local function evaluateNetwork(network, inputs, inputDeltas)
|
|||
table.insert(inputs, 1)
|
||||
table.insert(inputDeltas,99)
|
||||
if #inputs ~= Inputs then
|
||||
print("Incorrect number of neural network inputs.")
|
||||
message(_M, "Incorrect number of neural network inputs.", 0x00990000)
|
||||
return {}
|
||||
end
|
||||
|
||||
|
@ -401,7 +401,7 @@ local function mainLoop(_M, genome)
|
|||
if not pcall(function()
|
||||
displayGenome(genome)
|
||||
end) then
|
||||
message(_M, "Could not render genome graph")
|
||||
message(_M, "Could not render genome graph", 0x00990000)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -557,7 +557,7 @@ local function mainLoop(_M, genome)
|
|||
_M.genomeCallback(genome, _M.currentGenomeIndex)
|
||||
end
|
||||
|
||||
message(_M, string.format("Gen %d species %d genome %d fitness: %d", _M.currentGenerationIndex, _M.currentSpeciesIndex, _M.currentGenomeIndex, fitness))
|
||||
message(_M, string.format("Gen %d species %d genome %d fitness: %d", _M.currentGenerationIndex, _M.currentSpecies.id, _M.currentGenomeIndex, fitness))
|
||||
_M.currentGenomeIndex = 1
|
||||
while fitnessAlreadyMeasured(_M) do
|
||||
_M.currentGenomeIndex = _M.currentGenomeIndex + 1
|
||||
|
@ -792,11 +792,10 @@ local function saveLoadInput(_M)
|
|||
end
|
||||
end
|
||||
|
||||
local function run(_M, species, generationIdx, speciesIdx, genomeCallback, finishCallback)
|
||||
local function run(_M, species, generationIdx, genomeCallback, finishCallback)
|
||||
game.registerHandlers()
|
||||
|
||||
_M.currentGenerationIndex = generationIdx
|
||||
_M.currentSpeciesIndex = speciesIdx
|
||||
_M.currentSpecies = species
|
||||
_M.currentGenomeIndex = 1
|
||||
_M.genomeCallback = genomeCallback
|
||||
|
@ -841,7 +840,6 @@ end
|
|||
return function()
|
||||
local _M = {
|
||||
currentGenerationIndex = 1,
|
||||
currentSpeciesIndex = 1,
|
||||
currentSpecies = nil,
|
||||
finishCallback = nil,
|
||||
genomeCallback = nil,
|
||||
|
@ -897,8 +895,8 @@ return function()
|
|||
onLoad(_M, handler)
|
||||
end
|
||||
|
||||
_M.run = function(species, generationIdx, speciesIdx, genomeCallback, finishCallback)
|
||||
run(_M, species, generationIdx, speciesIdx, genomeCallback, finishCallback)
|
||||
_M.run = function(species, generationIdx, genomeCallback, finishCallback)
|
||||
run(_M, species, generationIdx, genomeCallback, finishCallback)
|
||||
end
|
||||
|
||||
return _M
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
#! /bin/bash
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
xpra start --bind-tcp=127.0.0.1:5309 --html=on --start-child="lsnes --lua=$SCRIPT_DIR/neat-donk.lua" --exit-with-child=yes --start-new-commands=no
|
||||
xdg-open http://127.0.0.1:5309
|
||||
PORT=5309
|
||||
xpra start --bind-tcp=127.0.0.1:$PORT --html=on --start-child="lsnes --lua=$SCRIPT_DIR/neat-donk.lua" --exit-with-child=yes --start-new-commands=no
|
||||
while ! nc -z localhost $PORT ; do
|
||||
sleep 0.1
|
||||
done
|
||||
xdg-open http://127.0.0.1:$PORT
|
||||
|
|
Loading…
Add table
Reference in a new issue