diff --git a/CMakeLists.txt b/CMakeLists.txt index 18c01b71..65664cef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,57 +1,77 @@ cmake_minimum_required(VERSION 3.3) project(MultiNEAT) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + +if(MINGW OR CYGWIN) + add_definitions(-O3) +endif() + +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj") find_package(PythonLibs REQUIRED) include(FindPythonLibs) +#set(Boost_Path "C:/boost/include") + +#set(BOOST_ROOT "C:\\Boost") +#set(BOOSTROOT "C:\\Boost") + +add_definitions("-DMS_WIN64") set(Boost_USE_STATIC_LIBS OFF) # only find static libs set(Boost_USE_MULTITHREADED ON) -set(Boost_USE_STATIC_RUNTIME OFF) -find_package(Boost COMPONENTS - date_time - system - filesystem - python3 - serialization) +set(Boost_USE_STATIC_RUNTIME OFF) + +find_package(BOOST COMPONENTS REQUIRED + system + python + numpy + date_time + filesystem + serialization) + if(Boost_FOUND) + message(STATUS "It works!") include_directories(${Boost_INCLUDE_DIRS}) + link_directories("C:/Boost/lib") endif() + include_directories(${PYTHON_INCLUDE_DIRS}) add_definitions(-DUSE_BOOST_PYTHON) +#add_definitions(-DUSE_BOOST_NUMPY) add_definitions(-DUSE_BOOST_RANDOM) +#add_definitions(-DVDEBUG) + + +add_executable(MultiNEAT ${PROJECT_SOURCE_DIR}/src/Assert.h + ${PROJECT_SOURCE_DIR}/src/Genes.h + ${PROJECT_SOURCE_DIR}/src/Genome.cpp + ${PROJECT_SOURCE_DIR}/src/Genome.h + ${PROJECT_SOURCE_DIR}/src/Innovation.cpp + ${PROJECT_SOURCE_DIR}/src/Innovation.h + ${PROJECT_SOURCE_DIR}/src/Main.cpp + ${PROJECT_SOURCE_DIR}/src/NeuralNetwork.cpp + ${PROJECT_SOURCE_DIR}/src/NeuralNetwork.h + ${PROJECT_SOURCE_DIR}/src/Parameters.cpp + ${PROJECT_SOURCE_DIR}/src/Parameters.h + ${PROJECT_SOURCE_DIR}/src/PhenotypeBehavior.cpp + ${PROJECT_SOURCE_DIR}/src/PhenotypeBehavior.h + ${PROJECT_SOURCE_DIR}/src/Population.cpp + ${PROJECT_SOURCE_DIR}/src/Population.h + ${PROJECT_SOURCE_DIR}/src/PythonBindings.cpp + ${PROJECT_SOURCE_DIR}/src/Random.cpp + ${PROJECT_SOURCE_DIR}/src/Random.h + ${PROJECT_SOURCE_DIR}/src/Species.cpp + ${PROJECT_SOURCE_DIR}/src/Species.h + ${PROJECT_SOURCE_DIR}/src/Substrate.cpp + ${PROJECT_SOURCE_DIR}/src/Substrate.h + ${PROJECT_SOURCE_DIR}/src/Utils.cpp + ${PROJECT_SOURCE_DIR}/src/Utils.h + ${PROJECT_SOURCE_DIR}/src/Traits.h + ${PROJECT_SOURCE_DIR}/src/Traits.cpp) -set(SOURCE_FILES - src/Assert.h - src/Genes.h - src/Genome.cpp - src/Genome.h - src/Innovation.cpp - src/Innovation.h - src/Main.cpp - src/NeuralNetwork.cpp - src/NeuralNetwork.h - src/Parameters.cpp - src/Parameters.h - src/PhenotypeBehavior.cpp - src/PhenotypeBehavior.h - src/Population.cpp - src/Population.h - src/PythonBindings.cpp - src/Random.cpp - src/Random.h - src/Species.cpp - src/Species.h - src/Substrate.cpp - src/Substrate.h - src/Utils.cpp - src/Utils.h - src/Traits.h - src/Traits.cpp) - - -add_executable(MultiNEAT ${SOURCE_FILES}) -target_link_libraries(MultiNEAT ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} pthread) +target_link_libraries(MultiNEAT + "ws2_32" + ${BOOST_LIBRARIES} + ${PYTHON_LIBRARIES}) diff --git a/CMakeLists_MinGW64.txt b/CMakeLists_MinGW64.txt new file mode 100644 index 00000000..4e8ba5ca --- /dev/null +++ b/CMakeLists_MinGW64.txt @@ -0,0 +1,84 @@ +cmake_minimum_required(VERSION 3.3) +project(MultiNEAT) + + +if(MINGW OR CYGWIN) + add_definitions(-O3) +endif() + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj") + +find_package(PythonLibs REQUIRED) +include(FindPythonLibs) +#set(Boost_Path "C:/boost/include") + +#set(BOOST_ROOT "C:\\Boost") +#set(BOOSTROOT "C:\\Boost") + +#add_definitions("-DMS_WIN64") + +set(Boost_USE_STATIC_LIBS OFF) # only find static libs +set(Boost_USE_MULTITHREADED ON) +set(Boost_USE_STATIC_RUNTIME OFF) + +find_package(BOOST COMPONENTS REQUIRED + system + python36 + numpy36 + date_time + filesystem + serialization) + +if(Boost_FOUND) + message(STATUS "It works!") + include_directories(${Boost_INCLUDE_DIRS}) + link_directories("C:/Boost/lib") +endif() + + +include_directories(${PYTHON_INCLUDE_DIRS}) + +add_definitions(-DUSE_BOOST_PYTHON) +add_definitions(-DUSE_BOOST_NUMPY) +add_definitions(-DUSE_BOOST_RANDOM) +#add_definitions(-DVDEBUG) + + +add_executable(MultiNEAT ${PROJECT_SOURCE_DIR}/src/Assert.h + ${PROJECT_SOURCE_DIR}/src/Genes.h + ${PROJECT_SOURCE_DIR}/src/Genome.cpp + ${PROJECT_SOURCE_DIR}/src/Genome.h + ${PROJECT_SOURCE_DIR}/src/Innovation.cpp + ${PROJECT_SOURCE_DIR}/src/Innovation.h + ${PROJECT_SOURCE_DIR}/src/Main.cpp + ${PROJECT_SOURCE_DIR}/src/NeuralNetwork.cpp + ${PROJECT_SOURCE_DIR}/src/NeuralNetwork.h + ${PROJECT_SOURCE_DIR}/src/Parameters.cpp + ${PROJECT_SOURCE_DIR}/src/Parameters.h + ${PROJECT_SOURCE_DIR}/src/PhenotypeBehavior.cpp + ${PROJECT_SOURCE_DIR}/src/PhenotypeBehavior.h + ${PROJECT_SOURCE_DIR}/src/Population.cpp + ${PROJECT_SOURCE_DIR}/src/Population.h + ${PROJECT_SOURCE_DIR}/src/PythonBindings.cpp + ${PROJECT_SOURCE_DIR}/src/Random.cpp + ${PROJECT_SOURCE_DIR}/src/Random.h + ${PROJECT_SOURCE_DIR}/src/Species.cpp + ${PROJECT_SOURCE_DIR}/src/Species.h + ${PROJECT_SOURCE_DIR}/src/Substrate.cpp + ${PROJECT_SOURCE_DIR}/src/Substrate.h + ${PROJECT_SOURCE_DIR}/src/Utils.cpp + ${PROJECT_SOURCE_DIR}/src/Utils.h + ${PROJECT_SOURCE_DIR}/src/Traits.h + ${PROJECT_SOURCE_DIR}/src/Traits.cpp) + +target_link_libraries(MultiNEAT + "ws2_32" +# ${BOOST_LIBRARIES} + "boost_system-mgw81-mt-x64-1_71" + "boost_filesystem-mgw81-mt-x64-1_71" + "boost_serialization-mgw81-mt-x64-1_71" + "boost_date_time-mgw81-mt-x64-1_71" + "boost_random-mgw81-mt-x64-1_71" + "boost_python36-mgw81-mt-x64-1_71" + "boost_numpy36-mgw81-mt-x64-1_71" + ${PYTHON_LIBRARIES} pthread) diff --git a/MultiNEAT.sln b/MultiNEAT.sln index a772ac1a..b1d4ebcb 100644 --- a/MultiNEAT.sln +++ b/MultiNEAT.sln @@ -1,7 +1,9 @@  -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MultiNEAT", "MultiNEAT.vcproj", "{826B4E58-F9C4-45F1-BFE3-4E8B16D37AA6}" +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.1082 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MultiNEAT", "MultiNEAT.vcxproj", "{826B4E58-F9C4-45F1-BFE3-4E8B16D37AA6}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -17,4 +19,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {57264A91-576A-4F26-B2AA-727EE1EAED34} + EndGlobalSection EndGlobal diff --git a/MultiNEAT/__init__.py b/MultiNEAT/__init__.py index ac00287d..aa15c997 100644 --- a/MultiNEAT/__init__.py +++ b/MultiNEAT/__init__.py @@ -21,17 +21,29 @@ def ZipFitness(genome_list, fitness_list): try: import networkx as nx - def Genome2NX(g): + def Genome2NX(g, with_inputs=False, with_weights=False): nts = g.GetNeuronTraits() - lts = g.GetLinkTraits() + lts = g.GetLinkTraits(with_weights) gr = nx.DiGraph() for i, tp, traits in nts: - gr.add_node( i, **traits) - - for inp, outp, traits in lts: - gr.add_edge( inp, outp, **traits ) + if with_inputs: + gr.add_node( i, **traits) + else: + # don't add traits on inputs + if tp != 'input': + gr.add_node( i, **traits) + else: + gr.add_node( i ) + + if not with_weights: + for inp, outp, traits in lts: + gr.add_edge( inp, outp, **traits) + else: + for inp, outp, traits, w in lts: + t = {**traits, 'w':w} + gr.add_edge( inp, outp, **t) gr.genome_traits = g.GetGenomeTraits() diff --git a/MultiNEAT/viz.py b/MultiNEAT/viz.py index b5323715..3727909b 100644 --- a/MultiNEAT/viz.py +++ b/MultiNEAT/viz.py @@ -30,15 +30,12 @@ def AlmostEqual(a, b, margin): except: print('Install NumPy for visualization') - try: import cv2 cvnumpy_installed = True except: print ('Tip: install the OpenCV computer vision library (2.0+) with ' - 'Python bindings') - print (' to get convenient neural network visualization to NumPy ' - 'arrays') + 'Python bindings to get convenient neural network visualization to NumPy arrays.') cvnumpy_installed = False try: diff --git a/_MultiNEAT.pyx b/_MultiNEAT.pyx index 860f05f9..934ab52c 100644 --- a/_MultiNEAT.pyx +++ b/_MultiNEAT.pyx @@ -920,8 +920,8 @@ cdef class Genome: def BuildHyperNEATPhenotype(self, NeuralNetwork net, Substrate subst): self.thisptr.BuildHyperNEATPhenotype(deref(net.thisptr), deref(subst.thisptr)) - def BuildESHyperNEATPhenotype(Genome self, NeuralNetwork a_net, Substrate subst, Parameters params): - self.thisptr.BuildESHyperNEATPhenotype(deref(a_net.thisptr), deref(subst.thisptr), deref(params.thisptr)) + #def BuildESHyperNEATPhenotype(Genome self, NeuralNetwork a_net, Substrate subst, Parameters params): + # self.thisptr.BuildESHyperNEATPhenotype(deref(a_net.thisptr), deref(subst.thisptr), deref(params.thisptr)) def Save(self, str a_filename): self.thisptr.Save(a_filename) diff --git a/conda/build.sh b/conda/build.sh old mode 100755 new mode 100644 diff --git a/conda/meta.yaml b/conda/meta.yaml index 9e26d3e0..ea49cb41 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -1,6 +1,6 @@ package: name: multineat - version: 0.5 # Update version in setup.py as well + version: 0.6 # Update version in setup.py as well build: number: diff --git a/conda/run_test.sh b/conda/run_test.sh old mode 100755 new mode 100644 diff --git a/examples/PythonObjectTraits.ipynb b/examples/PythonObjectTraits.ipynb index c74b47f5..319e78a6 100644 --- a/examples/PythonObjectTraits.ipynb +++ b/examples/PythonObjectTraits.ipynb @@ -2,17 +2,9 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Populating the interactive namespace from numpy and matplotlib\n" - ] - } - ], + "outputs": [], "source": [ "%pylab inline \n", "\n", @@ -38,7 +30,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -59,7 +51,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -114,27 +106,9 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(100, 100)\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# load the target picture\n", "target_img = cv2.imread('smiley.jpg')\n", @@ -152,7 +126,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -195,7 +169,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -215,17 +189,9 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Inputs: 1 Outputs: 1 Links: 1\n" - ] - } - ], + "outputs": [], "source": [ "run_name = str(uuid.uuid4()).replace('-', '')[0:16]\n", "\n", @@ -245,122 +211,9 @@ }, { "cell_type": "code", - "execution_count": 8, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "============================================================\n", - "Please wait for the initial evaluation to complete.\n", - "======================\n", - "rtNEAT phase\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "# generational mode\n", "if generational_mode:\n", @@ -573,9 +426,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.8" } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/TestNEAT_xor.py b/examples/TestNEAT_xor.py index f652d38d..b9d6bc2b 100644 --- a/examples/TestNEAT_xor.py +++ b/examples/TestNEAT_xor.py @@ -104,19 +104,21 @@ def evaluate(genome): params.AllowClones = True def getbest(i): - g = NEAT.Genome(0, 3, 0, 1, False, NEAT.ActivationFunction.UNSIGNED_SIGMOID, - NEAT.ActivationFunction.UNSIGNED_SIGMOID, 0, params, 0) + gi = NEAT.GenomeInitStruct() + gi.NumInputs = 3 + g = NEAT.Genome(params, gi) pop = NEAT.Population(g, params, True, 1.0, i) - pop.RNG.Seed(int(time.clock()*100)) + pop.RNG.Seed(int(time.perf_counter()*100)) generations = 0 - for generation in range(1000): + for generation in range(300): genome_list = NEAT.GetGenomeList(pop) fitness_list = EvaluateGenomeList_Serial(genome_list, evaluate, display=False) NEAT.ZipFitness(genome_list, fitness_list) pop.Epoch() generations = generation best = max(fitness_list) + print('gen:', generation, 'best:',best) if best > 15.0: break @@ -124,7 +126,7 @@ def getbest(i): gens = [] -for run in range(100): +for run in range(1000): gen = getbest(run) gens += [gen] print('Run:', run, 'Generations to solve XOR:', gen) diff --git a/examples/TestTraits.py b/examples/TestTraits.py index 648f253d..fdeddc32 100644 --- a/examples/TestTraits.py +++ b/examples/TestTraits.py @@ -104,8 +104,9 @@ def custom_constraint(genome): params.CustomConstraints = custom_constraint # the seed genome and test population -g = NEAT.Genome(0, 3, 0, 1, False, NEAT.ActivationFunction.UNSIGNED_SIGMOID, - NEAT.ActivationFunction.UNSIGNED_SIGMOID, 0, params, 0) +gi = NEAT.GenomeInitStruct() +gi.NumInputs = 3 +g = NEAT.Genome(params, gi) pop = NEAT.Population(g, params, True, 1.0, rnd.randint(0, 100)) pop.RNG.Seed(int(time.clock()*100)) diff --git a/examples/ball_keeper.py b/examples/ball_keeper.py index c46f9b5f..6485366c 100644 --- a/examples/ball_keeper.py +++ b/examples/ball_keeper.py @@ -298,7 +298,7 @@ def main(): g = NEAT.Genome(0, 6, 0, 2, False, - NEAT.ActivationFunction.TANH, NEAT.ActivationFunction.UNSIGNED_SIGMOID, 0, params, 0) + NEAT.ActivationFunction.TANH, NEAT.ActivationFunction.UNSIGNED_SIGMOID, 0, params, 0, 1) pop = NEAT.Population(g, params, True, 1.0, rnd.randint(0, 1000)) best_genome_ever = None diff --git a/examples/gym/lunar_lander.py b/examples/gym/lunar_lander.py index 4a4967cb..3c9c3d39 100644 --- a/examples/gym/lunar_lander.py +++ b/examples/gym/lunar_lander.py @@ -8,6 +8,7 @@ import pickle import numpy as np import cv2 +from tqdm import tqdm rng = NEAT.RNG() rng.TimeSeed() @@ -72,7 +73,7 @@ render_during_training = 0 g = NEAT.Genome(0, 8 +1, 0, 4, False, - NEAT.ActivationFunction.TANH, NEAT.ActivationFunction.TANH, 0, params, 0) + NEAT.ActivationFunction.TANH, NEAT.ActivationFunction.TANH, 0, params, 0, 1) pop = NEAT.Population(g, params, True, 1.0, rnd.randint(0, 1000)) @@ -129,7 +130,7 @@ def do_trial(): for generation in range(20): - for i_episode, genome in enumerate(NEAT.GetGenomeList(pop)): + for i_episode, genome in tqdm(enumerate(NEAT.GetGenomeList(pop))): net = NEAT.NeuralNetwork() genome.BuildPhenotype(net) diff --git a/examples/gym/walker.py b/examples/gym/walker.py index 42aa0577..427b3510 100644 --- a/examples/gym/walker.py +++ b/examples/gym/walker.py @@ -8,32 +8,33 @@ import random as rnd import pickle import numpy as np +from tqdm import tqdm import cv2 substrate = NEAT.Substrate([(-1, -1), (-1, 0), (-1, 1)], [(0, -1), (0, 0), (0, 1)], [(1, 0)]) -substrate.m_allow_input_hidden_links = False; -substrate.m_allow_input_output_links = False; -substrate.m_allow_hidden_hidden_links = False; -substrate.m_allow_hidden_output_links = False; -substrate.m_allow_output_hidden_links = False; -substrate.m_allow_output_output_links = False; -substrate.m_allow_looped_hidden_links = False; -substrate.m_allow_looped_output_links = False; +substrate.m_allow_input_hidden_links = False +substrate.m_allow_input_output_links = False +substrate.m_allow_hidden_hidden_links = False +substrate.m_allow_hidden_output_links = False +substrate.m_allow_output_hidden_links = False +substrate.m_allow_output_output_links = False +substrate.m_allow_looped_hidden_links = False +substrate.m_allow_looped_output_links = False -substrate.m_allow_input_hidden_links = True; -substrate.m_allow_input_output_links = False; -substrate.m_allow_hidden_output_links = True; -substrate.m_allow_hidden_hidden_links = False; +substrate.m_allow_input_hidden_links = True +substrate.m_allow_input_output_links = False +substrate.m_allow_hidden_output_links = True +substrate.m_allow_hidden_hidden_links = False -substrate.m_hidden_nodes_activation = NEAT.ActivationFunction.SIGNED_SIGMOID; -substrate.m_output_nodes_activation = NEAT.ActivationFunction.UNSIGNED_SIGMOID; +substrate.m_hidden_nodes_activation = NEAT.ActivationFunction.SIGNED_SIGMOID +substrate.m_output_nodes_activation = NEAT.ActivationFunction.UNSIGNED_SIGMOID -substrate.m_with_distance = True; +substrate.m_with_distance = True -substrate.m_max_weight_and_bias = 8.0; +substrate.m_max_weight_and_bias = 8.0 try: x = pickle.dumps(substrate) @@ -129,7 +130,7 @@ def main(): generations = 10 g = NEAT.Genome(0, 24 + 1 + 1, 0, 4, False, - NEAT.ActivationFunction.TANH, NEAT.ActivationFunction.TANH, 0, params, 0) + NEAT.ActivationFunction.TANH, NEAT.ActivationFunction.TANH, 0, params, 0, 1) pop = NEAT.Population(g, params, True, 1.0, rnd.randint(0, 1000)) hof = [] maxf_ever = 0 @@ -142,7 +143,7 @@ def main(): #args = [x for x in NEAT.GetGenomeList(pop)] #dv.block=True #fitnesses = dv.map_sync(evaluate_genome, args) - for _, genome in enumerate(NEAT.GetGenomeList(pop)): + for _, genome in tqdm(enumerate(NEAT.GetGenomeList(pop))): fitness = evaluate_genome(env, genome, trials) fitnesses.append(fitness) for genome, fitness in zip(NEAT.GetGenomeList(pop), fitnesses): @@ -184,10 +185,10 @@ def do_trial(env, net, render_during_training): net.Flush() f = 0 - for t in range(300): + for t in range(500): if render_during_training: - time.sleep(0.001) + #time.sleep(0.001) env.render() # interact with NN diff --git a/setup.py b/setup.py index e8522013..eddf8322 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ -#!/usr/bin/python +#!/usr/bin/python3 -from __future__ import print_function +#from __future__ import print_function from setuptools import setup, Extension import sys import os @@ -23,15 +23,15 @@ def _single_compile(obj): list(multiprocessing.pool.ThreadPool(N).imap(_single_compile,objects)) return objects -import distutils.ccompiler -distutils.ccompiler.CCompiler.compile=parallelCCompile +#import distutils.ccompiler +#distutils.ccompiler.CCompiler.compile=parallelCCompile ''' Note: to build Boost.Python on Windows with mingw -bjam target-os=windows/python=3.4 toolset=gcc variant=debug,release link=static,shared threading=multi runtime-link=shared cxxflags="-include cmath " +bjam target-os=windows/python=3.9 toolset=gcc variant=debug,release link=static,shared threading=multi runtime-link=shared cxxflags="-include cmath " also insert this on top of boost/python.hpp : @@ -57,7 +57,8 @@ def getExtensions(): 'src/Utils.cpp'] extra = ['-march=native', - '-g' + '-mtune=native', + '-g', ] if platform == 'darwin': @@ -67,10 +68,13 @@ def getExtensions(): extra += ['-std=gnu++11'] is_windows = 'win' in platform and platform != 'darwin' + #if is_windows: + # extra.append('/EHsc') + #else: + # extra.append('-w') if is_windows: - extra.append('/EHsc') - else: - extra.append('-w') + extra.append('-IC:/Boost/include/') + extra.append('-LC:/Boost/lib') prefix = os.getenv('PREFIX') if prefix and len(prefix) > 0: @@ -108,23 +112,44 @@ def getExtensions(): if is_python_2: raise RuntimeError("Python prior to version 3 is not supported on Windows due to limits of VC++ compiler version") - libs = ['boost_system', 'boost_serialization'] + libs = []#['boost_system', 'boost_serialization'] if is_python_2: - libs += ['boost_python', "boost_numpy"] + libs += ['boost_python', "boost_numpy", "boost_system", + 'boost_filesystem', 'boost_serialization', 'boost_date_time', + 'boost_random'] else: - libs += ['boost_python3', "boost_numpy3"] # in Ubuntu 14 there is only 'boost_python-py34' - - # for Windows with mingw - # libraries= ['libboost_python-mgw48-mt-1_58', - # 'libboost_serialization-mgw48-mt-1_58'], - # include_dirs = ['C:/MinGW/include', 'C:/Users/Peter/Desktop/boost_1_58_0'], - # library_dirs = ['C:/MinGW/lib', 'C:/Users/Peter/Desktop/boost_1_58_0/stage/lib'], - extra.extend(['-DUSE_BOOST_PYTHON', '-DUSE_BOOST_RANDOM']) - extensionsList.append(Extension('MultiNEAT._MultiNEAT', - sources, - libraries=libs, - extra_compile_args=extra) - ) + # for Windows + if sys.platform == 'win32': + # when compiling with Visual Studio 2017 this are the libs you need (boost 1.71) + libs += ["boost_system-vc141-mt-x64-1_71", + "boost_filesystem-vc141-mt-x64-1_71", + "boost_wserialization-vc141-mt-x64-1_71", + "boost_date_time-vc141-mt-x64-1_71", + "boost_random-vc141-mt-x64-1_71", + "boost_python36-vc141-mt-x64-1_71", + "boost_numpy36-vc141-mt-x64-1_71", + "python3" + ] + else: + # with boost 1.67+ you need boost_python3x and boost_numpy3x where x is python version 3.x + libs += ['boost_python38', "boost_numpy38", "boost_system", + 'boost_filesystem', 'boost_serialization', 'boost_date_time', + 'boost_random'] # in Ubuntu 14 there is only 'boost_python-py34' + + #include_dirs = ['C:/MinGW/include'], + library_dirs = ['C:/MinGW/lib', 'C:/Boost/lib', 'C:/Python36/libs'] + extra.extend(['-DUSE_BOOST_PYTHON', '-DUSE_BOOST_RANDOM', '-DUSE_BOOST_NUMPY',# '-DMS_WIN64', '-DWIN64', '-DWIN_64' #'-O0', + #'-DVDEBUG', + ]) + exx = Extension('MultiNEAT._MultiNEAT', + sources, + libraries=libs, + library_dirs=library_dirs, + extra_compile_args=extra) + print(dir(exx)) + print(exx) + print(exx.extra_compile_args) + extensionsList.append(exx) else: raise AttributeError('Unknown tool: {}'.format(build_sys)) @@ -132,6 +157,6 @@ def getExtensions(): setup(name='multineat', - version='0.5', # Update version in conda/meta.yaml as well + version='0.6', # Update version in conda/meta.yaml as well packages=['MultiNEAT'], ext_modules=getExtensions()) diff --git a/src/Genes.h b/src/Genes.h index 67151c6f..8d76156a 100644 --- a/src/Genes.h +++ b/src/Genes.h @@ -87,7 +87,6 @@ namespace NEAT RELU, // Rectifiers SOFTPLUS - }; ////////////////////////////////// @@ -174,6 +173,33 @@ namespace NEAT py::object itp = bs::get(it->second.m_Details); t = itp(); // details is a function that returns a random instance of the trait } + + if (it->second.type == "pyclassset") + { + // this time m_Details is a (list, probs) tuple + // the list is a list of classes that get instantiated + py::object tup = bs::get(it->second.m_Details); + py::list classlist = py::extract(tup[0]); + py::list probs = py::extract(tup[1]); + std::vector dprobs; + + // get the probs + int ln = py::len(probs); + if ((ln == 0) || (py::len(classlist) == 0)) + { + throw std::runtime_error("Empty class or probs list"); + } + + for(int i=0; i(probs[i])); + } + + // instantiate random class + int idx = a_RNG.Roulette(dprobs); + py::object itp = py::extract(classlist[idx]); + t = itp(); + } #endif Trait tr; @@ -195,6 +221,7 @@ namespace NEAT if (!(mine.type() == yours.type())) { + //std::cout << "t1:" << mine << " t2:" << yours << "\n"; throw std::runtime_error("Types of traits doesn't match"); } @@ -208,7 +235,6 @@ namespace NEAT else #endif { - if (a_RNG.RandFloat() < 0.5) // pick either one { m_Traits[it->first].value = (a_RNG.RandFloat() < 0.5) ? mine : yours; @@ -259,9 +285,6 @@ namespace NEAT bool did_mutate = false; for(auto it = tp.begin(); it != tp.end(); it++) { - // Check what kind of type is this and modify it - TraitType t; - // only mutate the trait if it's enabled bool doit = false; if (it->second.dep_key != "") @@ -287,118 +310,129 @@ namespace NEAT if (doit) { - if (it->second.type == "int") + // Mutate? + if (a_RNG.RandFloat() < it->second.m_MutationProb) { - IntTraitParameters itp = bs::get(it->second.m_Details); - - // Mutate? - if (a_RNG.RandFloat() < it->second.m_MutationProb) + if (it->second.type == "int") { + IntTraitParameters itp = bs::get(it->second.m_Details); + // determine type of mutation - modify or replace, according to parameters if (a_RNG.RandFloat() < itp.mut_replace_prob) { // replace - int val = 0; - int cur = bs::get(m_Traits[it->first].value); - val = a_RNG.RandInt(itp.min, itp.max); + int val = bs::get(m_Traits[it->first].value); + int cur = val; + while (cur == val) + { + val = a_RNG.RandInt(itp.min, itp.max); + } m_Traits[it->first].value = val; - if (cur != val) - did_mutate = true; + did_mutate = true; } else { // modify int val = bs::get(m_Traits[it->first].value); int cur = val; - val += a_RNG.RandInt(-itp.mut_power, itp.mut_power); - Clamp(val, itp.min, itp.max); + while (cur == val) + { + val += a_RNG.RandInt(-itp.mut_power, itp.mut_power); + Clamp(val, itp.min, itp.max); + } m_Traits[it->first].value = val; - if (cur != val) - did_mutate = true; + did_mutate = true; } } - } - if (it->second.type == "float") - { - FloatTraitParameters itp = bs::get(it->second.m_Details); - - // Mutate? - if (a_RNG.RandFloat() < it->second.m_MutationProb) + else if (it->second.type == "float") { + FloatTraitParameters itp = bs::get(it->second.m_Details); + // determine type of mutation - modify or replace, according to parameters if (a_RNG.RandFloat() < itp.mut_replace_prob) { // replace - double val = 0; - double cur = bs::get(m_Traits[it->first].value); - val = a_RNG.RandFloat(); - Scale(val, 0, 1, itp.min, itp.max); + double val = bs::get(m_Traits[it->first].value); + double cur = val; + while (cur == val) + { + val = a_RNG.RandFloat(); + Scale(val, 0.0, 1.0, itp.min, itp.max); + } m_Traits[it->first].value = val; - if (cur != val) - did_mutate = true; + did_mutate = true; } else { // modify double val = bs::get(m_Traits[it->first].value); double cur = val; - val += a_RNG.RandFloatSigned() * itp.mut_power; - Clamp(val, itp.min, itp.max); + while (cur == val) + { + val += a_RNG.RandFloatSigned() * itp.mut_power; + Clamp(val, itp.min, itp.max); + } m_Traits[it->first].value = val; - if (cur != val) - did_mutate = true; + did_mutate = true; } + } - } - if (it->second.type == "str") - { - StringTraitParameters itp = bs::get(it->second.m_Details); - std::vector probs = itp.probs; - probs.resize(itp.set.size()); - - int idx = a_RNG.Roulette(probs); - std::string cur = bs::get(m_Traits[it->first].value); - - // now choose the new idx from the set - m_Traits[it->first].value = itp.set[idx]; - if (cur != itp.set[idx]) + else if (it->second.type == "str") + { + StringTraitParameters itp = bs::get(it->second.m_Details); + std::vector probs = itp.probs; + probs.resize(itp.set.size()); + std::string cur = bs::get(m_Traits[it->first].value); + int idx = a_RNG.Roulette(probs); + + while (cur == itp.set[idx]) + { + idx = a_RNG.Roulette(probs); + } + // now choose the new idx from the set + m_Traits[it->first].value = itp.set[idx]; did_mutate = true; - } - if (it->second.type == "intset") - { - IntSetTraitParameters itp = bs::get(it->second.m_Details); - std::vector probs = itp.probs; - probs.resize(itp.set.size()); - - int idx = a_RNG.Roulette(probs); - intsetelement cur = bs::get(m_Traits[it->first].value); - - // now choose the new idx from the set - m_Traits[it->first].value = itp.set[idx]; - if(cur.value != itp.set[idx].value) + } + else if (it->second.type == "intset") + { + IntSetTraitParameters itp = bs::get(it->second.m_Details); + std::vector probs = itp.probs; + probs.resize(itp.set.size()); + intsetelement cur = bs::get(m_Traits[it->first].value); + int idx = a_RNG.Roulette(probs); + + while (cur.value == itp.set[idx].value) + { + idx = a_RNG.Roulette(probs); + } + // now choose the new idx from the set + m_Traits[it->first].value = itp.set[idx]; did_mutate = true; - } - if (it->second.type == "floatset") - { - FloatSetTraitParameters itp = bs::get(it->second.m_Details); - std::vector probs = itp.probs; - probs.resize(itp.set.size()); - - int idx = a_RNG.Roulette(probs); - floatsetelement cur = bs::get(m_Traits[it->first].value); - - // now choose the new idx from the set - m_Traits[it->first].value = itp.set[idx]; - if(cur.value != itp.set[idx].value) + } + else if (it->second.type == "floatset") + { + FloatSetTraitParameters itp = bs::get(it->second.m_Details); + std::vector probs = itp.probs; + probs.resize(itp.set.size()); + floatsetelement cur = bs::get(m_Traits[it->first].value); + int idx = a_RNG.Roulette(probs); + + while (cur.value == itp.set[idx].value) + { + idx = a_RNG.Roulette(probs); + } + // now choose the new idx from the set + m_Traits[it->first].value = itp.set[idx]; did_mutate = true; - } + } #ifdef USE_BOOST_PYTHON - if (it->second.type == "pyobject") - { - m_Traits[it->first].value = bs::get(m_Traits[it->first].value).attr("mutate")(); - did_mutate = true; - } + else if ((it->second.type == "pyobject") || (it->second.type == "pyclassset")) + { + m_Traits[it->first].value = bs::get(m_Traits[it->first].value).attr("mutate")(); + did_mutate = true; + } #endif + } } } @@ -555,7 +589,11 @@ namespace NEAT //////////////// LinkGene() { - + m_FromNeuronID = 0; + m_ToNeuronID = 0; + m_InnovationID = 0; + m_Weight = 0; + m_IsRecurrent = false; } LinkGene(int a_InID, int a_OutID, int a_InnovID, double a_Wgt, bool a_Recurrent = false) @@ -740,13 +778,14 @@ namespace NEAT friend bool operator==(const NeuronGene &a_lhs, const NeuronGene &a_rhs) { return (a_lhs.m_ID == a_rhs.m_ID) && - (a_lhs.m_Type == a_rhs.m_Type) && - (a_lhs.m_SplitY == a_rhs.m_SplitY) && - (a_lhs.m_A == a_rhs.m_A) && - (a_lhs.m_B == a_rhs.m_B) && - (a_lhs.m_TimeConstant == a_rhs.m_TimeConstant) && - (a_lhs.m_Bias == a_rhs.m_Bias) && - (a_lhs.m_ActFunction == a_rhs.m_ActFunction); + (a_lhs.m_Type == a_rhs.m_Type) + //(a_lhs.m_SplitY == a_rhs.m_SplitY) && + //(a_lhs.m_A == a_rhs.m_A) && + //(a_lhs.m_B == a_rhs.m_B) && + //(a_lhs.m_TimeConstant == a_rhs.m_TimeConstant) && + //(a_lhs.m_Bias == a_rhs.m_Bias) && + //(a_lhs.m_ActFunction == a_rhs.m_ActFunction) + ; } NeuronGene(NeuronType a_type, int a_id, double a_splity) @@ -774,15 +813,19 @@ namespace NEAT m_ID = a_g.m_ID; m_Type = a_g.m_Type; m_SplitY = a_g.m_SplitY; - x = a_g.x; - y = a_g.y; - m_A = a_g.m_A; - m_B = a_g.m_B; - m_TimeConstant = a_g.m_TimeConstant; - m_Bias = a_g.m_Bias; - m_ActFunction = a_g.m_ActFunction; - - m_Traits = a_g.m_Traits; + + // maybe inputs don't need that + if ((m_Type != NeuronType::INPUT) && (m_Type != NeuronType::BIAS)) + { + x = a_g.x; + y = a_g.y; + m_A = a_g.m_A; + m_B = a_g.m_B; + m_TimeConstant = a_g.m_TimeConstant; + m_Bias = a_g.m_Bias; + m_ActFunction = a_g.m_ActFunction; + m_Traits = a_g.m_Traits; + } } return *this; diff --git a/src/Genome.cpp b/src/Genome.cpp index 389e4d63..d0d77eb5 100644 --- a/src/Genome.cpp +++ b/src/Genome.cpp @@ -1,4306 +1,4627 @@ -/////////////////////////////////////////////////////////////////////////////////////////// -// MultiNEAT - Python/C++ NeuroEvolution of Augmenting Topologies Library -// -// Copyright (C) 2012 Peter Chervenski -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see < http://www.gnu.org/licenses/ >. -// -// Contact info: -// -// Peter Chervenski < spookey@abv.bg > -// Shane Ryan < shane.mcdonald.ryan@gmail.com > -/////////////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// File: Genome.cpp -// Description: Implementation of the Genome class. -/////////////////////////////////////////////////////////////////////////////// - - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Genome.h" -#include "Random.h" -#include "Utils.h" -#include "Parameters.h" -#include "Assert.h" - -namespace NEAT -{ - - // forward - ActivationFunction GetRandomActivation( const Parameters &a_Parameters, RNG &a_RNG); - - // squared x - inline double sqr(double x) - { - return x * x; - } - - - // Create an empty genome - Genome::Genome() - { - m_ID = 0; - m_Fitness = 0; - m_Depth = 0; - m_LinkGenes.clear(); - m_NeuronGenes.clear(); - m_NumInputs = 0; - m_NumOutputs = 0; - m_AdjustedFitness = 0; - m_OffspringAmount = 0; - m_Evaluated = false; - m_PhenotypeBehavior = NULL; - m_initial_num_neurons = 0; - m_initial_num_links = 0; - } - - - // Copy constructor - Genome::Genome(const Genome &a_G) - { - m_ID = a_G.m_ID; - m_Depth = a_G.m_Depth; - m_NeuronGenes = a_G.m_NeuronGenes; - m_LinkGenes = a_G.m_LinkGenes; - m_GenomeGene = a_G.m_GenomeGene; - m_Fitness = a_G.m_Fitness; - m_NumInputs = a_G.m_NumInputs; - m_NumOutputs = a_G.m_NumOutputs; - m_AdjustedFitness = a_G.m_AdjustedFitness; - m_OffspringAmount = a_G.m_OffspringAmount; - m_Evaluated = a_G.m_Evaluated; - m_PhenotypeBehavior = a_G.m_PhenotypeBehavior; - m_initial_num_neurons = a_G.m_initial_num_neurons; - m_initial_num_links = a_G.m_initial_num_links; -#ifdef USE_BOOST_PYTHON - m_behavior = a_G.m_behavior; -#endif - } - - // assignment operator - Genome &Genome::operator=(const Genome &a_G) - { - // self assignment guard - if (this != &a_G) - { - m_ID = a_G.m_ID; - m_Depth = a_G.m_Depth; - m_NeuronGenes = a_G.m_NeuronGenes; - m_LinkGenes = a_G.m_LinkGenes; - m_GenomeGene = a_G.m_GenomeGene; - m_Fitness = a_G.m_Fitness; - m_AdjustedFitness = a_G.m_AdjustedFitness; - m_NumInputs = a_G.m_NumInputs; - m_NumOutputs = a_G.m_NumOutputs; - m_OffspringAmount = a_G.m_OffspringAmount; - m_Evaluated = a_G.m_Evaluated; - m_PhenotypeBehavior = a_G.m_PhenotypeBehavior; - m_initial_num_neurons = a_G.m_initial_num_neurons; - m_initial_num_links = a_G.m_initial_num_links; -#ifdef USE_BOOST_PYTHON - m_behavior = a_G.m_behavior; -#endif - } - - return *this; - } - - // New constructor that creates a fully-connected CTRNN - Genome::Genome(unsigned int a_ID, - unsigned int a_NumInputs, - unsigned int a_NumHidden, // ignored for seed type == 0, specifies number of hidden units if seed type == 1 - unsigned int a_NumOutputs, ActivationFunction a_OutputActType, - ActivationFunction a_HiddenActType, - const Parameters &a_Parameters) - { - ASSERT((a_NumInputs > 1) && (a_NumOutputs > 0)); - RNG t_RNG; - t_RNG.TimeSeed(); - - m_ID = a_ID; - int t_innovnum = 1, t_nnum = 1; - - if (a_Parameters.DontUseBiasNeuron == false) - { - - // Create the input neurons. - // Warning! The last one is a bias! - // The order of the neurons is very important. It is the following: INPUTS, BIAS, OUTPUTS, HIDDEN ... (no limit) - for (unsigned int i = 0; i < (a_NumInputs - 1); i++) - { - NeuronGene n = NeuronGene(INPUT, t_nnum, 0.0); - // Initialize the traits - n.InitTraits(a_Parameters.NeuronTraits, t_RNG); - m_NeuronGenes.push_back(n); - t_nnum++; - } - // add the bias - NeuronGene n = NeuronGene(BIAS, t_nnum, 0.0); - // Initialize the traits - n.InitTraits(a_Parameters.NeuronTraits, t_RNG); - - m_NeuronGenes.push_back(n); - t_nnum++; - } - else - { - // Create the input neurons without marking the last node as bias. - // The order of the neurons is very important. It is the following: INPUTS, OUTPUTS, HIDDEN ... (no limit) - for (unsigned int i = 0; i < a_NumInputs; i++) - { - NeuronGene n = NeuronGene(INPUT, t_nnum, 0.0); - // Initialize the traits - n.InitTraits(a_Parameters.NeuronTraits, t_RNG); - - m_NeuronGenes.push_back(n); - t_nnum++; - } - } - - // now the outputs - for (unsigned int i = 0; i < (a_NumOutputs); i++) - { - NeuronGene t_ngene(OUTPUT, t_nnum, 1.0); - // Initialize the neuron gene's properties - t_ngene.Init((a_Parameters.MinActivationA + a_Parameters.MaxActivationA) / 2.0f, - (a_Parameters.MinActivationB + a_Parameters.MaxActivationB) / 2.0f, - (a_Parameters.MinNeuronTimeConstant + a_Parameters.MaxNeuronTimeConstant) / 2.0f, - (a_Parameters.MinNeuronBias + a_Parameters.MaxNeuronBias) / 2.0f, - a_OutputActType); - // Initialize the traits - t_ngene.InitTraits(a_Parameters.NeuronTraits, t_RNG); - - m_NeuronGenes.push_back(t_ngene); - t_nnum++; - } - - for (unsigned int i = 0; i < a_NumHidden; i++) - { - NeuronGene t_ngene(HIDDEN, t_nnum, 1.0); - // Initialize the neuron gene's properties - t_ngene.Init((a_Parameters.MinActivationA + a_Parameters.MaxActivationA) / 2.0f, - (a_Parameters.MinActivationB + a_Parameters.MaxActivationB) / 2.0f, - (a_Parameters.MinNeuronTimeConstant + a_Parameters.MaxNeuronTimeConstant) / 2.0f, - (a_Parameters.MinNeuronBias + a_Parameters.MaxNeuronBias) / 2.0f, - a_HiddenActType); - // Initialize the traits - t_ngene.InitTraits(a_Parameters.NeuronTraits, t_RNG); - t_ngene.m_SplitY = 0.5; - - m_NeuronGenes.push_back(t_ngene); - t_nnum++; - } - - // Fully connect every neuron to every other. Only inputs don't receive output. - for (unsigned int i = a_NumInputs; i < (a_NumInputs+a_NumOutputs+a_NumHidden); i++) - { - for (unsigned int j = 0; j < (a_NumInputs+a_NumOutputs+a_NumHidden); j++) - { - // add the link - // created with zero weights. needs future random initialization. !!!!!!!! - LinkGene l = LinkGene(j + 1, i + 1, t_innovnum, 0.0, false); - l.InitTraits(a_Parameters.LinkTraits, t_RNG); - m_LinkGenes.push_back(l); - t_innovnum++; - } - } - - // Also initialize the Genome's traits - m_GenomeGene.InitTraits(a_Parameters.GenomeTraits, t_RNG); - - m_Evaluated = false; - m_NumInputs = a_NumInputs; - m_NumOutputs = a_NumOutputs; - m_Fitness = 0.0; - m_AdjustedFitness = 0.0; - m_OffspringAmount = 0.0; - m_Depth = 0; - m_PhenotypeBehavior = NULL; - - m_initial_num_neurons = NumNeurons(); - m_initial_num_links = NumLinks(); - } - - Genome::Genome(unsigned int a_ID, - unsigned int a_NumInputs, - unsigned int a_NumHidden, // ignored for seed type == 0, specifies number of hidden units if seed type == 1 - unsigned int a_NumOutputs, - bool a_FS_NEAT, ActivationFunction a_OutputActType, - ActivationFunction a_HiddenActType, - unsigned int a_SeedType, - const Parameters &a_Parameters, - unsigned int a_NumLayers = 1) // number of hidden layers. Each will have a_NumHidden nodes - { - ASSERT((a_NumInputs > 1) && (a_NumOutputs > 0)); - RNG t_RNG; - t_RNG.TimeSeed(); - - m_ID = a_ID; - int t_innovnum = 1, t_nnum = 1; - - // override seed_type if 0 hidden units are specified - if ((a_SeedType == 1) && (a_NumHidden == 0)) - { - a_SeedType = 0; - } - - if (a_Parameters.DontUseBiasNeuron == false) - { - - // Create the input neurons. - // Warning! The last one is a bias! - // The order of the neurons is very important. It is the following: INPUTS, BIAS, OUTPUTS, HIDDEN ... (no limit) - for (unsigned int i = 0; i < (a_NumInputs - 1); i++) - { - NeuronGene n = NeuronGene(INPUT, t_nnum, 0.0); - // Initialize the traits - n.InitTraits(a_Parameters.NeuronTraits, t_RNG); - m_NeuronGenes.push_back(n); - t_nnum++; - } - // add the bias - NeuronGene n = NeuronGene(BIAS, t_nnum, 0.0); - // Initialize the traits - n.InitTraits(a_Parameters.NeuronTraits, t_RNG); - - m_NeuronGenes.push_back(n); - t_nnum++; - } - else - { - // Create the input neurons without marking the last node as bias. - // The order of the neurons is very important. It is the following: INPUTS, OUTPUTS, HIDDEN ... (no limit) - for (unsigned int i = 0; i < a_NumInputs; i++) - { - NeuronGene n = NeuronGene(INPUT, t_nnum, 0.0); - // Initialize the traits - n.InitTraits(a_Parameters.NeuronTraits, t_RNG); - - m_NeuronGenes.push_back(n); - t_nnum++; - } - } - - // now the outputs - for (unsigned int i = 0; i < (a_NumOutputs); i++) - { - NeuronGene t_ngene(OUTPUT, t_nnum, 1.0); - // Initialize the neuron gene's properties - t_ngene.Init((a_Parameters.MinActivationA + a_Parameters.MaxActivationA) / 2.0f, - (a_Parameters.MinActivationB + a_Parameters.MaxActivationB) / 2.0f, - (a_Parameters.MinNeuronTimeConstant + a_Parameters.MaxNeuronTimeConstant) / 2.0f, - (a_Parameters.MinNeuronBias + a_Parameters.MaxNeuronBias) / 2.0f, - a_OutputActType); - // Initialize the traits - t_ngene.InitTraits(a_Parameters.NeuronTraits, t_RNG); - - m_NeuronGenes.push_back(t_ngene); - t_nnum++; - } - - // Now add LEO - if (a_Parameters.Leo) - { - NeuronGene t_ngene(OUTPUT, t_nnum, 1.0); - // Initialize the neuron gene's properties - t_ngene.Init((a_Parameters.MinActivationA + a_Parameters.MaxActivationA) / 2.0f, - (a_Parameters.MinActivationB + a_Parameters.MaxActivationB) / 2.0f, - (a_Parameters.MinNeuronTimeConstant + a_Parameters.MaxNeuronTimeConstant) / 2.0f, - (a_Parameters.MinNeuronBias + a_Parameters.MaxNeuronBias) / 2.0f, - UNSIGNED_STEP); - // Initialize the traits - t_ngene.InitTraits(a_Parameters.NeuronTraits, t_RNG); - - m_NeuronGenes.push_back(t_ngene); - t_nnum++; - a_NumOutputs++; - } - - // add and connect hidden neurons if seed type is != 0 - if ((a_SeedType != 0) && (a_NumHidden > 0)) - { - double lt_inc = 1.0 / (a_NumLayers+1); - double initlt = lt_inc; - for (unsigned int n = 0; n < a_NumLayers; n++) - { - for (unsigned int i = 0; i < a_NumHidden; i++) - { - NeuronGene t_ngene(HIDDEN, t_nnum, 1.0); - // Initialize the neuron gene's properties - t_ngene.Init((a_Parameters.MinActivationA + a_Parameters.MaxActivationA) / 2.0f, - (a_Parameters.MinActivationB + a_Parameters.MaxActivationB) / 2.0f, - (a_Parameters.MinNeuronTimeConstant + a_Parameters.MaxNeuronTimeConstant) / 2.0f, - (a_Parameters.MinNeuronBias + a_Parameters.MaxNeuronBias) / 2.0f, - a_HiddenActType); - // Initialize the traits - t_ngene.InitTraits(a_Parameters.NeuronTraits, t_RNG); - t_ngene.m_SplitY = initlt; - - m_NeuronGenes.push_back(t_ngene); - t_nnum++; - } - - initlt += lt_inc; - } - - if (!a_FS_NEAT) - { - int last_dest_id = a_NumInputs + a_NumOutputs + 1; - int last_src_id = 1; - int prev_layer_size = a_NumInputs; - - for (unsigned int n = 0; n < a_NumLayers; n++) - { - // The links from each previous layer to this hidden node - for (unsigned int i = 0; i < a_NumHidden; i++) - { - for (unsigned int j = 0; j < prev_layer_size; j++) - { - // add the link - // created with zero weights. needs future random initialization. !!!!!!!! - // init traits (TODO: maybe init empty traits?) - LinkGene l = LinkGene(j + last_src_id, i + last_dest_id, t_innovnum, 0.0, false); - l.InitTraits(a_Parameters.LinkTraits, t_RNG); - m_LinkGenes.push_back(l); - t_innovnum++; - } - } - - last_dest_id += a_NumHidden; - if (n == 0) - { - // for the first hidden layer, jump over the outputs too - last_src_id += prev_layer_size + a_NumOutputs; - } - else - { - last_src_id += prev_layer_size; - } - prev_layer_size = a_NumHidden; - } - - last_dest_id = a_NumInputs + 1; - - // The links from each previous layer to this output node - for (unsigned int i = 0; i < a_NumOutputs; i++) - { - for (unsigned int j = 0; j < prev_layer_size; j++) - { - // add the link - // created with zero weights. needs future random initialization. !!!!!!!! - // init traits (TODO: maybe init empty traits?) - LinkGene l = LinkGene(j + last_src_id, i + last_dest_id, t_innovnum, 0.0, false); - l.InitTraits(a_Parameters.LinkTraits, t_RNG); - m_LinkGenes.push_back(l); - t_innovnum++; - } - } - - /*if (a_Parameters.DontUseBiasNeuron == false) - { - // Connect the bias as well - for (unsigned int i = 0; i < a_NumOutputs; i++) - { - // add the link - // created with zero weights. needs future random initialization. !!!!!!!! - LinkGene l = LinkGene(a_NumInputs, i + last_dest_id, t_innovnum, 0.0, false); - l.InitTraits(a_Parameters.LinkTraits, t_RNG); - m_LinkGenes.push_back(l); - t_innovnum++; - } - }*/ - } - } - else // The links connecting every input to every output - perceptron structure - { - if ((!a_FS_NEAT) && (a_SeedType == 0)) - { - for (unsigned int i = 0; i < (a_NumOutputs); i++) - { - for (unsigned int j = 0; j < a_NumInputs; j++) - { - // add the link - // created with zero weights. needs future random initialization. !!!!!!!! - LinkGene l = LinkGene(j + 1, i + a_NumInputs + 1, t_innovnum, 0.0, false); - l.InitTraits(a_Parameters.LinkTraits, t_RNG); - m_LinkGenes.push_back(l); - t_innovnum++; - } - } - } - else - { - // Start very minimally - connect a random input to each output - // Also connect the bias to every output - for (unsigned int i = 0; i < a_NumOutputs; i++) - { - int t_inp_id = t_RNG.RandInt(1, a_NumInputs - 1); - int t_bias_id = a_NumInputs; - int t_outp_id = a_NumInputs + 1 + i; - - // created with zero weights. needs future random initialization. !!!!!!!! - LinkGene l = LinkGene(t_inp_id, t_outp_id, t_innovnum, 0.0, false); - l.InitTraits(a_Parameters.LinkTraits, t_RNG); - m_LinkGenes.push_back(l); - t_innovnum++; - - if (a_Parameters.DontUseBiasNeuron == false) - { - LinkGene bl = LinkGene(t_bias_id, t_outp_id, t_innovnum, 0.0, false); - bl.InitTraits(a_Parameters.LinkTraits, t_RNG); - m_LinkGenes.push_back(bl); - t_innovnum++; - } - } - } - } - - // Also initialize the Genome's traits - m_GenomeGene.InitTraits(a_Parameters.GenomeTraits, t_RNG); - - m_Evaluated = false; - m_NumInputs = a_NumInputs; - m_NumOutputs = a_NumOutputs; - m_Fitness = 0.0; - m_AdjustedFitness = 0.0; - m_OffspringAmount = 0.0; - m_Depth = 0; - m_PhenotypeBehavior = NULL; - - m_initial_num_neurons = NumNeurons(); - m_initial_num_links = NumLinks(); - } - - void Genome::SetDepth(unsigned int a_d) - { - m_Depth = a_d; - } - - unsigned int Genome::GetDepth() const - { - return m_Depth; - } - - void Genome::SetID(unsigned int a_id) - { - m_ID = a_id; - } - - unsigned int Genome::GetID() const - { - return m_ID; - } - - void Genome::SetAdjFitness(double a_af) - { - m_AdjustedFitness = a_af; - } - - void Genome::SetFitness(double a_f) - { - m_Fitness = a_f; - } - - double Genome::GetAdjFitness() const - { - return m_AdjustedFitness; - } - - double Genome::GetFitness() const - { - return m_Fitness; - } - - void Genome::SetNeuronY(unsigned int a_idx, int a_y) - { - ASSERT(a_idx < m_NeuronGenes.size()); - m_NeuronGenes[a_idx].y = a_y; - } - - void Genome::SetNeuronX(unsigned int a_idx, int a_x) - { - ASSERT(a_idx < m_NeuronGenes.size()); - m_NeuronGenes[a_idx].x = a_x; - } - - void Genome::SetNeuronXY(unsigned int a_idx, int a_x, int a_y) - { - ASSERT(a_idx < m_NeuronGenes.size()); - m_NeuronGenes[a_idx].x = a_x; - m_NeuronGenes[a_idx].y = a_y; - } - - LinkGene Genome::GetLinkByIndex(int a_idx) const - { - ASSERT(a_idx < m_LinkGenes.size()); - return m_LinkGenes[a_idx]; - } - - LinkGene Genome::GetLinkByInnovID(int a_ID) const - { - ASSERT(HasLinkByInnovID(a_ID)); - for (unsigned int i = 0; i < m_LinkGenes.size(); i++) - if (m_LinkGenes[i].InnovationID() == a_ID) - return m_LinkGenes[i]; - - // should never reach this code - throw std::exception(); - } - - NeuronGene Genome::GetNeuronByIndex(int a_idx) const - { - ASSERT(a_idx < m_NeuronGenes.size()); - return m_NeuronGenes[a_idx]; - } - - NeuronGene Genome::GetNeuronByID(int a_ID) const - { - ASSERT(HasNeuronID(a_ID)); - int t_idx = GetNeuronIndex(a_ID); - ASSERT(t_idx != -1); - return m_NeuronGenes[t_idx]; - } - - double Genome::GetOffspringAmount() const - { - return m_OffspringAmount; - } - - void Genome::SetOffspringAmount(double a_oa) - { - m_OffspringAmount = a_oa; - } - - bool Genome::IsEvaluated() const - { - return m_Evaluated; - } - - void Genome::SetEvaluated() - { - m_Evaluated = true; - } - - void Genome::ResetEvaluated() - { - m_Evaluated = false; - } - - // A little helper function to find the index of a neuron, given its ID - // returns -1 if not found - int Genome::GetNeuronIndex(int a_ID) const - { - ASSERT(a_ID > 0); - - for (unsigned int i = 0; i < NumNeurons(); i++) - { - if (m_NeuronGenes[i].ID() == a_ID) - { - return i; - } - } - - return -1; - } - - // A little helper function to find the index of a link, given its innovation ID - // returns -1 if not found - int Genome::GetLinkIndex(int a_InnovID) const - { - ASSERT(a_InnovID > 0); - ASSERT(NumLinks() > 0); - - for (unsigned int i = 0; i < NumLinks(); i++) - { - if (m_LinkGenes[i].InnovationID() == a_InnovID) - { - return i; - } - } - - return -1; - } - - - // returns the max neuron ID - int Genome::GetLastNeuronID() const - { - ASSERT(NumNeurons() > 0); - - int t_maxid = 0; - - for (unsigned int i = 0; i < NumNeurons(); i++) - { - if (m_NeuronGenes[i].ID() > t_maxid) - t_maxid = m_NeuronGenes[i].ID(); - } - - return t_maxid + 1; - } - - // returns the max innovation Id - int Genome::GetLastInnovationID() const - { - ASSERT(NumLinks() > 0); - - int t_maxid = 0; - - for (unsigned int i = 0; i < NumLinks(); i++) - { - if (m_LinkGenes[i].InnovationID() > t_maxid) - t_maxid = m_LinkGenes[i].InnovationID(); - } - - return t_maxid + 1; - } - - // Returns true if the specified neuron ID is present in the genome - bool Genome::HasNeuronID(int a_ID) const - { - ASSERT(a_ID > 0); - ASSERT(NumNeurons() > 0); - - for (unsigned int i = 0; i < NumNeurons(); i++) - { - if (m_NeuronGenes[i].ID() == a_ID) - { - return true; - } - } - - return false; - } - - - // Returns true if the specified link is present in the genome - bool Genome::HasLink(int a_n1id, int a_n2id) const - { - ASSERT((a_n1id > 0) && (a_n2id > 0)); - - for (unsigned int i = 0; i < NumLinks(); i++) - { - if ((m_LinkGenes[i].FromNeuronID() == a_n1id) && (m_LinkGenes[i].ToNeuronID() == a_n2id)) - { - return true; - } - } - - return false; - } - - bool Genome::HasLoops() - { - NeuralNetwork net; - BuildPhenotype(net); - bool has_cycles = false; - - // convert the net to a Boost::Graph object - Graph g; - for (int i = 0; i < net.m_connections.size(); i++) - { - bs::add_edge(net.m_connections[i].m_source_neuron_idx, net.m_connections[i].m_target_neuron_idx, g); - } - - typedef std::vector container; - container c; - try - { - bs::topological_sort(g, std::back_inserter(c)); - } - catch (bs::not_a_dag) - { - has_cycles = true; - } - - return has_cycles; - } - - // Returns true if the specified link is present in the genome - bool Genome::HasLinkByInnovID(int id) const - { - ASSERT(id > 0); - - for (unsigned int i = 0; i < NumLinks(); i++) - { - if (m_LinkGenes[i].InnovationID() == id) - { - return true; - } - } - - return false; - } - - - // This builds a fastnetwork structure out from the genome - void Genome::BuildPhenotype(NeuralNetwork &a_Net) - { - // first clear out the network - a_Net.Clear(); - a_Net.SetInputOutputDimentions(m_NumInputs, m_NumOutputs); - - // Fill the net with the neurons - for (unsigned int i = 0; i < NumNeurons(); i++) - { - Neuron t_n; - - t_n.m_a = m_NeuronGenes[i].m_A; - t_n.m_b = m_NeuronGenes[i].m_B; - t_n.m_timeconst = m_NeuronGenes[i].m_TimeConstant; - t_n.m_bias = m_NeuronGenes[i].m_Bias; - t_n.m_activation_function_type = m_NeuronGenes[i].m_ActFunction; - t_n.m_split_y = m_NeuronGenes[i].SplitY(); - t_n.m_type = m_NeuronGenes[i].Type(); - - a_Net.AddNeuron(t_n); - } - - // Fill the net with the connections - for (unsigned int i = 0; i < NumLinks(); i++) - { - Connection t_c; - - t_c.m_source_neuron_idx = GetNeuronIndex(m_LinkGenes[i].FromNeuronID()); - t_c.m_target_neuron_idx = GetNeuronIndex(m_LinkGenes[i].ToNeuronID()); - t_c.m_weight = m_LinkGenes[i].GetWeight(); - t_c.m_recur_flag = m_LinkGenes[i].IsRecurrent(); - - ////////////////////// - // default values - t_c.m_hebb_rate = 0.3; - t_c.m_hebb_pre_rate = 0.1; - - // if a float trait "hebb_rate" exists - if (m_LinkGenes[i].m_Traits.count("hebb_rate") == 1) - { - try - { - t_c.m_hebb_rate = boost::get(m_LinkGenes[i].m_Traits["hebb_rate"].value); - } - catch(std::exception e) - { - // do nothing - } - } - // if a float trait "hebb_pre_rate" exists - if (m_LinkGenes[i].m_Traits.count("hebb_pre_rate") == 1) - { - try - { - t_c.m_hebb_pre_rate = boost::get(m_LinkGenes[i].m_Traits["hebb_pre_rate"].value); - } - catch(std::exception e) - { - // do nothing - } - } - - ////////////////////// - - a_Net.AddConnection(t_c); - } - - a_Net.Flush(); - - // Note however that the RTRL variables are not initialized. - // The user must manually call the InitRTRLMatrix() method to do it. - // This is because of storage issues. RTRL need not to be used every time. - } - - - // Builds a HyperNEAT phenotype based on the substrate - // The CPPN input dimensionality must match the largest number of - // dimensions in the substrate - // The output dimensionality is determined according to flags set in the - // substrate - - // The procedure uses the [0] CPPN output for creating nodes, and if the substrate is leaky, [1] and [2] for time constants and biases - // Also assumes the CPPN uses signed activation outputs - void Genome::BuildHyperNEATPhenotype(NeuralNetwork &net, Substrate &subst) - { - // We need a substrate with at least one input and output - ASSERT(subst.m_input_coords.size() > 0); - ASSERT(subst.m_output_coords.size() > 0); - - int max_dims = subst.GetMaxDims(); - - // Make sure the CPPN dimensionality is right - ASSERT(subst.GetMinCPPNInputs() > 0); - ASSERT(NumInputs() >= subst.GetMinCPPNInputs()); - ASSERT(NumOutputs() >= subst.GetMinCPPNOutputs()); - if (subst.m_leaky) - { - ASSERT(NumOutputs() >= subst.GetMinCPPNOutputs()); - } - - // Now we create the substrate (net) - net.SetInputOutputDimentions(static_cast(subst.m_input_coords.size()), - static_cast(subst.m_output_coords.size())); - - // Inputs - for (unsigned int i = 0; i < subst.m_input_coords.size(); i++) - { - Neuron t_n; - - t_n.m_a = 1; - t_n.m_b = 0; - t_n.m_substrate_coords = subst.m_input_coords[i]; - ASSERT(t_n.m_substrate_coords.size() > 0); // prevent 0D points - t_n.m_activation_function_type = NEAT::LINEAR; - t_n.m_type = NEAT::INPUT; - - net.AddNeuron(t_n); - } - - // Output - for (unsigned int i = 0; i < subst.m_output_coords.size(); i++) - { - Neuron t_n; - - t_n.m_a = 1; - t_n.m_b = 0; - t_n.m_substrate_coords = subst.m_output_coords[i]; - ASSERT(t_n.m_substrate_coords.size() > 0); // prevent 0D points - t_n.m_activation_function_type = subst.m_output_nodes_activation; - t_n.m_type = NEAT::OUTPUT; - - net.AddNeuron(t_n); - } - - // Hidden - for (unsigned int i = 0; i < subst.m_hidden_coords.size(); i++) - { - Neuron t_n; - - t_n.m_a = 1; - t_n.m_b = 0; - t_n.m_substrate_coords = subst.m_hidden_coords[i]; - ASSERT(t_n.m_substrate_coords.size() > 0); // prevent 0D points - t_n.m_activation_function_type = subst.m_hidden_nodes_activation; - t_n.m_type = NEAT::HIDDEN; - - net.AddNeuron(t_n); - } - - // Begin querying the CPPN - // Create the neural network that will represent the CPPN - NeuralNetwork t_temp_phenotype(true); - BuildPhenotype(t_temp_phenotype); - t_temp_phenotype.Flush(); - - // To ensure network relaxation - int dp = 8; - if (!HasLoops()) - { - CalculateDepth(); - dp = GetDepth(); - } - - // now loop over every potential connection in the substrate and take its weight - - // For leaky substrates, first loop over the neurons and set their properties - if (subst.m_leaky) - { - for (unsigned int i = net.NumInputs(); i < net.m_neurons.size(); i++) - { - // neuron specific stuff - t_temp_phenotype.Flush(); - - // Inputs for the generation of time consts and biases across - // the nodes in the substrate - // We input only the position of the first node and ignore the other one - std::vector t_inputs; - t_inputs.resize(NumInputs()); - - for (unsigned int n = 0; n < net.m_neurons[i].m_substrate_coords.size(); n++) - { - t_inputs[n] = net.m_neurons[i].m_substrate_coords[n]; - } - - if (subst.m_with_distance) - { - // compute the Eucledian distance between the point and the origin - double sum = 0; - for (int n = 0; n < max_dims; n++) - { - sum += sqr(t_inputs[n]); - } - sum = sqrt(sum); - t_inputs[NumInputs() - 2] = sum; - } - t_inputs[NumInputs() - 1] = 1.0; // the CPPN's bias - - t_temp_phenotype.Input(t_inputs); - - // activate as many times as deep - for (int d = 0; d < dp; d++) - { - t_temp_phenotype.Activate(); - } - - double t_tc = t_temp_phenotype.Output()[NumOutputs() - 2]; - double t_bias = t_temp_phenotype.Output()[NumOutputs() - 1]; - - Clamp(t_tc, -1, 1); - Clamp(t_bias, -1, 1); - - // rescale the values - Scale(t_tc, -1, 1, subst.m_min_time_const, subst.m_max_time_const); - Scale(t_bias, -1, 1, -subst.m_max_weight_and_bias, subst.m_max_weight_and_bias); - - net.m_neurons[i].m_timeconst = t_tc; - net.m_neurons[i].m_bias = t_bias; - } - } - - // list of src_idx, dst_idx pairs of all connections to query - std::vector > t_to_query; - - // There isn't custom connectiviy scheme? - if (subst.m_custom_connectivity.size() == 0) - { - // only incoming connections, so loop only the hidden and output neurons - for (int i = net.NumInputs(); i < net.m_neurons.size(); i++) - { - // loop all neurons - for (int j = 0; j < net.m_neurons.size(); j++) - { - // this is connection "j" to "i" - - // conditions for canceling the CPPN query - if ( - ((!subst.m_allow_input_hidden_links) && - ((net.m_neurons[j].m_type == INPUT) && (net.m_neurons[i].m_type == HIDDEN))) - - || ((!subst.m_allow_input_output_links) && - ((net.m_neurons[j].m_type == INPUT) && (net.m_neurons[i].m_type == OUTPUT))) - - || ((!subst.m_allow_hidden_hidden_links) && - ((net.m_neurons[j].m_type == HIDDEN) && (net.m_neurons[i].m_type == HIDDEN) && - (i != j))) - - || ((!subst.m_allow_hidden_output_links) && - ((net.m_neurons[j].m_type == HIDDEN) && (net.m_neurons[i].m_type == OUTPUT))) - - || ((!subst.m_allow_output_hidden_links) && - ((net.m_neurons[j].m_type == OUTPUT) && (net.m_neurons[i].m_type == HIDDEN))) - - || ((!subst.m_allow_output_output_links) && - ((net.m_neurons[j].m_type == OUTPUT) && (net.m_neurons[i].m_type == OUTPUT) && - (i != j))) - - || ((!subst.m_allow_looped_hidden_links) && - ((net.m_neurons[j].m_type == HIDDEN) && (net.m_neurons[i].m_type == HIDDEN) && - (i == j))) - - || ((!subst.m_allow_looped_output_links) && - ((net.m_neurons[j].m_type == OUTPUT) && (net.m_neurons[i].m_type == OUTPUT) && - (i == j))) - - ) - { - continue; - } - - // Save potential link to query - std::vector t_link; - t_link.push_back(j); - t_link.push_back(i); - t_to_query.push_back(t_link); - } - } - } - else - { - // use the custom connectivity - for (unsigned int idx = 0; idx < subst.m_custom_connectivity.size(); idx++) - { - NeuronType src_type = (NeuronType) subst.m_custom_connectivity[idx][0]; - int src_idx = subst.m_custom_connectivity[idx][1]; - NeuronType dst_type = (NeuronType) subst.m_custom_connectivity[idx][2]; - int dst_idx = subst.m_custom_connectivity[idx][3]; - - // determine the indices in the NN - int j = 0; // src - int i = 0; // dst - - if ((src_type == INPUT) || (src_type == BIAS)) - { - j = src_idx; - } - else if (src_type == HIDDEN) - { - j = subst.m_input_coords.size() + subst.m_output_coords.size() + src_idx; - } - else if (src_type == OUTPUT) - { - j = subst.m_input_coords.size() + src_idx; - } - - - if ((dst_type == INPUT) || (dst_type == BIAS)) - { - i = dst_idx; - } - else if (dst_type == HIDDEN) - { - i = subst.m_input_coords.size() + subst.m_output_coords.size() + dst_idx; - } - else if (dst_type == OUTPUT) - { - i = subst.m_input_coords.size() + dst_idx; - } - - // conditions for canceling the CPPN query - if (subst.m_custom_conn_obeys_flags && ( - ((!subst.m_allow_input_hidden_links) && - ((net.m_neurons[j].m_type == INPUT) && (net.m_neurons[i].m_type == HIDDEN))) - - || ((!subst.m_allow_input_output_links) && - ((net.m_neurons[j].m_type == INPUT) && (net.m_neurons[i].m_type == OUTPUT))) - - || ((!subst.m_allow_hidden_hidden_links) && - ((net.m_neurons[j].m_type == HIDDEN) && (net.m_neurons[i].m_type == HIDDEN) && (i != j))) - - || ((!subst.m_allow_hidden_output_links) && - ((net.m_neurons[j].m_type == HIDDEN) && (net.m_neurons[i].m_type == OUTPUT))) - - || ((!subst.m_allow_output_hidden_links) && - ((net.m_neurons[j].m_type == OUTPUT) && (net.m_neurons[i].m_type == HIDDEN))) - - || ((!subst.m_allow_output_output_links) && - ((net.m_neurons[j].m_type == OUTPUT) && (net.m_neurons[i].m_type == OUTPUT) && (i != j))) - - || ((!subst.m_allow_looped_hidden_links) && - ((net.m_neurons[j].m_type == HIDDEN) && (net.m_neurons[i].m_type == HIDDEN) && (i == j))) - - || ((!subst.m_allow_looped_output_links) && - ((net.m_neurons[j].m_type == OUTPUT) && (net.m_neurons[i].m_type == OUTPUT) && (i == j))) - ) - ) - { - continue; - } - - // Save potential link to query - std::vector t_link; - t_link.push_back(j); - t_link.push_back(i); - t_to_query.push_back(t_link); - } - } - - - // Query and create all links - for (unsigned int conn = 0; conn < t_to_query.size(); conn++) - { - int j = t_to_query[conn][0]; - int i = t_to_query[conn][1]; - - // Take the weight of this connection by querying the CPPN - // as many times as deep (recurrent or looped CPPNs may be very slow!!!*) - std::vector t_inputs; - t_inputs.resize(NumInputs()); - - int from_dims = net.m_neurons[j].m_substrate_coords.size(); - int to_dims = net.m_neurons[i].m_substrate_coords.size(); - - // input the node positions to the CPPN - // from - for (int n = 0; n < from_dims; n++) - { - t_inputs[n] = net.m_neurons[j].m_substrate_coords[n]; - } - // to - for (int n = 0; n < to_dims; n++) - { - t_inputs[max_dims + n] = net.m_neurons[i].m_substrate_coords[n]; - } - - // the input is like - // x000|xx00|1 - 1D -> 2D connection - // xx00|xx00|1 - 2D -> 2D connection - // xx00|xxx0|1 - 2D -> 3D connection - // if max_dims is 4 and no distance input - - if (subst.m_with_distance) - { - // compute the Eucledian distance between the two points - // differing dimensionality doesn't matter as the extra dimensions are 0s - double sum = 0; - for (int n = 0; n < max_dims; n++) - { - sum += sqr(t_inputs[n] - t_inputs[max_dims + n]); - } - sum = sqrt(sum); - - t_inputs[NumInputs() - 2] = sum; - } - - t_inputs[NumInputs() - 1] = 1.0; - - - // flush between each query - t_temp_phenotype.Flush(); - t_temp_phenotype.Input(t_inputs); - - // activate as many times as deep - for (int d = 0; d < dp; d++) - { - t_temp_phenotype.Activate(); - } - - // the output is a weight - double t_link = 0; - double t_weight = 0; - - if (subst.m_query_weights_only) - { - t_weight = t_temp_phenotype.Output()[0]; - } - else - { - t_link = t_temp_phenotype.Output()[0]; - t_weight = t_temp_phenotype.Output()[1]; - } - - if (((t_link > 0) && (!subst.m_query_weights_only)) || (subst.m_query_weights_only)) - { - // now this weight will be scaled - t_weight *= subst.m_max_weight_and_bias; - - // build the connection - Connection t_c; - - t_c.m_source_neuron_idx = j; - t_c.m_target_neuron_idx = i; - t_c.m_weight = t_weight; - t_c.m_recur_flag = false; - - net.AddConnection(t_c); - } - } - } - - - // Projects the weight changes of a phenotype back to the genome. - // WARNING! Using this too often in conjuction with RTRL can confuse evolution. - void Genome::DerivePhenotypicChanges(NeuralNetwork &a_Net) - { - // the a_Net and the genome must have identical topology. - // if the topology differs, no changes will be made to the genome - - // Since we don't have a comparison operator yet, we are going to assume - // identical topolgy - // TODO: create that comparison operator for NeuralNetworks - - // Iterate through the links and replace weights - for (unsigned int i = 0; i < NumLinks(); i++) - { - m_LinkGenes[i].SetWeight(a_Net.GetConnectionByIndex(i).m_weight); - } - - // TODO: if neuron parameters were changed, derive them - // * in future expansions - } - - - // Returns the absolute distance between this genome and a_G - double Genome::CompatibilityDistance(Genome &a_G, Parameters &a_Parameters) - { - // iterators for moving through the genomes' genes - std::vector::iterator t_g1; - std::vector::iterator t_g2; - - // this variable is the total distance between the genomes - // if it passes beyond the compatibility treshold, the function returns false - double t_total_distance = 0.0; - - double t_total_weight_difference = 0.0; - double t_total_timeconstant_difference = 0.0; - double t_total_bias_difference = 0.0; - double t_total_A_difference = 0.0; - double t_total_B_difference = 0.0; - double t_total_num_activation_difference = 0.0; - std::map t_total_neuron_trait_difference; - std::map t_total_link_trait_difference; - std::map t_genome_link_trait_difference; - - // count of matching genes - double t_num_excess = 0; - double t_num_disjoint = 0; - double t_num_matching_links = 0; - double t_num_matching_neurons = 0; - - // calculate genome trait difference here - t_genome_link_trait_difference = m_GenomeGene.GetTraitDistances(a_G.m_GenomeGene.m_Traits); - - // used for percentage of excess/disjoint genes calculation - int t_max_genome_size = static_cast (NumLinks() < a_G.NumLinks()) ? (a_G.NumLinks()) : (NumLinks()); - int t_max_neurons = static_cast (NumNeurons() < a_G.NumNeurons()) ? (a_G.NumNeurons()) : (NumNeurons()); - - t_g1 = m_LinkGenes.begin(); - t_g2 = a_G.m_LinkGenes.begin(); - - // Step through the genes until both genomes end - while (!((t_g1 == m_LinkGenes.end()) && ((t_g2 == a_G.m_LinkGenes.end())))) - { - // end of first genome? - if (t_g1 == m_LinkGenes.end()) - { - // add to the total distance - t_num_excess++; - t_g2++; - } - else if (t_g2 == a_G.m_LinkGenes.end()) - // end of second genome? - { - // add to the total distance - t_num_excess++; - t_g1++; - } - else - { - // extract the innovation numbers - int t_g1innov = t_g1->InnovationID(); - int t_g2innov = t_g2->InnovationID(); - - // matching genes? - if (t_g1innov == t_g2innov) - { - t_num_matching_links++; - - double t_wdiff = (t_g1->GetWeight() - t_g2->GetWeight()); - if (t_wdiff < 0) t_wdiff = -t_wdiff; // make sure it is positive - t_total_weight_difference += t_wdiff; - - // calculate link trait difference here - std::map link_trait_difference = t_g1->GetTraitDistances(t_g2->m_Traits); - // add to the totals - for(auto it = link_trait_difference.begin(); it != link_trait_difference.end(); it++) - { - if (t_total_link_trait_difference.count(it->first) == 0) - { - t_total_link_trait_difference[it->first] = it->second; - } - else - { - t_total_link_trait_difference[it->first] += it->second; - } - } - - t_g1++; - t_g2++; - } - else if (t_g1innov < t_g2innov) // disjoint - { - t_num_disjoint++; - t_g1++; - } - else if (t_g1innov > t_g2innov) // disjoint - { - t_num_disjoint++; - t_g2++; - } - } - } - - // find matching neuron IDs - for (unsigned int i = 0; i < NumNeurons(); i++) - { - // no inputs considered for comparison - if ((m_NeuronGenes[i].Type() != INPUT) && (m_NeuronGenes[i].Type() != BIAS)) - { - // a match - if (a_G.HasNeuronID(m_NeuronGenes[i].ID())) - { - t_num_matching_neurons++; - - double t_A_difference = m_NeuronGenes[i].m_A - a_G.GetNeuronByID(m_NeuronGenes[i].ID()).m_A; - if (t_A_difference < 0.0f) t_A_difference = -t_A_difference; - t_total_A_difference += t_A_difference; - - double t_B_difference = m_NeuronGenes[i].m_B - a_G.GetNeuronByID(m_NeuronGenes[i].ID()).m_B; - if (t_B_difference < 0.0f) t_B_difference = -t_B_difference; - t_total_B_difference += t_B_difference; - - double t_time_constant_difference = - m_NeuronGenes[i].m_TimeConstant - a_G.GetNeuronByID(m_NeuronGenes[i].ID()).m_TimeConstant; - if (t_time_constant_difference < 0.0f) t_time_constant_difference = -t_time_constant_difference; - t_total_timeconstant_difference += t_time_constant_difference; - - double t_bias_difference = - m_NeuronGenes[i].m_Bias - a_G.GetNeuronByID(m_NeuronGenes[i].ID()).m_Bias; - if (t_bias_difference < 0.0f) t_bias_difference = -t_bias_difference; - t_total_bias_difference += t_bias_difference; - - // Activation function type difference is found - if (m_NeuronGenes[i].m_ActFunction != a_G.GetNeuronByID(m_NeuronGenes[i].ID()).m_ActFunction) - { - t_total_num_activation_difference++; - } - - // calculate and add node trait difference here - std::map neuron_trait_difference = m_NeuronGenes[i].GetTraitDistances( a_G.GetNeuronByID(m_NeuronGenes[i].ID()).m_Traits ); - // add to the totals - for(auto it = neuron_trait_difference.begin(); it != neuron_trait_difference.end(); it++) - { - if (t_total_neuron_trait_difference.count(it->first) == 0) - { - t_total_neuron_trait_difference[it->first] = it->second; - } - else - { - t_total_neuron_trait_difference[it->first] += it->second; - } - } - } - } - } - - // choose between normalizing for genome size or not - double t_normalizer = 1.0; - if (a_Parameters.NormalizeGenomeSize) - { - t_normalizer = static_cast(t_max_genome_size); - } - - // if there are no matching links, make it 1.0 to avoid divide error - if (t_num_matching_links <= 0) - t_num_matching_links = 1; - - // if there are no matching neurons, make it 1.0 to avoid divide error - if (t_num_matching_neurons <= 0) - t_num_matching_neurons = 1; - - if (t_normalizer <= 0.0) - t_normalizer = 1.0; - - t_total_distance = - (a_Parameters.ExcessCoeff * (t_num_excess / t_normalizer)) + - (a_Parameters.DisjointCoeff * (t_num_disjoint / t_normalizer)) + - (a_Parameters.WeightDiffCoeff * (t_total_weight_difference / t_num_matching_links)) + - (a_Parameters.ActivationADiffCoeff * (t_total_A_difference / t_num_matching_neurons)) + - (a_Parameters.ActivationBDiffCoeff * (t_total_B_difference / t_num_matching_neurons)) + - (a_Parameters.TimeConstantDiffCoeff * (t_total_timeconstant_difference / t_num_matching_neurons)) + - (a_Parameters.BiasDiffCoeff * (t_total_bias_difference / t_num_matching_neurons)) + - (a_Parameters.ActivationFunctionDiffCoeff * (t_total_num_activation_difference / t_num_matching_neurons)); - - // add trait differences according to each one's coeff - for(auto it = t_total_link_trait_difference.begin(); it != t_total_link_trait_difference.end(); it++) - { - t_total_distance += (a_Parameters.LinkTraits[it->first].m_ImportanceCoeff * it->second) / t_num_matching_links; - } - for(auto it = t_total_neuron_trait_difference.begin(); it != t_total_neuron_trait_difference.end(); it++) - { - t_total_distance += (a_Parameters.NeuronTraits[it->first].m_ImportanceCoeff * it->second) / t_num_matching_neurons; - } - for(auto it = t_genome_link_trait_difference.begin(); it != t_genome_link_trait_difference.end(); it++) - { - t_total_distance += (a_Parameters.GenomeTraits[it->first].m_ImportanceCoeff * it->second); - } - - return t_total_distance; - } - - // Returns true if this genome and a_G are compatible (belong in the same species) - bool Genome::IsCompatibleWith(Genome &a_G, Parameters &a_Parameters) - { - // full compatibility cases - if (this == &a_G) - return true; - - if (GetID() == a_G.GetID()) - return true; - - if ((NumLinks() == 0) && (a_G.NumLinks() == 0)) - return true; - - double t_total_distance = CompatibilityDistance(a_G, a_Parameters); - - if (t_total_distance <= a_Parameters.CompatTreshold) - return true; // compatible - else - return false; // incompatible - } - - - // Returns a random activation function from the canonical set based ot probabilities - ActivationFunction GetRandomActivation(const Parameters &a_Parameters, RNG &a_RNG) - { - std::vector t_probs; - - t_probs.push_back(a_Parameters.ActivationFunction_SignedSigmoid_Prob); - t_probs.push_back(a_Parameters.ActivationFunction_UnsignedSigmoid_Prob); - t_probs.push_back(a_Parameters.ActivationFunction_Tanh_Prob); - t_probs.push_back(a_Parameters.ActivationFunction_TanhCubic_Prob); - t_probs.push_back(a_Parameters.ActivationFunction_SignedStep_Prob); - t_probs.push_back(a_Parameters.ActivationFunction_UnsignedStep_Prob); - t_probs.push_back(a_Parameters.ActivationFunction_SignedGauss_Prob); - t_probs.push_back(a_Parameters.ActivationFunction_UnsignedGauss_Prob); - t_probs.push_back(a_Parameters.ActivationFunction_Abs_Prob); - t_probs.push_back(a_Parameters.ActivationFunction_SignedSine_Prob); - t_probs.push_back(a_Parameters.ActivationFunction_UnsignedSine_Prob); - t_probs.push_back(a_Parameters.ActivationFunction_Linear_Prob); - t_probs.push_back(a_Parameters.ActivationFunction_Relu_Prob); - t_probs.push_back(a_Parameters.ActivationFunction_Softplus_Prob); - - return (NEAT::ActivationFunction) a_RNG.Roulette(t_probs); - } - - - // Adds a new neuron to the genome - // returns true if succesful - bool Genome::Mutate_AddNeuron(InnovationDatabase &a_Innovs, const Parameters &a_Parameters, RNG &a_RNG) - { - // No links to split - go away.. - if (NumLinks() == 0) - return false; - - // First find a link that to be split - //////////////////// - - // Select a random link for now - bool t_link_found = false; - int t_link_num = 0; - int t_in = 0, t_out = 0; - LinkGene t_chosenlink(0, 0, -1, 0, false); // to save it for later - - // number of tries to find a good link or give up - int t_tries = 64; - while (!t_link_found) - { - if (NumLinks() == 1) - { - t_link_num = 0; - } - /*else if (NumLinks() == 2) - { - t_link_num = Rounded(a_RNG.RandFloat()); - }*/ - else - { - //if (NumLinks() > 8) - { - t_link_num = a_RNG.RandInt(0, NumLinks() - 1); // random selection - } - /*else - { - // this selects older links for splitting - double t_r = abs(RandGaussSigned()/3.0); - Clamp(t_r, 0, 1); - t_link_num = static_cast(t_r * (NumLinks()-1)); - }*/ - } - - - t_in = m_LinkGenes[t_link_num].FromNeuronID(); - t_out = m_LinkGenes[t_link_num].ToNeuronID(); - - ASSERT((t_in > 0) && (t_out > 0)); - - t_link_found = true; - - // In case there is only one link, coming from a bias - just quit - - // unless the parameter is set - if (a_Parameters.DontUseBiasNeuron == false) - { - if ((m_NeuronGenes[GetNeuronIndex(t_in)].Type() == BIAS) && (NumLinks() == 1)) - { - return false; - } - - // Do not allow splitting a link coming from a bias - if (m_NeuronGenes[GetNeuronIndex(t_in)].Type() == BIAS) - t_link_found = false; - } - - // Do not allow splitting of recurrent links - if (!a_Parameters.SplitRecurrent) - { - if (m_LinkGenes[t_link_num].IsRecurrent()) - { - if ((!a_Parameters.SplitLoopedRecurrent) && (t_in == t_out)) - { - t_link_found = false; - } - } - } - - t_tries--; - if (t_tries <= 0) - { - return false; - } - } - // Now the link has been selected - - // the weight of the link that is being split - double t_orig_weight = m_LinkGenes[t_link_num].GetWeight(); - t_chosenlink = m_LinkGenes[t_link_num]; // save the whole link - - // remove the link from the genome - // find it first and then erase it - // TODO: add option to keep the link, but disabled - std::vector::iterator t_iter; - for (t_iter = m_LinkGenes.begin(); t_iter != m_LinkGenes.end(); t_iter++) - { - if (t_iter->InnovationID() == m_LinkGenes[t_link_num].InnovationID()) - { - // found it! now erase.. - m_LinkGenes.erase(t_iter); - break; - } - } - - // Check if an innovation of this type already occured somewhere in the population - int t_innovid = a_Innovs.CheckInnovation(t_in, t_out, NEW_NEURON); - - // the new neuron and links ids - int t_nid = 0; - int t_l1id = 0; - int t_l2id = 0; - - // This is a novel innovation? - if (t_innovid == -1) - { - // Add the new neuron innovation - t_nid = a_Innovs.AddNeuronInnovation(t_in, t_out, HIDDEN); - // add the first link innovation - t_l1id = a_Innovs.AddLinkInnovation(t_in, t_nid); - // add the second innovation - t_l2id = a_Innovs.AddLinkInnovation(t_nid, t_out); - - // Adjust the SplitY - double t_sy = m_NeuronGenes[GetNeuronIndex(t_in)].SplitY() + m_NeuronGenes[GetNeuronIndex(t_out)].SplitY(); - t_sy /= 2.0; - - // Create the neuron gene - NeuronGene t_ngene(HIDDEN, t_nid, t_sy); - - double t_A = a_RNG.RandFloat(), t_B = a_RNG.RandFloat(), t_TC = a_RNG.RandFloat(), t_Bs = - a_RNG.RandFloatSigned() * a_Parameters.WeightReplacementMaxPower; - Scale(t_A, 0, 1, a_Parameters.MinActivationA, a_Parameters.MaxActivationA); - Scale(t_B, 0, 1, a_Parameters.MinActivationB, a_Parameters.MaxActivationB); - Scale(t_TC, 0, 1, a_Parameters.MinNeuronTimeConstant, a_Parameters.MaxNeuronTimeConstant); - //Scale(t_Bs, 0, 1, a_Parameters.MinNeuronBias, a_Parameters.MaxNeuronBias); - - Clamp(t_A, a_Parameters.MinActivationA, a_Parameters.MaxActivationA); - Clamp(t_B, a_Parameters.MinActivationB, a_Parameters.MaxActivationB); - Clamp(t_TC, a_Parameters.MinNeuronTimeConstant, a_Parameters.MaxNeuronTimeConstant); - Clamp(t_Bs, a_Parameters.MinNeuronBias, a_Parameters.MaxNeuronBias); - - // Initialize the neuron gene's properties - t_ngene.Init(t_A, - t_B, - t_TC, - t_Bs, - GetRandomActivation(a_Parameters, a_RNG)); - - // Initialize the traits - if (a_RNG.RandFloat() < 0.5) - { - t_ngene.InitTraits(a_Parameters.NeuronTraits, a_RNG); - } - else - { // mate instead of randomizing - t_ngene.m_Traits = m_NeuronGenes[GetNeuronIndex(t_in)].m_Traits; - t_ngene.MateTraits(m_NeuronGenes[GetNeuronIndex(t_out)].m_Traits, a_RNG); - } - - // Add the NeuronGene - m_NeuronGenes.push_back(t_ngene); - - // Now the links - - // Make sure the recurrent flag is kept - bool t_recurrentflag = t_chosenlink.IsRecurrent(); - - // First link - LinkGene l1 = LinkGene(t_in, t_nid, t_l1id, 1.0, t_recurrentflag); - // Init the link's traits - l1.InitTraits(a_Parameters.LinkTraits, a_RNG); - m_LinkGenes.push_back(l1); - - // Second link - LinkGene l2 = LinkGene(t_nid, t_out, t_l2id, t_orig_weight, t_recurrentflag); - // Init the link's traits - l2.InitTraits(a_Parameters.LinkTraits, a_RNG); - m_LinkGenes.push_back(l2); - } - else - { - // This innovation already happened, so inherit it. - - // get the neuron ID - t_nid = a_Innovs.FindNeuronID(t_in, t_out); - ASSERT(t_nid != -1); - - // if such an innovation happened, these must exist - t_l1id = a_Innovs.CheckInnovation(t_in, t_nid, NEW_LINK); - t_l2id = a_Innovs.CheckInnovation(t_nid, t_out, NEW_LINK); - - ASSERT((t_l1id > 0) && (t_l2id > 0)); - - // Perhaps this innovation occured more than once. Find the - // first such innovation that had occured, but the genome - // not having the same id.. If didn't find such, then add new innovation. - std::vector t_idxs = a_Innovs.CheckAllInnovations(t_in, t_out, NEW_NEURON); - bool t_found = false; - for (unsigned int i = 0; i < t_idxs.size(); i++) - { - if (!HasNeuronID(a_Innovs.GetInnovationByIdx(t_idxs[i]).NeuronID())) - { - // found such innovation & this genome doesn't have that neuron ID - // So we are going to inherit the innovation - t_nid = a_Innovs.GetInnovationByIdx(t_idxs[i]).NeuronID(); - - // these must exist - t_l1id = a_Innovs.CheckInnovation(t_in, t_nid, NEW_LINK); - t_l2id = a_Innovs.CheckInnovation(t_nid, t_out, NEW_LINK); - - ASSERT((t_l1id > 0) && (t_l2id > 0)); - - t_found = true; - break; - } - } - - // Such an innovation was not found or the genome has all neuron IDs - // So we are going to add new innovation - if (!t_found) - { - // Add 3 new innovations and replace the variables with them - - // Add the new neuron innovation - t_nid = a_Innovs.AddNeuronInnovation(t_in, t_out, HIDDEN); - // add the first link innovation - t_l1id = a_Innovs.AddLinkInnovation(t_in, t_nid); - // add the second innovation - t_l2id = a_Innovs.AddLinkInnovation(t_nid, t_out); - } - - - // Add the neuron and the links - double t_sy = m_NeuronGenes[GetNeuronIndex(t_in)].SplitY() + m_NeuronGenes[GetNeuronIndex(t_out)].SplitY(); - t_sy /= 2.0; - - // Create the neuron gene - NeuronGene t_ngene(HIDDEN, t_nid, t_sy); - - double t_A = a_RNG.RandFloat(), t_B = a_RNG.RandFloat(), t_TC = a_RNG.RandFloat(), t_Bs = - a_RNG.RandFloatSigned() * a_Parameters.WeightReplacementMaxPower; - Scale(t_A, 0, 1, a_Parameters.MinActivationA, a_Parameters.MaxActivationA); - Scale(t_B, 0, 1, a_Parameters.MinActivationB, a_Parameters.MaxActivationB); - Scale(t_TC, 0, 1, a_Parameters.MinNeuronTimeConstant, a_Parameters.MaxNeuronTimeConstant); - //Scale(t_Bs, 0, 1, GlobalParameters.MinNeuronBias, GlobalParameters.MaxNeuronBias); - - Clamp(t_A, a_Parameters.MinActivationA, a_Parameters.MaxActivationA); - Clamp(t_B, a_Parameters.MinActivationB, a_Parameters.MaxActivationB); - Clamp(t_TC, a_Parameters.MinNeuronTimeConstant, a_Parameters.MaxNeuronTimeConstant); - Clamp(t_Bs, a_Parameters.MinNeuronBias, a_Parameters.MaxNeuronBias); - - // Initialize the neuron gene's properties - t_ngene.Init(t_A, - t_B, - t_TC, - t_Bs, - GetRandomActivation(a_Parameters, a_RNG)); - - // Initialize the traits - if (a_RNG.RandFloat() < 0.5) - { - t_ngene.InitTraits(a_Parameters.NeuronTraits, a_RNG); - }// mate instead of randomizing - else - { - t_ngene.m_Traits = m_NeuronGenes[GetNeuronIndex(t_in)].m_Traits; - t_ngene.MateTraits(m_NeuronGenes[GetNeuronIndex(t_out)].m_Traits, a_RNG); - } - - // Make sure the recurrent flag is kept - bool t_recurrentflag = t_chosenlink.IsRecurrent(); - - // Add the NeuronGene - m_NeuronGenes.push_back(t_ngene); - // First link - LinkGene l1 = LinkGene(t_in, t_nid, t_l1id, 1.0, t_recurrentflag); - // initialize the link's traits - l1.InitTraits(a_Parameters.LinkTraits, a_RNG); - m_LinkGenes.push_back(l1); - // Second link - LinkGene l2 = LinkGene(t_nid, t_out, t_l2id, t_orig_weight, t_recurrentflag); - // initialize the link's traits - l2.InitTraits(a_Parameters.LinkTraits, a_RNG); - m_LinkGenes.push_back(l2); - } - - return true; - } - - - // Adds a new link to the genome - // returns true if succesful - bool Genome::Mutate_AddLink(InnovationDatabase &a_Innovs, const Parameters &a_Parameters, RNG &a_RNG) - { - // this variable tells where is the first noninput node - int t_first_noninput = 0; - - // The pair of neurons that has to be connected (1 - in, 2 - out) - // It may be the same neuron - this means that the connection is a looped recurrent one. - // These are indexes in the NeuronGenes array! - int t_n1idx = 0, t_n2idx = 0; - - // Should we make this connection recurrent? - bool t_MakeRecurrent = false; - - // If so, should it be a looped one? - bool t_LoopedRecurrent = false; - - // Should it come from the bias neuron? - bool t_MakeBias = false; - - // Counter of tries to find a candidate pair of neuron/s to connect. - unsigned int t_NumTries = 0; - - - // Decide whether the connection will be recurrent or not.. - if (a_RNG.RandFloat() < a_Parameters.RecurrentProb) - { - t_MakeRecurrent = true; - - if (a_RNG.RandFloat() < a_Parameters.RecurrentLoopProb) - { - t_LoopedRecurrent = true; - } - } - // if not recurrent, there is a probability that this link will be from the bias - // if such link doesn't already exist. - // in case such link exists, search for a standard feed-forward connection place - else - { - if (a_RNG.RandFloat() < a_Parameters.MutateAddLinkFromBiasProb) - { - t_MakeBias = true; - } - } - - // Try to find a good pair of neurons - bool t_Found = false; - - // Find the first noninput node - for (unsigned int i = 0; i < NumNeurons(); i++) - { - if ((m_NeuronGenes[i].Type() == INPUT) || (m_NeuronGenes[i].Type() == BIAS)) - { - t_first_noninput++; - } - else - { - break; - } - } - - // A forward link is characterized with the fact that - // the From neuron has less or equal SplitY value - - // find a good pair of nodes for a forward link - if (!t_MakeRecurrent) - { - // first see if this should come from the bias or not - bool t_found_bias = true; - t_n1idx = static_cast(NumInputs() - 1); // the bias is always the last input - // try to find a neuron that is not connected to the bias already - t_NumTries = 0; - do - { - t_n2idx = a_RNG.RandInt(t_first_noninput, static_cast(NumNeurons() - 1)); - t_NumTries++; - - if (t_NumTries >= a_Parameters.LinkTries) - { - // couldn't find anything - t_found_bias = false; - break; - } - } - while ((HasLink(m_NeuronGenes[t_n1idx].ID(), m_NeuronGenes[t_n2idx].ID()))); // already present? - - // so if we found that link, we can skip the rest of the things - if (t_found_bias && t_MakeBias) - { - t_Found = true; - } - // otherwise continue trying to find a normal forward link - else - { - t_NumTries = 0; - // try to find a standard forward connection - do - { - t_n1idx = a_RNG.RandInt(0, static_cast(NumNeurons() - 1)); - t_n2idx = a_RNG.RandInt(t_first_noninput, static_cast(NumNeurons() - 1)); - t_NumTries++; - - if (t_NumTries >= a_Parameters.LinkTries) - { - // couldn't find anything - // say goodbye - return false; - } - } - while ( - (m_NeuronGenes[t_n1idx].SplitY() > m_NeuronGenes[t_n2idx].SplitY()) // backward? - || - (HasLink(m_NeuronGenes[t_n1idx].ID(), m_NeuronGenes[t_n2idx].ID())) // already present? - || - (m_NeuronGenes[t_n1idx].Type() == OUTPUT) // consider connections out of outputs recurrent - || - (t_n1idx == t_n2idx) // make sure they differ - ); - - // it found a good pair of neurons - t_Found = true; - } - } - // find a good pair of nodes for a recurrent link (non-looped) - else if (t_MakeRecurrent && !t_LoopedRecurrent) - { - t_NumTries = 0; - do - { - t_n1idx = a_RNG.RandInt(t_first_noninput, static_cast(NumNeurons() - 1)); - t_n2idx = a_RNG.RandInt(t_first_noninput, static_cast(NumNeurons() - 1)); - t_NumTries++; - - if (t_NumTries >= a_Parameters.LinkTries) - { - // couldn't find anything - // say goodbye - return false; - } - } - // NOTE: this considers output-output connections as forward. Should be fixed. - while ( - (m_NeuronGenes[t_n1idx].SplitY() <= m_NeuronGenes[t_n2idx].SplitY()) // forward? - || - (HasLink(m_NeuronGenes[t_n1idx].ID(), m_NeuronGenes[t_n2idx].ID())) // already present? - || - (t_n1idx == t_n2idx) // they should differ - ); - - // it found a good pair of neurons - t_Found = true; - } - // find a good neuron to make a looped recurrent link - else if (t_MakeRecurrent && t_LoopedRecurrent) - { - t_NumTries = 0; - do - { - t_n1idx = t_n2idx = a_RNG.RandInt(t_first_noninput, static_cast(NumNeurons() - 1)); - t_NumTries++; - - if (t_NumTries >= a_Parameters.LinkTries) - { - // couldn't find anything - // say goodbye - return false; - } - } - while ( - (HasLink(m_NeuronGenes[t_n1idx].ID(), m_NeuronGenes[t_n2idx].ID())) // already present? - //|| - //(m_NeuronGenes[t_n1idx].Type() == OUTPUT) // do not allow looped recurrent on the outputs (experimental) - ); - - // it found a good pair of neurons - t_Found = true; - } - - - // To make sure it is all right - if (!t_Found) - { - return false; - } - - // This link MUST NOT be a part of the genome by any reason - ASSERT((!HasLink(m_NeuronGenes[t_n1idx].ID(), m_NeuronGenes[t_n2idx].ID()))); // already present? - - // extract the neuron IDs from the indexes - int t_n1id = m_NeuronGenes[t_n1idx].ID(); - int t_n2id = m_NeuronGenes[t_n2idx].ID(); - - // So we have a good pair of neurons to connect. See the innovation database if this is novel innovation. - int t_innovid = a_Innovs.CheckInnovation(t_n1id, t_n2id, NEW_LINK); - - // Choose the weight for this link - double t_weight = a_RNG.RandFloatSigned() * a_Parameters.WeightReplacementMaxPower; - - // A novel innovation? - if (t_innovid == -1) - { - // Make new innovation - t_innovid = a_Innovs.AddLinkInnovation(t_n1id, t_n2id); - } - - // Create and add the link - LinkGene l = LinkGene(t_n1id, t_n2id, t_innovid, t_weight, t_MakeRecurrent); - // init the link's traits - l.InitTraits(a_Parameters.LinkTraits, a_RNG); - m_LinkGenes.push_back(l); - - // All done. - return true; - } - - - - - /////////// - // Helper functions for the pruning procedure - - // Removes the link with the specified innovation ID - void Genome::RemoveLinkGene(int a_InnovID) - { - // for iterating through the genes - std::vector::iterator t_curlink = m_LinkGenes.begin(); - - while (t_curlink != m_LinkGenes.end()) - { - if (t_curlink->InnovationID() == a_InnovID) - { - // found it - erase & quit - t_curlink = m_LinkGenes.erase(t_curlink); - break; - } - - t_curlink++; - } - } - - - // Remove node - // Links connected to this node are also removed - void Genome::RemoveNeuronGene(int a_ID) - { - // the list of links connected to this neuron - std::vector t_link_removal_queue; - - // OK find all links connected to this neuron ID - for (unsigned int i = 0; i < NumLinks(); i++) - { - if ((m_LinkGenes[i].FromNeuronID() == a_ID) || (m_LinkGenes[i].ToNeuronID() == a_ID)) - { - // found one, add it - t_link_removal_queue.push_back(m_LinkGenes[i].InnovationID()); - } - } - - // Now remove them - for (unsigned int i = 0; i < t_link_removal_queue.size(); i++) - { - RemoveLinkGene(t_link_removal_queue[i]); - } - - // Now is safe to remove the neuron - // find it first - std::vector::iterator t_curneuron = m_NeuronGenes.begin(); - - while (t_curneuron != m_NeuronGenes.end()) - { - if (t_curneuron->ID() == a_ID) - { - // found it, erase and quit - m_NeuronGenes.erase(t_curneuron); - break; - } - - t_curneuron++; - } - } - - - // Returns true is the specified neuron ID is a dead end or isolated - bool Genome::IsDeadEndNeuron(int a_ID) const - { - bool t_no_incoming = true; - bool t_no_outgoing = true; - - // search the links and prove both are wrong - for (unsigned int i = 0; i < NumLinks(); i++) - { - // there is a link going to this neuron, so there are incoming - // don't count the link if it is recurrent or coming from a bias - if ((m_LinkGenes[i].ToNeuronID() == a_ID) - && (!m_LinkGenes[i].IsLoopedRecurrent()) - && (GetNeuronByID(m_LinkGenes[i].FromNeuronID()).Type() != BIAS)) - { - t_no_incoming = false; - } - - // there is a link going from this neuron, so there are outgoing - // don't count the link if it is recurrent or coming from a bias - if ((m_LinkGenes[i].FromNeuronID() == a_ID) - && (!m_LinkGenes[i].IsLoopedRecurrent()) - && (GetNeuronByID(m_LinkGenes[i].FromNeuronID()).Type() != BIAS)) - { - t_no_outgoing = false; - } - } - - // if just one of these is true, this neuron is a dead end - if (t_no_incoming || t_no_outgoing) - { - return true; - } - else - { - return false; - } - } - - - // Search the genome for isolated structure and clean it up - // Returns true is something was removed - bool Genome::Cleanup() - { - bool t_removed = false; - - // remove any dead-end hidden neurons - for (unsigned int i = 0; i < NumNeurons(); i++) - { - if (m_NeuronGenes[i].Type() == HIDDEN) - { - if (IsDeadEndNeuron(m_NeuronGenes[i].ID())) - { - RemoveNeuronGene(m_NeuronGenes[i].ID()); - t_removed = true; - } - } - } - - // a special case are isolated outputs - these are outputs having - // one and only one looped recurrent connection - // we simply remove these connections and leave the outputs naked. - for (unsigned int i = 0; i < NumNeurons(); i++) - { - if (m_NeuronGenes[i].Type() == OUTPUT) - { - // Only outputs with 1 input and 1 output connection are considered. - if ((LinksInputtingFrom(m_NeuronGenes[i].ID()) == 1) && (LinksOutputtingTo(m_NeuronGenes[i].ID()) == 1)) - { - // that must be a lonely looped recurrent, - // because we know that the outputs are the dead end of the network - // find this link - for (unsigned int j = 0; j < NumLinks(); j++) - { - if (m_LinkGenes[j].ToNeuronID() == m_NeuronGenes[i].ID()) - { - // Remove it. - RemoveLinkGene(m_LinkGenes[j].InnovationID()); - t_removed = true; - } - } - } - } - } - - return t_removed; - } - - - // Returns true if has any dead end - bool Genome::HasDeadEnds() const - { - // any dead-end hidden neurons? - for (unsigned int i = 0; i < NumNeurons(); i++) - { - if (m_NeuronGenes[i].Type() == HIDDEN) - { - if (IsDeadEndNeuron(m_NeuronGenes[i].ID())) - { - return true; - } - } - } - - // a special case are isolated outputs - these are outputs having - // one and only one looped recurrent connection or no connections at all - for (unsigned int i = 0; i < NumNeurons(); i++) - { - if (m_NeuronGenes[i].Type() == OUTPUT) - { - // Only outputs with 1 input and 1 output connection are considered. - if ((LinksInputtingFrom(m_NeuronGenes[i].ID()) == 1) && (LinksOutputtingTo(m_NeuronGenes[i].ID()) == 1)) - { - // that must be a lonely looped recurrent, - // because we know that the outputs are the dead end of the network - return true; - } - - // There may be cases for totally isolated outputs - // Consider this if only one output is present - if (NumOutputs() == 1) - if ((LinksInputtingFrom(m_NeuronGenes[i].ID()) == 0) && - (LinksOutputtingTo(m_NeuronGenes[i].ID()) == 0)) - { - return true; - } - } - } - - return false; - } - - - // Remove a link from the genome - // A cleanup procedure is invoked so any dead-ends or stranded neurons are also deleted - // returns true if succesful - bool Genome::Mutate_RemoveLink(RNG &a_RNG) - { - // at least 2 links must be present in the genome - if (NumLinks() < 2) - return false; - - // find a random link to remove - // with tendency to remove older connections - double t_randnum = a_RNG.RandFloat();//RandGaussSigned()/4; - Clamp(t_randnum, 0, 1); - - int t_link_index = static_cast(t_randnum * static_cast(NumLinks() - - 1));//RandInt(0, static_cast(NumLinks()-1)); - - // remove it - RemoveLinkGene(m_LinkGenes[t_link_index].InnovationID()); - - // Now cleanup - //Cleanup(); - - return true; - } - - - // Returns the count of links inputting from the specified neuron ID - int Genome::LinksInputtingFrom(int a_ID) const - { - int t_counter = 0; - for (unsigned int i = 0; i < NumLinks(); i++) - { - if (m_LinkGenes[i].FromNeuronID() == a_ID) - t_counter++; - } - - return t_counter; - } - - - // Returns the count of links outputting to the specified neuron ID - int Genome::LinksOutputtingTo(int a_ID) const - { - int t_counter = 0; - for (unsigned int i = 0; i < NumLinks(); i++) - { - if (m_LinkGenes[i].ToNeuronID() == a_ID) - t_counter++; - } - - return t_counter; - } - - - // Replaces a hidden neuron having only one input and only one output with - // a direct link between them. - bool Genome::Mutate_RemoveSimpleNeuron(InnovationDatabase &a_Innovs, RNG &a_RNG) - { - // At least one hidden node must be present - if (NumNeurons() == (NumInputs() + NumOutputs())) - return false; - - // Build a list of candidate neurons for deletion - // Indexes! - std::vector t_neurons_to_delete; - for (int i = 0; i < NumNeurons(); i++) - { - if ((LinksInputtingFrom(m_NeuronGenes[i].ID()) == 1) && (LinksOutputtingTo(m_NeuronGenes[i].ID()) == 1) - && (m_NeuronGenes[i].Type() == HIDDEN)) - { - t_neurons_to_delete.push_back(i); - } - } - - // If the list is empty, say goodbye - if (t_neurons_to_delete.size() == 0) - return false; - - // Now choose a random one to delete - int t_choice; - if (t_neurons_to_delete.size() == 2) - t_choice = Rounded(a_RNG.RandFloat()); - else - t_choice = a_RNG.RandInt(0, static_cast(t_neurons_to_delete.size() - 1)); - - // the links in & out - int t_l1idx = -1, t_l2idx = -1; - - // find the link outputting to the neuron - for (unsigned int i = 0; i < NumLinks(); i++) - { - if (m_LinkGenes[i].ToNeuronID() == m_NeuronGenes[t_neurons_to_delete[t_choice]].ID()) - { - t_l1idx = i; - break; - } - } - // find the link inputting from the neuron - for (unsigned int i = 0; i < NumLinks(); i++) - { - if (m_LinkGenes[i].FromNeuronID() == m_NeuronGenes[t_neurons_to_delete[t_choice]].ID()) - { - t_l2idx = i; - break; - } - } - - ASSERT((t_l1idx >= 0) && (t_l2idx >= 0)); - - // OK now see if a link connecting the original 2 nodes is present. If it is, we will just - // delete the neuron and quit. - if (HasLink(m_LinkGenes[t_l1idx].FromNeuronID(), m_LinkGenes[t_l2idx].ToNeuronID())) - { - RemoveNeuronGene(m_NeuronGenes[t_neurons_to_delete[t_choice]].ID()); - return true; - } - // Else the link is not present and we will replace the neuron and 2 links with one link - else - { - // Remember the first link's weight - double t_weight = m_LinkGenes[t_l1idx].GetWeight(); - - // See the innovation database for an innovation number - int t_innovid = a_Innovs.CheckInnovation(m_LinkGenes[t_l1idx].FromNeuronID(), - m_LinkGenes[t_l2idx].ToNeuronID(), NEW_LINK); - - // a novel innovation? - if (t_innovid == -1) - { - // Add the innovation and the link gene - int t_newinnov = a_Innovs.AddLinkInnovation(m_LinkGenes[t_l1idx].FromNeuronID(), - m_LinkGenes[t_l2idx].ToNeuronID()); - m_LinkGenes.push_back( - LinkGene(m_LinkGenes[t_l1idx].FromNeuronID(), m_LinkGenes[t_l2idx].ToNeuronID(), t_newinnov, - t_weight, false)); - - // Remove the neuron now - RemoveNeuronGene(m_NeuronGenes[t_neurons_to_delete[t_choice]].ID()); - - // bye - return true; - } - // not a novel innovation - else - { - // Add the link and remove the neuron - m_LinkGenes.push_back( - LinkGene(m_LinkGenes[t_l1idx].FromNeuronID(), m_LinkGenes[t_l2idx].ToNeuronID(), t_innovid, - t_weight, false)); - - // Remove the neuron now - RemoveNeuronGene(m_NeuronGenes[t_neurons_to_delete[t_choice]].ID()); - - // bye - return true; - } - } - - return false; - } - - - // Perturbs the weights - bool Genome::Mutate_LinkWeights(const Parameters &a_Parameters, RNG &a_RNG) - { - // The end part of the genome - int t_genometail = 0; - if (NumLinks() > m_initial_num_links) - { - t_genometail = (int)(((double)(NumLinks())) * 0.8); - } - if (t_genometail < m_initial_num_links) - { - t_genometail = m_initial_num_links; - } - - bool did_mutate = false; - - // This tells us if this mutation will shake things up - bool t_severe_mutation; - - if (a_RNG.RandFloat() < a_Parameters.MutateWeightsSevereProb) - { - t_severe_mutation = true; - } - else - { - t_severe_mutation = false; - } - - // For all links.. - for(unsigned int i=0; i= t_genometail); - - if (ontail || (a_RNG.RandFloat() < a_Parameters.WeightReplacementRate)) - { - t_LinkGenesWeight = a_RNG.RandFloatSigned() * a_Parameters.WeightReplacementMaxPower; - } - else - { - t_LinkGenesWeight += a_RNG.RandFloatSigned() * a_Parameters.WeightMutationMaxPower; - } - - Clamp(t_LinkGenesWeight, -a_Parameters.MaxWeight, a_Parameters.MaxWeight); - m_LinkGenes[i].SetWeight(t_LinkGenesWeight); - - did_mutate = true; - } - else if (t_severe_mutation) - { - t_LinkGenesWeight = a_RNG.RandFloatSigned() * a_Parameters.WeightReplacementMaxPower; - - did_mutate = true; - } - } - - return did_mutate; - } - - - // Set all link weights to random values between [-R .. R] - void Genome::Randomize_LinkWeights(double a_Range, RNG &a_RNG) - { - // For all links.. - for (unsigned int i = 0; i < NumLinks(); i++) - { - m_LinkGenes[i].SetWeight( - a_RNG.RandFloatSigned() * a_Range); - } - } - - // Randomize traits - void Genome::Randomize_Traits(const Parameters &a_Parameters, RNG &a_RNG) - { - for (auto &m_NeuronGene : m_NeuronGenes) - { - m_NeuronGene.InitTraits(a_Parameters.NeuronTraits, a_RNG); - } - for (auto &m_LinkGene : m_LinkGenes) - { - m_LinkGene.InitTraits(a_Parameters.LinkTraits, a_RNG); - } - - m_GenomeGene.InitTraits(a_Parameters.GenomeTraits, a_RNG); - } - - // Perturbs the A parameters of the neuron activation functions - bool Genome::Mutate_NeuronActivations_A(const Parameters &a_Parameters, RNG &a_RNG) - { - // for all neurons.. - for (unsigned int i = 0; i < NumNeurons(); i++) - { - // skip inputs and bias - if ((m_NeuronGenes[i].Type() != INPUT) && (m_NeuronGenes[i].Type() != BIAS)) - { - double t_randnum = a_RNG.RandFloatSigned() * a_Parameters.ActivationAMutationMaxPower; - - m_NeuronGenes[i].m_A += t_randnum; - - Clamp(m_NeuronGenes[i].m_A, a_Parameters.MinActivationA, a_Parameters.MaxActivationA); - } - } - - return true; - } - - - // Perturbs the B parameters of the neuron activation functions - bool Genome::Mutate_NeuronActivations_B(const Parameters &a_Parameters, RNG &a_RNG) - { - // for all neurons.. - for (unsigned int i = 0; i < NumNeurons(); i++) - { - // skip inputs and bias - if ((m_NeuronGenes[i].Type() != INPUT) && (m_NeuronGenes[i].Type() != BIAS)) - { - double t_randnum = a_RNG.RandFloatSigned() * a_Parameters.ActivationBMutationMaxPower; - - m_NeuronGenes[i].m_B += t_randnum; - - Clamp(m_NeuronGenes[i].m_B, a_Parameters.MinActivationB, a_Parameters.MaxActivationB); - } - } - - return true; - } - - - // Changes the activation function type for a random neuron - bool Genome::Mutate_NeuronActivation_Type(const Parameters &a_Parameters, RNG &a_RNG) - { - // the first non-input neuron - int t_first_idx = NumInputs(); - int t_choice = a_RNG.RandInt(t_first_idx, m_NeuronGenes.size() - 1); - - int cur = m_NeuronGenes[t_choice].m_ActFunction; - - m_NeuronGenes[t_choice].m_ActFunction = GetRandomActivation(a_Parameters, a_RNG); - if (m_NeuronGenes[t_choice].m_ActFunction == cur) // same as before? - { - return false; - } - else - { - return true; - } - } - - // Perturbs the neuron time constants - bool Genome::Mutate_NeuronTimeConstants(const Parameters &a_Parameters, RNG &a_RNG) - { - // for all neurons.. - for (unsigned int i = 0; i < NumNeurons(); i++) - { - // skip inputs and bias - if ((m_NeuronGenes[i].Type() != INPUT) && (m_NeuronGenes[i].Type() != BIAS)) - { - double t_randnum = a_RNG.RandFloatSigned() * a_Parameters.TimeConstantMutationMaxPower; - - m_NeuronGenes[i].m_TimeConstant += t_randnum; - - Clamp(m_NeuronGenes[i].m_TimeConstant, a_Parameters.MinNeuronTimeConstant, - a_Parameters.MaxNeuronTimeConstant); - } - } - - return true; - } - - // Perturbs the neuron biases - bool Genome::Mutate_NeuronBiases(const Parameters &a_Parameters, RNG &a_RNG) - { - // for all neurons.. - for (unsigned int i = 0; i < NumNeurons(); i++) - { - // skip inputs and bias - if ((m_NeuronGenes[i].Type() != INPUT) && (m_NeuronGenes[i].Type() != BIAS)) - { - double t_randnum = a_RNG.RandFloatSigned() * a_Parameters.BiasMutationMaxPower; - - m_NeuronGenes[i].m_Bias += t_randnum; - - Clamp(m_NeuronGenes[i].m_TimeConstant, a_Parameters.MinNeuronBias, a_Parameters.MaxNeuronBias); - } - } - - return true; - } - - bool Genome::Mutate_NeuronTraits(const Parameters &a_Parameters, RNG &a_RNG) - { - bool did_mutate = false; - for(auto it = m_NeuronGenes.begin(); it != m_NeuronGenes.end(); it++) - { - // don't mutate inputs and bias - if ((it->Type() != INPUT) && (it->Type() != BIAS)) - { - if (it->MutateTraits(a_Parameters.NeuronTraits, a_RNG)) - { - did_mutate = true; - } - } - } - return did_mutate; - } - - bool Genome::Mutate_LinkTraits(const Parameters &a_Parameters, RNG &a_RNG) - { - bool did_mutate = false; - for(auto it = m_LinkGenes.begin(); it != m_LinkGenes.end(); it++) - { - if ( it->MutateTraits(a_Parameters.LinkTraits, a_RNG) ) - { - did_mutate = true; - } - } - return did_mutate; - } - - bool Genome::Mutate_GenomeTraits(const Parameters &a_Parameters, RNG &a_RNG) - { - return m_GenomeGene.MutateTraits(a_Parameters.GenomeTraits, a_RNG); - } - - // Mate this genome with dad and return the baby - // This is multipoint mating - genes inherited randomly - // Disjoint and excess genes are inherited from the fittest parent - // If fitness is equal, the smaller genome is assumed to be the better one - Genome Genome::Mate(Genome &a_Dad, bool a_MateAverage, bool a_InterSpecies, RNG &a_RNG, Parameters &a_Parameters) - { - // Cannot mate with itself - if (GetID() == a_Dad.GetID()) - return *this; - - // helps make the code clearer - enum t_parent_type - { - MOM, DAD, - }; - - // This is the fittest genome. - t_parent_type t_better; - - // This empty genome will hold the baby - Genome t_baby; - - // create iterators so we can step through each parents genes and set - // them to the first gene of each parent - std::vector::iterator t_curMom = m_LinkGenes.begin(); - std::vector::iterator t_curDad = a_Dad.m_LinkGenes.begin(); - - // this will hold a copy of the gene we wish to add at each step - LinkGene t_selectedgene(0, 0, -1, 0, false); - - // Mate the GenomeGene first - // Determine if it will pick either gene or mate it - if (a_RNG.RandFloat() < 0.5) - { - // pick - Gene n = ((a_RNG.RandFloat() < 0.5f)==0)? m_GenomeGene : a_Dad.m_GenomeGene; - t_baby.m_GenomeGene = n; - } - else - { - // mate - Gene n = m_GenomeGene; - n.MateTraits(a_Dad.m_GenomeGene.m_Traits, a_RNG); - t_baby.m_GenomeGene = n; - } - - - // Make sure all inputs/outputs are present in the baby - // Essential to FS-NEAT - - if (!a_Parameters.DontUseBiasNeuron) - { - // the inputs - unsigned int i = 0; - for (i = 0; i < m_NumInputs - 1; i++) - { - // Determine if it will pick either gene or mate it - if (a_RNG.RandFloat() < 0.5) - { - // pick - NeuronGene n = ((a_RNG.RandFloat() < 0.5f)==0)? m_NeuronGenes[i] : a_Dad.m_NeuronGenes[i]; - t_baby.m_NeuronGenes.push_back(n); - } - else - { - // mate - NeuronGene n = m_NeuronGenes[i]; - n.MateTraits(a_Dad.m_NeuronGenes[i].m_Traits, a_RNG); - t_baby.m_NeuronGenes.push_back(n); - } - - } - if (a_RNG.RandFloat() < 0.5) - { - // the bias - NeuronGene nb = ((a_RNG.RandFloat() < 0.5f) == 0) ? m_NeuronGenes[i] : a_Dad.m_NeuronGenes[i]; - t_baby.m_NeuronGenes.push_back(nb); - } - else - { - // mate - NeuronGene nb = m_NeuronGenes[i]; - nb.MateTraits(a_Dad.m_NeuronGenes[i].m_Traits, a_RNG); - t_baby.m_NeuronGenes.push_back(nb); - } - } - else - { - // the inputs - for (unsigned int i = 0; i < m_NumInputs; i++) - { - if (a_RNG.RandFloat() < 0.5) - { - NeuronGene n = ((a_RNG.RandFloat() < 0.5f) == 0) ? m_NeuronGenes[i] : a_Dad.m_NeuronGenes[i]; - t_baby.m_NeuronGenes.push_back(n); - } - else - { - NeuronGene n = m_NeuronGenes[i]; - n.MateTraits(a_Dad.m_NeuronGenes[i].m_Traits, a_RNG); - t_baby.m_NeuronGenes.push_back(n); - } - } - } - - // the outputs - for (unsigned int i = 0; i < m_NumOutputs; i++) - { - NeuronGene t_tempneuron(OUTPUT, 0, 1); - - if (a_RNG.RandFloat() < 0.5) - { - // random pick - if (a_RNG.RandFloat() < 0.5f) - { - // from mother - t_tempneuron = GetNeuronByIndex(i + m_NumInputs); - } - else - { - // from father - t_tempneuron = a_Dad.GetNeuronByIndex(i + m_NumInputs); - } - } - else - { - // mating - // from mother - t_tempneuron = GetNeuronByIndex(i + m_NumInputs); - t_tempneuron.MateTraits(a_Dad.GetNeuronByIndex(i + m_NumInputs).m_Traits, a_RNG); - } - - t_baby.m_NeuronGenes.push_back(t_tempneuron); - } - - // if they are of equal fitness use the shorter (because we want to keep - // the networks as small as possible) - if (m_Fitness == a_Dad.m_Fitness) - { - // if they are of equal fitness and length just choose one at - // random - if (NumLinks() == a_Dad.NumLinks()) - { - if (a_RNG.RandFloat() < 0.5f) - { - t_better = MOM; - } - else - { - t_better = DAD; - } - } - else - { - if (NumLinks() < a_Dad.NumLinks()) - { - t_better = MOM; - } - else - { - t_better = DAD; - } - } - } - else - { - if (m_Fitness > a_Dad.m_Fitness) - { - t_better = MOM; - } - else - { - t_better = DAD; - } - } - - ////////////////////////////////////////////////////////// - // The better genome has been chosen. Now we mate them. - ////////////////////////////////////////////////////////// - - // for cleaning up - LinkGene t_emptygene(0, 0, -1, 0, false); - bool t_skip = false; - int t_innov_mom, t_innov_dad; - - // step through each parents link genes until we reach the end of both - while (!((t_curMom == m_LinkGenes.end()) && (t_curDad == a_Dad.m_LinkGenes.end()))) - { - t_selectedgene = t_emptygene; - t_skip = false; - t_innov_mom = t_innov_dad = 0; - - // the end of mum's genes have been reached - // EXCESS - if (t_curMom == m_LinkGenes.end()) - { - // select dads gene - t_selectedgene = *t_curDad; - // move onto dad's next gene - t_curDad++; - - // if mom is fittest, abort adding - if (t_better == MOM) - { - t_skip = true; - } - } - - // the end of dads's genes have been reached - // EXCESS - else if (t_curDad == a_Dad.m_LinkGenes.end()) - { - // add mums gene - t_selectedgene = *t_curMom; - // move onto mum's next gene - t_curMom++; - - // if dad is fittest, abort adding - if (t_better == DAD) - { - t_skip = true; - } - } - else - { - // extract the innovation numbers - t_innov_mom = t_curMom->InnovationID(); - t_innov_dad = t_curDad->InnovationID(); - - // if both innovations match - if (t_innov_mom == t_innov_dad) - { - // get a gene from either parent or average - if (!a_MateAverage) - { - if (a_RNG.RandFloat() < 0.5) - { - t_selectedgene = *t_curMom; - } - else - { - t_selectedgene = *t_curDad; - } - } - else - { - t_selectedgene = *t_curMom; - const double t_Weight = (t_curDad->GetWeight() + t_curMom->GetWeight()) / 2.0; - t_selectedgene.SetWeight(t_Weight); - // Mate traits here - t_selectedgene.MateTraits(t_curDad->m_Traits, a_RNG); - } - - // move onto next gene of each parent - t_curMom++; - t_curDad++; - } - else // DISJOINT - if (t_innov_mom < t_innov_dad) - { - t_selectedgene = *t_curMom; - t_curMom++; - - if (t_better == DAD) - { - t_skip = true; - } - } - else // DISJOINT - if (t_innov_dad < t_innov_mom) - { - t_selectedgene = *t_curDad; - t_curDad++; - - if (t_better == MOM) - { - t_skip = true; - } - } - } - - // for interspecies mating, allow all genes through - if (a_InterSpecies) - { - t_skip = false; - } - - // If the selected gene's innovation number is negative, - // this means that no gene is selected (should be skipped) - // also check the baby if it already has this link (maybe unnecessary) - if ((t_selectedgene.InnovationID() > 0) && - (!t_baby.HasLink(t_selectedgene.FromNeuronID(), t_selectedgene.ToNeuronID()))) - { - if (!t_skip) - { - t_baby.m_LinkGenes.push_back(t_selectedgene); - - // Check if we already have the nodes referred to in t_selectedgene. - // If not, they need to be added. - - NeuronGene t_ngene1(NONE, 0, 0); - NeuronGene t_ngene2(NONE, 0, 0); - - // mom has a neuron ID not present in the baby? - // From - if ((!t_baby.HasNeuronID(t_selectedgene.FromNeuronID())) && - (HasNeuronID(t_selectedgene.FromNeuronID()))) - { - // See if dad has the same neuron. - if (a_Dad.HasNeuronID(t_selectedgene.FromNeuronID())) - { - // if so, then choose randomly which neuron the baby shoud inherit - if (a_RNG.RandFloat() < 0.5f) - { - // add mom's neuron to the baby - t_baby.m_NeuronGenes.push_back( - m_NeuronGenes[GetNeuronIndex(t_selectedgene.FromNeuronID())]); - } - else - { - // add dad's neuron to the baby - t_baby.m_NeuronGenes.push_back( - a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.FromNeuronID())]); - } - } - else - { - // add mom's neuron to the baby - t_baby.m_NeuronGenes.push_back( - m_NeuronGenes[GetNeuronIndex(t_selectedgene.FromNeuronID())]); - } - } - - // To - if ((!t_baby.HasNeuronID(t_selectedgene.ToNeuronID())) && - (HasNeuronID(t_selectedgene.ToNeuronID()))) - { - // See if dad has the same neuron. - if (a_Dad.HasNeuronID(t_selectedgene.ToNeuronID())) - { - // if so, then choose randomly which neuron the baby shoud inherit - if (a_RNG.RandFloat() < 0.5f) - { - // add mom's neuron to the baby - t_baby.m_NeuronGenes.push_back( - m_NeuronGenes[GetNeuronIndex(t_selectedgene.ToNeuronID())]); - } - else - { - // add dad's neuron to the baby - t_baby.m_NeuronGenes.push_back( - a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.ToNeuronID())]); - } - } - else - { - // add mom's neuron to the baby - t_baby.m_NeuronGenes.push_back(m_NeuronGenes[GetNeuronIndex(t_selectedgene.ToNeuronID())]); - } - } - - // dad has a neuron ID not present in the baby? - // From - if ((!t_baby.HasNeuronID(t_selectedgene.FromNeuronID())) && - (a_Dad.HasNeuronID(t_selectedgene.FromNeuronID()))) - { - // See if mom has the same neuron - if (HasNeuronID(t_selectedgene.FromNeuronID())) - { - // if so, then choose randomly which neuron the baby shoud inherit - if (a_RNG.RandFloat() < 0.5f) - { - // add dad's neuron to the baby - t_baby.m_NeuronGenes.push_back( - a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.FromNeuronID())]); - } - else - { - // add mom's neuron to the baby - t_baby.m_NeuronGenes.push_back( - m_NeuronGenes[GetNeuronIndex(t_selectedgene.FromNeuronID())]); - } - } - else - { - // add dad's neuron to the baby - t_baby.m_NeuronGenes.push_back( - a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.FromNeuronID())]); - } - } - - // To - if ((!t_baby.HasNeuronID(t_selectedgene.ToNeuronID())) && - (a_Dad.HasNeuronID(t_selectedgene.ToNeuronID()))) - { - // See if mom has the same neuron - if (HasNeuronID(t_selectedgene.ToNeuronID())) - { - // if so, then choose randomly which neuron the baby shoud inherit - if (a_RNG.RandFloat() < 0.5f) - { - // add dad's neuron to the baby - t_baby.m_NeuronGenes.push_back( - a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.ToNeuronID())]); - } - else - { - // add mom's neuron to the baby - t_baby.m_NeuronGenes.push_back( - m_NeuronGenes[GetNeuronIndex(t_selectedgene.ToNeuronID())]); - } - } - else - { - // add dad's neuron to the baby - t_baby.m_NeuronGenes.push_back( - a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.ToNeuronID())]); - } - } - } - } - - } //end while - - t_baby.m_NumInputs = m_NumInputs; - t_baby.m_NumOutputs = m_NumOutputs; - - // Sort the baby's genes - t_baby.SortGenes(); - - return t_baby; - } - - - // Sorts the genes of the genome - // The neurons by IDs and the links by innovation numbers. - bool neuron_compare(NeuronGene a_ls, NeuronGene a_rs) - { - return a_ls.ID() < a_rs.ID(); - } - - bool link_compare(LinkGene a_ls, LinkGene a_rs) - { - return a_ls.InnovationID() < a_rs.InnovationID(); - } - - void Genome::SortGenes() - { - std::sort(m_NeuronGenes.begin(), m_NeuronGenes.end(), neuron_compare); - std::sort(m_LinkGenes.begin(), m_LinkGenes.end(), link_compare); - } - - unsigned int Genome::NeuronDepth(int a_NeuronID, unsigned int a_Depth) - { - unsigned int t_current_depth; - unsigned int t_max_depth = a_Depth; - - if (a_Depth > 16384) - { - // oops! a possible loop in the network! - // DBG(" ERROR! Trying to get the depth of a looped network!"); - return 16384; - } - - // Base case - if ((GetNeuronByID(a_NeuronID).Type() == INPUT) || (GetNeuronByID(a_NeuronID).Type() == BIAS)) - { - return a_Depth; - } - - // Find all links outputting to this neuron ID - std::vector t_inputting_links_idx; - for (unsigned int i = 0; i < NumLinks(); i++) - { - if (m_LinkGenes[i].ToNeuronID() == a_NeuronID) - t_inputting_links_idx.push_back(i); - } - - // For all incoming links.. - for (unsigned int i = 0; i < t_inputting_links_idx.size(); i++) - { - LinkGene t_link = GetLinkByIndex(t_inputting_links_idx[i]); - - // RECURSION - t_current_depth = NeuronDepth(t_link.FromNeuronID(), a_Depth + 1); - if (t_current_depth > t_max_depth) - t_max_depth = t_current_depth; - } - - return t_max_depth; - } - - - void Genome::CalculateDepth() - { - unsigned int t_max_depth = 0; - unsigned int t_cur_depth = 0; - - // The quick case - if no hidden neurons, - // the depth is 1 - if (NumNeurons() == (m_NumInputs + m_NumOutputs)) - { - m_Depth = 1; - return; - } - - // make a list of all output IDs - std::vector t_output_ids; - for (unsigned int i = 0; i < NumNeurons(); i++) - { - if (m_NeuronGenes[i].Type() == OUTPUT) - { - t_output_ids.push_back(m_NeuronGenes[i].ID()); - } - } - - // For each output - for (unsigned int i = 0; i < t_output_ids.size(); i++) - { - t_cur_depth = NeuronDepth(t_output_ids[i], 0); - - if (t_cur_depth > t_max_depth) - t_max_depth = t_cur_depth; - } - - m_Depth = t_max_depth; - } - - - - ////////////////////////////////////////////////////////////////////////////////// - // Saving/Loading methods - ////////////////////////////////////////////////////////////////////////////////// - - // Builds this genome from a file - Genome::Genome(const char *a_FileName) - { - std::ifstream t_DataFile(a_FileName); - *this = Genome(t_DataFile); - t_DataFile.close(); - } - - // Builds the genome from an *opened* file - Genome::Genome(std::ifstream &a_DataFile) - { - std::string t_Str; - - if (!a_DataFile) - { - ostringstream tStream; - tStream << "Genome file error!" << std::endl; - throw std::runtime_error("Genome file error!"); - } - - // search for GenomeStart - do - { - a_DataFile >> t_Str; - } - while (t_Str != "GenomeStart"); - - // read the genome ID - unsigned int t_gid; - a_DataFile >> t_gid; - m_ID = t_gid; - - // read the genome until GenomeEnd is encountered - do - { - a_DataFile >> t_Str; - - if (t_Str == "Neuron") - { - int t_id, t_type, t_activationfunc; - double t_splity, t_a, t_b, t_timeconst, t_bias; - - a_DataFile >> t_id; - a_DataFile >> t_type; - a_DataFile >> t_splity; - - a_DataFile >> t_activationfunc; - a_DataFile >> t_a; - a_DataFile >> t_b; - a_DataFile >> t_timeconst; - a_DataFile >> t_bias; - - // TODO read neuron traits - - NeuronGene t_neuron(static_cast(t_type), t_id, t_splity); - t_neuron.Init(t_a, t_b, t_timeconst, t_bias, static_cast(t_activationfunc)); - - m_NeuronGenes.push_back(t_neuron); - } - - if (t_Str == "Link") - { - int t_from, t_to, t_innov, t_isrecur; - double t_weight; - - a_DataFile >> t_from; - a_DataFile >> t_to; - a_DataFile >> t_innov; - a_DataFile >> t_isrecur; - a_DataFile >> t_weight; - - // TODO read link traits - - m_LinkGenes.push_back(LinkGene(t_from, t_to, t_innov, t_weight, static_cast(t_isrecur))); - } - } - while (t_Str != "GenomeEnd"); - - // Init additional stuff - // count inputs/outputs - m_NumInputs = 0; - m_NumOutputs = 0; - for (unsigned int i = 0; i < NumNeurons(); i++) - { - if ((m_NeuronGenes[i].Type() == INPUT) || (m_NeuronGenes[i].Type() == BIAS)) - { - m_NumInputs++; - } - - if (m_NeuronGenes[i].Type() == OUTPUT) - { - m_NumOutputs++; - } - } - - m_Fitness = 0.0; - m_AdjustedFitness = 0.0; - m_OffspringAmount = 0.0; - m_Depth = 0; - m_PhenotypeBehavior = NULL; - m_Evaluated = false; - } - - - // Saves this genome to a file - void Genome::Save(const char *a_FileName) - { - FILE *t_file; - t_file = fopen(a_FileName, "w"); - Save(t_file); - fclose(t_file); - } - - // Saves this genome to an already opened file for writing - void Genome::Save(FILE *a_file) - { - fprintf(a_file, "GenomeStart %d\n", GetID()); - - // loop over the neurons and save each one - for (unsigned int i = 0; i < NumNeurons(); i++) - { - // Save neuron - fprintf(a_file, "Neuron %d %d %3.8f %d %3.8f %3.8f %3.8f %3.8f\n", - m_NeuronGenes[i].ID(), static_cast(m_NeuronGenes[i].Type()), m_NeuronGenes[i].SplitY(), - static_cast(m_NeuronGenes[i].m_ActFunction), m_NeuronGenes[i].m_A, m_NeuronGenes[i].m_B, - m_NeuronGenes[i].m_TimeConstant, m_NeuronGenes[i].m_Bias); - // TODO write neuron traits - } - - // loop over the connections and save each one - for (unsigned int i = 0; i < NumLinks(); i++) - { - fprintf(a_file, "Link %d %d %d %d %3.8f\n", m_LinkGenes[i].FromNeuronID(), m_LinkGenes[i].ToNeuronID(), - m_LinkGenes[i].InnovationID(), static_cast(m_LinkGenes[i].IsRecurrent()), - m_LinkGenes[i].GetWeight()); - // TODO write link traits - } - - fprintf(a_file, "GenomeEnd\n\n"); - } - - void Genome::PrintTraits(std::map< std::string, Trait>& traits) - { - for(auto t = traits.begin(); t != traits.end(); t++) - { - bool doit = false; - std::string s = t->second.dep_key; - //std::string sv = bs::get(t->second.dep_values); - if (s != "") - { - // there is such trait.. - if (traits.count(s) != 0) - { - /*int a; double b; std::string c; - if ((*it).m_Traits[s].value.type() == typeid(int)) - a = bs::get((*it).m_Traits[s].value); - if ((*it).m_Traits[s].value.type() == typeid(double)) - b = bs::get((*it).m_Traits[s].value); - if ((*it).m_Traits[s].value.type() == typeid(std::string)) - c = bs::get((*it).m_Traits[s].value); - - int a1; double b1; std::string c1; - if ((t->second.dep_values).type() == typeid(int)) - a1 = bs::get((t->second.dep_values)); - if ((t->second.dep_values).type() == typeid(double)) - b1 = bs::get((t->second.dep_values)); - if ((t->second.dep_values).type() == typeid(std::string)) - c1 = bs::get((t->second.dep_values));*/ - - // and it has the right value? - for(int ix=0; ixsecond.dep_values.size(); ix++) - { - if (traits[s].value == (t->second.dep_values[ix])) - { - doit = true; - break; - } - } - } - } - else - { - doit = true; - } - - if (doit) - { - std::cout << t->first << " - "; - if (t->second.value.type() == typeid(int)) - { - std::cout << bs::get(t->second.value); - } - if (t->second.value.type() == typeid(double)) - { - std::cout << bs::get(t->second.value); - } - if (t->second.value.type() == typeid(std::string)) - { - std::cout << "\"" << bs::get(t->second.value) << "\""; - } - if (t->second.value.type() == typeid(intsetelement)) - { - std::cout << (bs::get(t->second.value)).value; - } - if (t->second.value.type() == typeid(floatsetelement)) - { - std::cout << (bs::get(t->second.value)).value; - } - - std::cout << ", "; - } - } - } - - void Genome::PrintAllTraits() - { - std::cout << "====================================================================\n"; - std::cout << "Genome:\n" - << "==================================\n"; - PrintTraits(m_GenomeGene.m_Traits); - - std::cout << "\n"; - - std::cout << "====================================================================\n"; - std::cout << "Neurons:\n" - << "==================================\n"; - for(auto it = m_NeuronGenes.begin(); it != m_NeuronGenes.end(); it++) - { - std::cout << "ID: " << it->ID() << " : "; - PrintTraits((*it).m_Traits); - - std::cout << "\n"; - } - std::cout << "==================================\n"; - - std::cout << "Links:\n" - << "==================================\n"; - for(auto it = m_LinkGenes.begin(); it != m_LinkGenes.end(); it++) - { - std::cout << "ID: " << it->InnovationID() << " : "; - PrintTraits((*it).m_Traits); - std::cout << "\n"; - } - std::cout << "==================================\n"; - std::cout << "====================================================================\n"; - } - - - //////////////////////////////////////////// - // Evovable Substrate Hyper NEAT. - // For more info on the algorithm check: http://eplex.cs.ucf.edu/ESHyperNEAT/ - //////////////////////////////////////////// - - - //divide and init for n dimensions - - void Genome::BuildESHyperNEATPhenotypeND(NeuralNetwork &net, Substrate &subst, Parameters ¶ms) - { - ASSERT(subst.m_input_coords.size() > 0); - ASSERT(subst.m_output_coords.size() > 0); - - unsigned int input_count = subst.m_input_coords.size(); - unsigned int output_count = subst.m_output_coords.size(); - unsigned int hidden_index = input_count + output_count; - unsigned int source_index = 0; - unsigned int target_index = 0; - unsigned int hidden_counter = 0; - unsigned int maxNodes = std::pow(4, params.MaxDepth); - unsigned int coord_len = subst.m_input_coords.at(0).size(); - std::vector TempConnections; - TempConnections.reserve(maxNodes + 1); - - std::vector point; - - point.reserve(coord_len); - - boost::shared_ptr root; - - boost::unordered_map, int> hidden_nodes; - hidden_nodes.reserve(maxNodes); - - boost::unordered_map, int> temp; - temp.reserve(maxNodes); - - boost::unordered_map, int> unexplored_nodes; - unexplored_nodes.reserve(maxNodes); - - net.m_neurons.reserve(maxNodes); - net.m_connections.reserve((maxNodes * (maxNodes - 1)) / 2); - net.SetInputOutputDimentions(static_cast(input_count), - static_cast(output_count)); - - - NeuralNetwork t_temp_phenotype(true); - BuildPhenotype(t_temp_phenotype); - - // Find Inputs to Hidden connections. - for (unsigned int i = 0; i < input_count; i++) - { - // Get the nTree - std::vector root_coord; - root_coord.reserve(coord_len); - for(unsigned int c_len = 0; c_len < coord_len; c_len++) - { - root_coord.push(0.0); - } - root = boost::shared_ptr( - new nTree(params.nTreeCoord, params.Width, params.Height, 1)); - DivideInitializeND(subst.m_input_coords[i], root, t_temp_phenotype, params, true, 0.0); - TempConnections.clear(); - PruneExpressND(subst.m_input_coords[i], root, t_temp_phenotype, params, TempConnections, true); - - for (unsigned int j = 0; j < TempConnections.size(); j++) - { - if (std::abs(TempConnections[j].weight * subst.m_max_weight_and_bias) < - 0.2/*subst.m_link_threshold*/) // TODO: fix this - continue; - - // Find the hidden node in the hidden nodes. If it is not there add it. - if (hidden_nodes.find(TempConnections[j].target) == hidden_nodes.end()) - { - target_index = hidden_counter++; - hidden_nodes.insert(std::make_pair(TempConnections[j].target, target_index)); - } - // Add connection - else - { - target_index = hidden_nodes.find(TempConnections[j].target)->second; - } - - Connection tc; - tc.m_source_neuron_idx = i; - tc.m_target_neuron_idx = target_index + hidden_index; - tc.m_weight = TempConnections[j].weight * subst.m_max_weight_and_bias; - tc.m_recur_flag = false; - - net.m_connections.push_back(tc); - - } - } - // Hidden to hidden. - // Basically the same procedure as above repeated IterationLevel times (see the params) - unexplored_nodes = hidden_nodes; - for (unsigned int i = 0; i < params.IterationLevel; i++) - { - boost::unordered_map, int>::iterator itr_hid; - for (itr_hid = unexplored_nodes.begin(); itr_hid != unexplored_nodes.end(); itr_hid++) - { - root = boost::shared_ptr( - new nTree(params.nTreeCoord, params.Width, params.Height, 1)); - DivideInitializeND(itr_hid->first, root, t_temp_phenotype, params, true, 0.0); - TempConnections.clear(); - PruneExpress(itr_hid->first, root, t_temp_phenotype, params, TempConnections, true); - //root.reset(); - - for (unsigned int k = 0; k < TempConnections.size(); k++) - { - if (std::abs(TempConnections[k].weight * subst.m_max_weight_and_bias) < - 0.2/*subst.m_link_threshold*/) // TODO: fix this - continue; - - if (hidden_nodes.find(TempConnections[k].target) == hidden_nodes.end()) - { - target_index = hidden_counter++; - hidden_nodes.insert(std::make_pair(TempConnections[k].target, target_index)); - } - else if(!params.feed_forward) // TODO: This can be skipped if building a feed forwad network. - { - target_index = hidden_nodes.find(TempConnections[k].target)->second; - } - - Connection tc; - tc.m_source_neuron_idx = itr_hid->second + hidden_index; // NO!!! - tc.m_target_neuron_idx = target_index + hidden_index; - tc.m_weight = TempConnections[k].weight * subst.m_max_weight_and_bias; - tc.m_recur_flag = false; - - net.m_connections.push_back(tc); - - } - } - // Now get the newly discovered hidden nodes - boost::unordered_map, int>::iterator itr1; - for (itr1 = hidden_nodes.begin(); itr1 != hidden_nodes.end(); itr1++) - { - if (unexplored_nodes.find(itr1->first) == unexplored_nodes.end()) - { - temp.insert(std::make_pair(itr1->first, itr1->second)); - } - } - unexplored_nodes = temp; - } - - // Finally Output to Hidden. Note that unlike before, here we connect the outputs to - // existing hidden nodes and no new nodes are added. - for (unsigned int i = 0; i < output_count; i++) - { - root = boost::shared_ptr( - new nTree(params.nTreeCoord, params.Width, params.Height, 1)); - DivideInitialize(subst.m_output_coords[i], root, t_temp_phenotype, params, false, 0.0); - TempConnections.clear(); - PruneExpress(subst.m_output_coords[i], root, t_temp_phenotype, params, TempConnections, false); - - for (unsigned int j = 0; j < TempConnections.size(); j++) - { - // Make sure the link weight is above the expected threshold. - if (std::abs(TempConnections[j].weight * subst.m_max_weight_and_bias) < - 0.2 /*subst.m_link_threshold*/) // TODO: fix this - continue; - - if (hidden_nodes.find(TempConnections[j].source) != hidden_nodes.end()) - { - source_index = hidden_nodes.find(TempConnections[j].source)->second; - - Connection tc; - tc.m_source_neuron_idx = source_index + hidden_index; - tc.m_target_neuron_idx = i + input_count; - - tc.m_weight = TempConnections[j].weight * subst.m_max_weight_and_bias; - tc.m_recur_flag = false; - - net.m_connections.push_back(tc); - } - } - } - // Add the neurons.Input first, followed by bias, output and hidden. In this order. - - for (unsigned int i = 0; i < input_count - 1; i++) - { - Neuron t_n; - t_n.m_a = 1; - t_n.m_b = 0; - t_n.m_substrate_coords = subst.m_input_coords[i]; - t_n.m_activation_function_type = NEAT::LINEAR; - t_n.m_type = NEAT::INPUT; - net.m_neurons.push_back(t_n); - } - // Bias n. - Neuron t_n; - t_n.m_a = 1; - t_n.m_b = 0; - t_n.m_substrate_coords = subst.m_input_coords[input_count - 1]; - t_n.m_activation_function_type = NEAT::LINEAR; - t_n.m_type = NEAT::BIAS; - net.m_neurons.push_back(t_n); - - for (unsigned int i = 0; i < output_count; i++) - { - Neuron t_n; - t_n.m_a = 1; - t_n.m_b = 0; - t_n.m_substrate_coords = subst.m_output_coords[i]; - t_n.m_activation_function_type = subst.m_output_nodes_activation; - t_n.m_type = NEAT::OUTPUT; - net.m_neurons.push_back(t_n); - } - - boost::unordered_map, int>::iterator itr; - for (itr = hidden_nodes.begin(); itr != hidden_nodes.end(); itr++) - { - Neuron t_n; - t_n.m_a = 1; - t_n.m_b = 0; - t_n.m_substrate_coords = itr->first; - - ASSERT(t_n.m_substrate_coords.size() > 0); // prevent 0D points - t_n.m_activation_function_type = subst.m_hidden_nodes_activation; - t_n.m_type = NEAT::HIDDEN; - net.m_neurons.push_back(t_n); - } - - // Clean the generated network from dangling connections and we're good to go. - Clean_Net(net.m_connections, input_count, output_count, hidden_nodes.size()); - } - - void Genome::BuildESHyperNEATPhenotype(NeuralNetwork &net, Substrate &subst, Parameters ¶ms) - { - ASSERT(subst.m_input_coords.size() > 0); - ASSERT(subst.m_output_coords.size() > 0); - - unsigned int input_count = subst.m_input_coords.size(); - unsigned int output_count = subst.m_output_coords.size(); - unsigned int hidden_index = input_count + output_count; - unsigned int source_index = 0; - unsigned int target_index = 0; - unsigned int hidden_counter = 0; - unsigned int maxNodes = std::pow(4, params.MaxDepth); - - std::vector TempConnections; - TempConnections.reserve(maxNodes + 1); - - std::vector point; - point.reserve(3); - - boost::shared_ptr root; - - boost::unordered_map, int> hidden_nodes; - hidden_nodes.reserve(maxNodes); - - boost::unordered_map, int> temp; - temp.reserve(maxNodes); - - boost::unordered_map, int> unexplored_nodes; - unexplored_nodes.reserve(maxNodes); - - net.m_neurons.reserve(maxNodes); - net.m_connections.reserve((maxNodes * (maxNodes - 1)) / 2); - net.SetInputOutputDimentions(static_cast(input_count), - static_cast(output_count)); - - - NeuralNetwork t_temp_phenotype(true); - BuildPhenotype(t_temp_phenotype); - - // Find Inputs to Hidden connections. - for (unsigned int i = 0; i < input_count; i++) - { - // Get the Quadtree and express the connections in it for this input - root = boost::shared_ptr( - new QuadPoint(params.Qtree_X, params.Qtree_Y, params.Width, params.Height, 1)); - DivideInitialize(subst.m_input_coords[i], root, t_temp_phenotype, params, true, 0.0); - TempConnections.clear(); - PruneExpress(subst.m_input_coords[i], root, t_temp_phenotype, params, TempConnections, true); - - for (unsigned int j = 0; j < TempConnections.size(); j++) - { - if (std::abs(TempConnections[j].weight * subst.m_max_weight_and_bias) < - 0.2/*subst.m_link_threshold*/) // TODO: fix this - continue; - - // Find the hidden node in the hidden nodes. If it is not there add it. - if (hidden_nodes.find(TempConnections[j].target) == hidden_nodes.end()) - { - target_index = hidden_counter++; - hidden_nodes.insert(std::make_pair(TempConnections[j].target, target_index)); - } - // Add connection - else - { - target_index = hidden_nodes.find(TempConnections[j].target)->second; - } - - Connection tc; - tc.m_source_neuron_idx = i; - tc.m_target_neuron_idx = target_index + hidden_index; - tc.m_weight = TempConnections[j].weight * subst.m_max_weight_and_bias; - tc.m_recur_flag = false; - - net.m_connections.push_back(tc); - - } - } - // Hidden to hidden. - // Basically the same procedure as above repeated IterationLevel times (see the params) - unexplored_nodes = hidden_nodes; - for (unsigned int i = 0; i < params.IterationLevel; i++) - { - boost::unordered_map, int>::iterator itr_hid; - for (itr_hid = unexplored_nodes.begin(); itr_hid != unexplored_nodes.end(); itr_hid++) - { - root = boost::shared_ptr( - new QuadPoint(params.Qtree_X, params.Qtree_Y, params.Width, params.Height, 1)); - DivideInitialize(itr_hid->first, root, t_temp_phenotype, params, true, 0.0); - TempConnections.clear(); - PruneExpress(itr_hid->first, root, t_temp_phenotype, params, TempConnections, true); - //root.reset(); - - for (unsigned int k = 0; k < TempConnections.size(); k++) - { - if (std::abs(TempConnections[k].weight * subst.m_max_weight_and_bias) < - 0.2/*subst.m_link_threshold*/) // TODO: fix this - continue; - - if (hidden_nodes.find(TempConnections[k].target) == hidden_nodes.end()) - { - target_index = hidden_counter++; - hidden_nodes.insert(std::make_pair(TempConnections[k].target, target_index)); - } - else // TODO: This can be skipped if building a feed forwad network. - { - target_index = hidden_nodes.find(TempConnections[k].target)->second; - } - - Connection tc; - tc.m_source_neuron_idx = itr_hid->second + hidden_index; // NO!!! - tc.m_target_neuron_idx = target_index + hidden_index; - tc.m_weight = TempConnections[k].weight * subst.m_max_weight_and_bias; - tc.m_recur_flag = false; - - net.m_connections.push_back(tc); - - } - } - // Now get the newly discovered hidden nodes - boost::unordered_map, int>::iterator itr1; - for (itr1 = hidden_nodes.begin(); itr1 != hidden_nodes.end(); itr1++) - { - if (unexplored_nodes.find(itr1->first) == unexplored_nodes.end()) - { - temp.insert(std::make_pair(itr1->first, itr1->second)); - } - } - unexplored_nodes = temp; - } - - // Finally Output to Hidden. Note that unlike before, here we connect the outputs to - // existing hidden nodes and no new nodes are added. - for (unsigned int i = 0; i < output_count; i++) - { - root = boost::shared_ptr( - new QuadPoint(params.Qtree_X, params.Qtree_Y, params.Width, params.Height, 1)); - DivideInitialize(subst.m_output_coords[i], root, t_temp_phenotype, params, false, 0.0); - TempConnections.clear(); - PruneExpress(subst.m_output_coords[i], root, t_temp_phenotype, params, TempConnections, false); - - for (unsigned int j = 0; j < TempConnections.size(); j++) - { - // Make sure the link weight is above the expected threshold. - if (std::abs(TempConnections[j].weight * subst.m_max_weight_and_bias) < - 0.2 /*subst.m_link_threshold*/) // TODO: fix this - continue; - - if (hidden_nodes.find(TempConnections[j].source) != hidden_nodes.end()) - { - source_index = hidden_nodes.find(TempConnections[j].source)->second; - - Connection tc; - tc.m_source_neuron_idx = source_index + hidden_index; - tc.m_target_neuron_idx = i + input_count; - - tc.m_weight = TempConnections[j].weight * subst.m_max_weight_and_bias; - tc.m_recur_flag = false; - - net.m_connections.push_back(tc); - } - } - } - // Add the neurons.Input first, followed by bias, output and hidden. In this order. - - for (unsigned int i = 0; i < input_count - 1; i++) - { - Neuron t_n; - t_n.m_a = 1; - t_n.m_b = 0; - t_n.m_substrate_coords = subst.m_input_coords[i]; - t_n.m_activation_function_type = NEAT::LINEAR; - t_n.m_type = NEAT::INPUT; - net.m_neurons.push_back(t_n); - } - // Bias n. - Neuron t_n; - t_n.m_a = 1; - t_n.m_b = 0; - t_n.m_substrate_coords = subst.m_input_coords[input_count - 1]; - t_n.m_activation_function_type = NEAT::LINEAR; - t_n.m_type = NEAT::BIAS; - net.m_neurons.push_back(t_n); - - for (unsigned int i = 0; i < output_count; i++) - { - Neuron t_n; - t_n.m_a = 1; - t_n.m_b = 0; - t_n.m_substrate_coords = subst.m_output_coords[i]; - t_n.m_activation_function_type = subst.m_output_nodes_activation; - t_n.m_type = NEAT::OUTPUT; - net.m_neurons.push_back(t_n); - } - - boost::unordered_map, int>::iterator itr; - for (itr = hidden_nodes.begin(); itr != hidden_nodes.end(); itr++) - { - Neuron t_n; - t_n.m_a = 1; - t_n.m_b = 0; - t_n.m_substrate_coords = itr->first; - - ASSERT(t_n.m_substrate_coords.size() > 0); // prevent 0D points - t_n.m_activation_function_type = subst.m_hidden_nodes_activation; - t_n.m_type = NEAT::HIDDEN; - net.m_neurons.push_back(t_n); - } - - // Clean the generated network from dangling connections and we're good to go. - Clean_Net(net.m_connections, input_count, output_count, hidden_nodes.size()); - } - // uses n dimensional sub division tree to determine placement of hidden nodes in the substrate - void Genome::DivideInitializeND(const std::vector &node, - boost::shared_ptr &root, - NeuralNetwork &cppn, - Parameters ¶ms, - const bool &outgoing) - { - int cpp_depth = 8; - - // some of the division, the permutation of center points in particular - // has been included with the tree struct - // and will simply be called here - std::vector t_inputs; - - boost::shared_ptr p; - std::queue > q; - q.push(p); - while(!q.empty()) - { - p = q.front(); - p.set_children(); - for (unsigned int i = 0; i < p->children.size(); i++) - { - t_inputs.clear(); - t_inputs.reserve(cppn.NumInputs()); - if(outgoing) - { - t_inputs = node; - for(unsigned int ci = 0; ci < node.size(); i++) - { - t_inputs.push_back(p->children[i]->coord[ci]); - } - } - else - { - t_inputs = p->children[i]->coord; - for(unsigned int ci = 0; ci < node.size(); i++) - { - t_inputs.push_back(node[ci]); - } - } - t_inputs[t_inputs.size() - 1] = (params.CPPN_Bias); - cppn.Flush(); - cppn.Input(t_inputs); - - for (int d = 0; d < cppn_depth; d++) - { - cppn.Activate(); - } - p->children[i]->weight = cppn.Output()[0]; - if (params.Leo) - { - p->children[i]->leo = cppn.Output()[cppn.Output().size() - 1]; - } - cppn.Flush(); - - } - - if ((p->level < params.InitialDepth) || - ((p->level < params.MaxDepth) && Variance(p) > params.DivisionThreshold)) - { - for(unsigned int add_idx = 0; add_idx < p->children.size(); add_idx) - { - q.push(p->children[add_idx]); - } - } - q.pop(); - } - return; - - } - // Used to determine the placement of hidden neurons in the Evolvable Substrate. - void Genome::DivideInitialize(const std::vector &node, - boost::shared_ptr &root, - NeuralNetwork &cppn, - Parameters ¶ms, - const bool &outgoing, - const double &z_coord) - { // Have to check if this actually does something useful here - //CalculateDepth(); - int cppn_depth = 8;//GetDepth(); - - std::vector t_inputs; - - // Standard Tree stuff. Create children, check their output with the CPPN - // and if they have higher variance add them to their parent. Repeat with the children - // until maxDepth has been reached or if the variance isn't high enough. - boost::shared_ptr p; - - std::queue > q; - q.push(root); - while (!q.empty()) - { - p = q.front(); - // Add children - p->children.push_back(boost::shared_ptr( - new QuadPoint(p->x - p->width / 2, p->y - p->height / 2, p->width / 2, p->height / 2, - p->level + 1))); - p->children.push_back(boost::shared_ptr( - new QuadPoint(p->x - p->width / 2, p->y + p->height / 2, p->width / 2, p->height / 2, - p->level + 1))); - p->children.push_back(boost::shared_ptr( - new QuadPoint(p->x + p->width / 2, p->y + p->height / 2, p->width / 2, p->height / 2, - p->level + 1))); - p->children.push_back(boost::shared_ptr( - new QuadPoint(p->x + p->width / 2, p->y - p->height / 2, p->width / 2, p->height / 2, - p->level + 1))); - - for (unsigned int i = 0; i < p->children.size(); i++) - { - t_inputs.clear(); - t_inputs.reserve(cppn.NumInputs()); - - if (outgoing) - { - // node goes here - t_inputs = node; - - t_inputs.push_back(p->children[i]->x); - t_inputs.push_back(p->children[i]->y); - t_inputs.push_back(p->children[i]->z); - } - - else - { - // QuadPoint goes first - t_inputs.push_back(p->children[i]->x); - t_inputs.push_back(p->children[i]->y); - t_inputs.push_back(p->children[i]->z); - - t_inputs.push_back(node[0]); - t_inputs.push_back(node[1]); - t_inputs.push_back(node[2]); - } - - // Bias - t_inputs[t_inputs.size() - 1] = (params.CPPN_Bias); - - cppn.Flush(); - cppn.Input(t_inputs); - - for (int d = 0; d < cppn_depth; d++) - { - cppn.Activate(); - } - p->children[i]->weight = cppn.Output()[0]; - if (params.Leo) - { - p->children[i]->leo = cppn.Output()[cppn.Output().size() - 1]; - } - cppn.Flush(); - - } - - if ((p->level < params.InitialDepth) || - ((p->level < params.MaxDepth) && Variance(p) > params.DivisionThreshold)) - { - for (unsigned int i = 0; i < 4; i++) - { - q.push(p->children[i]); - } - } - q.pop(); - - } - - return; - } - - void Genome::PruneExpressND(const std::vector &node, - boost::shared_ptr &root, - NeuralNetwork &cppn, - Parameters ¶ms, - std::vector &connections, - const bool &outgoing) - { - if (root->children[0] == NULL) - { - return; - } - - else - { - for (unsigned int i = 0; i < root->children.size(); i++) - { - if(Variance(root->children[i]) > params.VarianceThreshold) - { - PruneExpressND(node, root->children[i], cppn, params, connections, outgoing); - } - - else if(!params.Leo || (params.Leo && root->children[i]->leo > params.LeoThreshold)) - { - int cpp_depth = 8; //seems to be hard coded across the codebase, seems like plenty of depth to me! - std::vector child_array; - for(unsigned int c_ix = 0; c_ix < root->children[i]->coord.size(); c_ix++) - { - std::vector full_in; - std::vector full_in2; - std::vector inputs2; - std::vector inputs; - int root_index = 0; - int sign = -1; - double dimen_split1 = root->children[i]->coord[c_ix] - root->width; - double dimen_split2 = root->children[i]->coord[c_ix] + root->width; - for(unsigned int c2_ix = 0; c2_ix < node.size(); c2_ix++) - { - if(c2_ix == c_ix) - { - inputs.append(root->children[i].coord.at(c2_ix)); - inputs2.append(root->children[i]->coord.at(c2_ix)); - } else { - inputs.append(dimen_split2); - inputs2.append(dimen_split1); - } - } - if(outgoing) - { - full_in = node; - full_in2 = full_in; - fulll_in.insert(full_in.end(), inputs.begin(), inputs.end()); - full_in2.insert(full_in2.end(), inputs2.begin(), inputs2.end()); - } - else - { - full_in2 = inputs2; - full_in = inputs; - full_in2.insert(full_in2.end(), node.begin(), node.end()); - full_in.insert(full_in.end(), node.begin(), node.end()); - } - full_in.push_back(params.CPPN_Bias); - full_in2.push_back(params.CPPN_Bias); - cppn.Inputs(full_in); - child_array.append(cppn.Activate()[0]); - for (int d = 0; d < cppn_depth; d++) - { - cppn.Activate(); - } - child_array.append(Abs(root->child[i]->weight - Output()[0])); - cppn.Flush(); - cppn.Inputs(full_in2); - child_array.append(cppn.Activate()[0]); - for (int d = 0; d < cppn_depth; d++) - { - cppn.Activate(); - } - child_array.append(Abs(root->child[i]->weight - Output()[0])); - } - double biggest_smallest = std::min(child_array[0], child_array[1]); - unsigned int pair_idx = 2; - while(pair_idx < child_array.size()/2) - { - unsigned int new_min = std::min(child_array[pair_idx], child_array[pair_idx + 1]); - if(new_min > biggest_smallest) - { - biggest_smallest = new_min; - } - pair_idx += 2; - } - if(biggest_smallest > params.BandThreshold) - { - if(outgoing) - { - TempConnection tc(node, root->children[i]->coord, root->children[i]->weight, node.size()); - } - else - { - TempConnection tc(root->children[i]->coord, node, root->children[i]->weight, node.size()); - } - connections.push_back(tc); - } - } - } - } - // We take the tree generated above and see which connections can be expressed on the basis of Variance threshold, - // Band threshold and LEO. - void Genome::PruneExpress(const std::vector &node, - boost::shared_ptr &root, - NeuralNetwork &cppn, - Parameters ¶ms, - std::vector &connections, - const bool &outgoing) - { - if (root->children[0] == NULL) - { - return; - } - - else - { - for (unsigned int i = 0; i < 4; i++) - { - if (Variance(root->children[i]) > params.VarianceThreshold) - { - PruneExpress(node, root->children[i], cppn, params, connections, outgoing); - } - - // Band Pruning phase. - // If LEO is turned off this should always happen. - // If it is not it should only happen if the LEO output is greater than a specified threshold - else if (!params.Leo || (params.Leo && root->children[i]->leo > params.LeoThreshold)) - { - //CalculateDepth(); - int cppn_depth = 8;//GetDepth(); - - double d_left, d_right, d_top, d_bottom; - std::vector inputs; - - int root_index = 0; - - if (outgoing) - { - inputs = node; - inputs.push_back(root->children[i]->x); - inputs.push_back(root->children[i]->y); - inputs.push_back(root->children[i]->z); - - root_index = node.size(); - } - - else - { - inputs.push_back(root->children[i]->x); - inputs.push_back(root->children[i]->y); - inputs.push_back(root->children[i]->z); - inputs.push_back(node[0]); - inputs.push_back(node[1]); - inputs.push_back(node[2]); - } - - // Left - inputs.push_back(params.CPPN_Bias); - inputs[root_index] -= root->width; - - cppn.Input(inputs); - - for (int d = 0; d < cppn_depth; d++) - { - cppn.Activate(); - } - - d_left = Abs(root->children[i]->weight - cppn.Output()[0]); - cppn.Flush(); - - // Right - inputs[root_index] += 2 * (root->width); - cppn.Input(inputs); - - for (int d = 0; d < cppn_depth; d++) - { - cppn.Activate(); - } - - d_right = Abs(root->children[i]->weight - cppn.Output()[0]); - cppn.Flush(); - - // Top - inputs[root_index] -= root->width; - inputs[root_index + 1] -= root->width; - cppn.Input(inputs); - - for (int d = 0; d < cppn_depth; d++) - { - cppn.Activate(); - } - - d_top = Abs(root->children[i]->weight - cppn.Output()[0]); - cppn.Flush(); - // Bottom - inputs[root_index + 1] += 2 * root->width; - cppn.Input(inputs); - - for (int d = 0; d < cppn_depth; d++) - { - cppn.Activate(); - } - - d_bottom = Abs(root->children[i]->weight - cppn.Output()[0]); - cppn.Flush(); - - if (std::max(std::min(d_top, d_bottom), std::min(d_left, d_right)) > params.BandThreshold) - { - Genome::TempConnection tc; - //Yeah its ugly - if (outgoing) - { - tc.source = node; - - tc.target.push_back(root->children[i]->x); - tc.target.push_back(root->children[i]->y); - tc.target.push_back(root->children[i]->z); - } - else - { - tc.source.push_back(root->children[i]->x); - tc.source.push_back(root->children[i]->y); - tc.source.push_back(root->children[i]->z); - - tc.target = node; - } - // Normalize - // TODO: Put in Parameters - tc.weight = root->children[i]->weight; - connections.push_back(tc); - } - } - } - } - return; - } - - double Genome::VarianceND(boost::shared_ptr &point){ - if(point->children.size() == 0){ - return 0.0; - } - - boost::accumulators::accumulator_set > acc; - for (unsigned int i = 0; i < point->children.size(); i++){ - acc(point->children[i]->weight);) - } - return boost::accumulators::variance(acc); - } - // Calculates the variance of a given Quadpoint. - // Maybe an alternative solution would be to add this in the Quadpoint const. - double Genome::Variance(boost::shared_ptr &point) - { - if (point->children.size() == 0) - { - return 0.0; - } - - boost::accumulators::accumulator_set > acc; - for (unsigned int i = 0; i < 4; i++) - { - acc(point->children[i]->weight); - } - - return boost::accumulators::variance(acc); - } - - // Helper method for Variance - void Genome::CollectValues(std::vector &vals, boost::shared_ptr &point) - { - //In theory we shouldn't get here at all. - if (point == NULL) - { - return; - } - - if (point->children.size() > 0) - { - for (unsigned int i = 0; i < 4; i++) - { - CollectValues(vals, point->children[i]); - } - } - - else - { // Here, Apparently it treats the point a if it is not initialized - vals.push_back(point->weight); - } - } - - - // Removes all the dangling connections. This still leaves the nodes though, - void Genome::Clean_Net(std::vector &connections, unsigned int input_count, - unsigned int output_count, unsigned int hidden_count) - { - bool loose_connections = true; - int node_count = input_count + output_count + hidden_count; - std::vector temp; - temp.reserve(connections.size()); - while (loose_connections) - { - std::vector hasOutgoing(node_count, false); - std::vector hasIncoming(node_count, false); - // Make sure inputs and outputs are covered. - for (unsigned int i = 0; i < output_count + input_count; i++) - { - hasOutgoing[i] = true; - hasIncoming[i] = true; - } - - // Move on to the nodes. - for (unsigned int i = 0; i < connections.size(); i++) - { - if (connections[i].m_source_neuron_idx != connections[i].m_target_neuron_idx) - { - hasOutgoing[connections[i].m_source_neuron_idx] = true; - hasIncoming[connections[i].m_target_neuron_idx] = true; - } - - } - - loose_connections = false; - - std::vector::iterator itr; - for (itr = connections.begin(); itr < connections.end();) - { - if (!hasOutgoing[itr->m_target_neuron_idx] || !hasIncoming[itr->m_source_neuron_idx]) - { - itr = connections.erase(itr); - if (!loose_connections) - { - loose_connections = true; - } - - } - else - { - itr++; - } - } - } - } - -} // namespace NEAT +/////////////////////////////////////////////////////////////////////////////////////////// +// MultiNEAT - Python/C++ NeuroEvolution of Augmenting Topologies Library +// +// Copyright (C) 2012 Peter Chervenski +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see < http://www.gnu.org/licenses/ >. +// +// Contact info: +// +// Peter Chervenski < spookey@abv.bg > +// Shane Ryan < shane.mcdonald.ryan@gmail.com > +/////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// File: Genome.cpp +// Description: Implementation of the Genome class. +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Genome.h" +#include "Random.h" +#include "Utils.h" +#include "Parameters.h" +#include "Assert.h" + +namespace NEAT +{ + + // forward + ActivationFunction GetRandomActivation( const Parameters &a_Parameters, RNG &a_RNG); + + // squared x + inline double sqr(double x) + { + return x * x; + } + + + // Create an empty genome + Genome::Genome() + { + m_ID = 0; + m_Fitness = 0; + m_Depth = 0; + m_LinkGenes.clear(); + m_NeuronGenes.clear(); + m_NumInputs = 0; + m_NumOutputs = 0; + m_AdjustedFitness = 0; + m_OffspringAmount = 0; + m_Evaluated = false; + m_PhenotypeBehavior = NULL; + m_initial_num_neurons = 0; + m_initial_num_links = 0; + } + + + // Copy constructor + Genome::Genome(const Genome &a_G) + { + m_ID = a_G.m_ID; + m_Depth = a_G.m_Depth; + m_NeuronGenes = a_G.m_NeuronGenes; + m_LinkGenes = a_G.m_LinkGenes; + m_GenomeGene = a_G.m_GenomeGene; + m_Fitness = a_G.m_Fitness; + m_NumInputs = a_G.m_NumInputs; + m_NumOutputs = a_G.m_NumOutputs; + m_AdjustedFitness = a_G.m_AdjustedFitness; + m_OffspringAmount = a_G.m_OffspringAmount; + m_Evaluated = a_G.m_Evaluated; + m_PhenotypeBehavior = a_G.m_PhenotypeBehavior; + m_initial_num_neurons = a_G.m_initial_num_neurons; + m_initial_num_links = a_G.m_initial_num_links; +#ifdef USE_BOOST_PYTHON + m_behavior = a_G.m_behavior; +#endif + } + + // assignment operator + Genome &Genome::operator=(const Genome &a_G) + { + // self assignment guard + if (this != &a_G) + { + m_ID = a_G.m_ID; + m_Depth = a_G.m_Depth; + m_NeuronGenes = a_G.m_NeuronGenes; + m_LinkGenes = a_G.m_LinkGenes; + m_GenomeGene = a_G.m_GenomeGene; + m_Fitness = a_G.m_Fitness; + m_AdjustedFitness = a_G.m_AdjustedFitness; + m_NumInputs = a_G.m_NumInputs; + m_NumOutputs = a_G.m_NumOutputs; + m_OffspringAmount = a_G.m_OffspringAmount; + m_Evaluated = a_G.m_Evaluated; + m_PhenotypeBehavior = a_G.m_PhenotypeBehavior; + m_initial_num_neurons = a_G.m_initial_num_neurons; + m_initial_num_links = a_G.m_initial_num_links; +#ifdef USE_BOOST_PYTHON + m_behavior = a_G.m_behavior; +#endif + } + + return *this; + } + + // New constructor that creates a fully-connected CTRNN + /* + Genome::Genome(int a_ID, + int a_NumInputs, + int a_NumHidden, // ignored for seed type == 0, specifies number of hidden units if seed type == 1 + int a_NumOutputs, ActivationFunction a_OutputActType, + ActivationFunction a_HiddenActType, + const Parameters &a_Parameters) + { + ASSERT((a_NumInputs > 1) && (a_NumOutputs > 0)); + RNG t_RNG; + t_RNG.TimeSeed(); + + m_ID = a_ID; + int t_innovnum = 1, t_nnum = 1; + + if (a_Parameters.DontUseBiasNeuron == false) + { + + // Create the input neurons. + // Warning! The last one is a bias! + // The order of the neurons is very important. It is the following: INPUTS, BIAS, OUTPUTS, HIDDEN ... (no limit) + for (unsigned int i = 0; i < (a_NumInputs - 1); i++) + { + NeuronGene n = NeuronGene(INPUT, t_nnum, 0.0); + // Initialize the traits + n.InitTraits(a_Parameters.NeuronTraits, t_RNG); + m_NeuronGenes.emplace_back(n); + t_nnum++; + } + // add the bias + NeuronGene n = NeuronGene(BIAS, t_nnum, 0.0); + // Initialize the traits + n.InitTraits(a_Parameters.NeuronTraits, t_RNG); + + m_NeuronGenes.emplace_back(n); + t_nnum++; + } + else + { + // Create the input neurons without marking the last node as bias. + // The order of the neurons is very important. It is the following: INPUTS, OUTPUTS, HIDDEN ... (no limit) + for (unsigned int i = 0; i < a_NumInputs; i++) + { + NeuronGene n = NeuronGene(INPUT, t_nnum, 0.0); + // Initialize the traits + n.InitTraits(a_Parameters.NeuronTraits, t_RNG); + + m_NeuronGenes.emplace_back(n); + t_nnum++; + } + } + + // now the outputs + for (unsigned int i = 0; i < (a_NumOutputs); i++) + { + NeuronGene t_ngene(OUTPUT, t_nnum, 1.0); + // Initialize the neuron gene's properties + t_ngene.Init((a_Parameters.MinActivationA + a_Parameters.MaxActivationA) / 2.0f, + (a_Parameters.MinActivationB + a_Parameters.MaxActivationB) / 2.0f, + (a_Parameters.MinNeuronTimeConstant + a_Parameters.MaxNeuronTimeConstant) / 2.0f, + (a_Parameters.MinNeuronBias + a_Parameters.MaxNeuronBias) / 2.0f, + a_OutputActType); + // Initialize the traits + t_ngene.InitTraits(a_Parameters.NeuronTraits, t_RNG); + + m_NeuronGenes.emplace_back(t_ngene); + t_nnum++; + } + + for (unsigned int i = 0; i < a_NumHidden; i++) + { + NeuronGene t_ngene(HIDDEN, t_nnum, 1.0); + // Initialize the neuron gene's properties + t_ngene.Init((a_Parameters.MinActivationA + a_Parameters.MaxActivationA) / 2.0f, + (a_Parameters.MinActivationB + a_Parameters.MaxActivationB) / 2.0f, + (a_Parameters.MinNeuronTimeConstant + a_Parameters.MaxNeuronTimeConstant) / 2.0f, + (a_Parameters.MinNeuronBias + a_Parameters.MaxNeuronBias) / 2.0f, + a_HiddenActType); + // Initialize the traits + t_ngene.InitTraits(a_Parameters.NeuronTraits, t_RNG); + t_ngene.m_SplitY = 0.5; + + m_NeuronGenes.emplace_back(t_ngene); + t_nnum++; + } + + // Fully connect every neuron to every other. Only inputs don't receive output. + for (unsigned int i = a_NumInputs; i < (a_NumInputs+a_NumOutputs+a_NumHidden); i++) + { + for (unsigned int j = 0; j < (a_NumInputs+a_NumOutputs+a_NumHidden); j++) + { + // add the link + // created with zero weights. needs future random initialization. !!!!!!!! + LinkGene l = LinkGene(j + 1, i + 1, t_innovnum, 0.0, false); + l.InitTraits(a_Parameters.LinkTraits, t_RNG); + m_LinkGenes.emplace_back(l); + t_innovnum++; + } + } + + // Also initialize the Genome's traits + m_GenomeGene.InitTraits(a_Parameters.GenomeTraits, t_RNG); + + m_Evaluated = false; + m_NumInputs = a_NumInputs; + m_NumOutputs = a_NumOutputs; + m_Fitness = 0.0; + m_AdjustedFitness = 0.0; + m_OffspringAmount = 0.0; + m_Depth = 0; + m_PhenotypeBehavior = NULL; + + m_initial_num_neurons = NumNeurons(); + m_initial_num_links = NumLinks(); + }*/ + + Genome::Genome(const Parameters &a_Parameters, + const GenomeInitStruct &in + ) + { + ASSERT((a_NumInputs > 1) && (a_NumOutputs > 0)); + RNG t_RNG; + t_RNG.TimeSeed(); + + m_ID = 0; + int t_innovnum = 1, t_nnum = 1; + GenomeSeedType seed_type = in.SeedType; + + // override seed_type if 0 hidden units are specified + if ((seed_type == LAYERED) && (in.NumHidden == 0)) + { + seed_type = PERCEPTRON; + } + + if (a_Parameters.DontUseBiasNeuron == false) + { + + // Create the input neurons. + // Warning! The last one is a bias! + // The order of the neurons is very important. It is the following: INPUTS, BIAS, OUTPUTS, HIDDEN ... (no limit) + for (unsigned int i = 0; i < (in.NumInputs - 1); i++) + { + NeuronGene n = NeuronGene(INPUT, t_nnum, 0.0); + // Initialize the traits + //n.InitTraits(a_Parameters.NeuronTraits, t_RNG); // no need to init traits for inputs + m_NeuronGenes.emplace_back(n); + t_nnum++; + } + // add the bias + NeuronGene n = NeuronGene(BIAS, t_nnum, 0.0); + // Initialize the traits + //n.InitTraits(a_Parameters.NeuronTraits, t_RNG); // no need to init traits for inputs + + m_NeuronGenes.emplace_back(n); + t_nnum++; + } + else + { + // Create the input neurons without marking the last node as bias. + // The order of the neurons is very important. It is the following: INPUTS, OUTPUTS, HIDDEN ... (no limit) + for (unsigned int i = 0; i < in.NumInputs; i++) + { + NeuronGene n = NeuronGene(INPUT, t_nnum, 0.0); + // Initialize the traits + //n.InitTraits(a_Parameters.NeuronTraits, t_RNG); // no need to init traits for inputs + + m_NeuronGenes.emplace_back(n); + t_nnum++; + } + } + + // now the outputs + for (unsigned int i = 0; i < (in.NumOutputs); i++) + { + NeuronGene t_ngene(OUTPUT, t_nnum, 1.0); + // Initialize the neuron gene's properties + t_ngene.Init((a_Parameters.MinActivationA + a_Parameters.MaxActivationA) / 2.0f, + (a_Parameters.MinActivationB + a_Parameters.MaxActivationB) / 2.0f, + (a_Parameters.MinNeuronTimeConstant + a_Parameters.MaxNeuronTimeConstant) / 2.0f, + (a_Parameters.MinNeuronBias + a_Parameters.MaxNeuronBias) / 2.0f, + in.OutputActType); + // Initialize the traits + t_ngene.InitTraits(a_Parameters.NeuronTraits, t_RNG); + + m_NeuronGenes.emplace_back(t_ngene); + t_nnum++; + } + + // Now add LEO + /*if (a_Parameters.Leo) + { + NeuronGene t_ngene(OUTPUT, t_nnum, 1.0); + // Initialize the neuron gene's properties + t_ngene.Init((a_Parameters.MinActivationA + a_Parameters.MaxActivationA) / 2.0f, + (a_Parameters.MinActivationB + a_Parameters.MaxActivationB) / 2.0f, + (a_Parameters.MinNeuronTimeConstant + a_Parameters.MaxNeuronTimeConstant) / 2.0f, + (a_Parameters.MinNeuronBias + a_Parameters.MaxNeuronBias) / 2.0f, + UNSIGNED_STEP); + // Initialize the traits + t_ngene.InitTraits(a_Parameters.NeuronTraits, t_RNG); + + m_NeuronGenes.emplace_back(t_ngene); + t_nnum++; + in.NumOutputs++; + }*/ + + // add and connect hidden neurons if seed type is != 0 + if ((in.SeedType == LAYERED) && (in.NumHidden > 0)) + { + double lt_inc = 1.0 / (in.NumLayers+1); + double initlt = lt_inc; + for (unsigned int n = 0; n < in.NumLayers; n++) + { + for (unsigned int i = 0; i < in.NumHidden; i++) + { + NeuronGene t_ngene(HIDDEN, t_nnum, 1.0); + // Initialize the neuron gene's properties + t_ngene.Init((a_Parameters.MinActivationA + a_Parameters.MaxActivationA) / 2.0f, + (a_Parameters.MinActivationB + a_Parameters.MaxActivationB) / 2.0f, + (a_Parameters.MinNeuronTimeConstant + a_Parameters.MaxNeuronTimeConstant) / 2.0f, + (a_Parameters.MinNeuronBias + a_Parameters.MaxNeuronBias) / 2.0f, + in.HiddenActType); + // Initialize the traits + t_ngene.InitTraits(a_Parameters.NeuronTraits, t_RNG); + t_ngene.m_SplitY = initlt; + + m_NeuronGenes.emplace_back(t_ngene); + t_nnum++; + } + + initlt += lt_inc; + } + + if (!in.FS_NEAT) + { + int last_dest_id = in.NumInputs + in.NumOutputs + 1; + int last_src_id = 1; + int prev_layer_size = in.NumInputs; + + for (unsigned int n = 0; n < in.NumLayers; n++) + { + // The links from each previous layer to this hidden node + for (unsigned int i = 0; i < in.NumHidden; i++) + { + for (unsigned int j = 0; j < prev_layer_size; j++) + { + // add the link + // created with zero weights. needs future random initialization. !!!!!!!! + // init traits (TODO: maybe init empty traits?) + LinkGene l = LinkGene(j + last_src_id, i + last_dest_id, t_innovnum, 0.0, false); + l.InitTraits(a_Parameters.LinkTraits, t_RNG); + m_LinkGenes.emplace_back(l); + t_innovnum++; + } + } + + last_dest_id += in.NumHidden; + if (n == 0) + { + // for the first hidden layer, jump over the outputs too + last_src_id += prev_layer_size + in.NumOutputs; + } + else + { + last_src_id += prev_layer_size; + } + prev_layer_size = in.NumHidden; + } + + last_dest_id = in.NumInputs + 1; + + // The links from each previous layer to this output node + for (unsigned int i = 0; i < in.NumOutputs; i++) + { + for (unsigned int j = 0; j < prev_layer_size; j++) + { + // add the link + // created with zero weights. needs future random initialization. !!!!!!!! + // init traits (TODO: maybe init empty traits?) + LinkGene l = LinkGene(j + last_src_id, i + last_dest_id, t_innovnum, 0.0, false); + l.InitTraits(a_Parameters.LinkTraits, t_RNG); + m_LinkGenes.emplace_back(l); + t_innovnum++; + } + } + + /*if (a_Parameters.DontUseBiasNeuron == false) + { + // Connect the bias as well + for (unsigned int i = 0; i < a_NumOutputs; i++) + { + // add the link + // created with zero weights. needs future random initialization. !!!!!!!! + LinkGene l = LinkGene(a_NumInputs, i + last_dest_id, t_innovnum, 0.0, false); + l.InitTraits(a_Parameters.LinkTraits, t_RNG); + m_LinkGenes.emplace_back(l); + t_innovnum++; + } + }*/ + } + } + else // The links connecting every input to every output - perceptron structure + { + if ((!in.FS_NEAT) && (seed_type == PERCEPTRON)) + { + for (unsigned int i = 0; i < (in.NumOutputs); i++) + { + for (unsigned int j = 0; j < in.NumInputs; j++) + { + // add the link + // created with zero weights. needs future random initialization. !!!!!!!! + LinkGene l = LinkGene(j + 1, i + in.NumInputs + 1, t_innovnum, 0.0, false); + l.InitTraits(a_Parameters.LinkTraits, t_RNG); + m_LinkGenes.emplace_back(l); + t_innovnum++; + } + } + } + else + { + // Start very minimally - connect a random input to each output + // Also connect the bias to every output + + std::vector< std::pair > made_already; + bool there=false; + int linksmade = 0; + + // do this a few times for more initial links created + // TODO: make sure the innovations don't repeat for the same input/output pairs + while(linksmade < in.FS_NEAT_links) + { + for (unsigned int i = 0; i < in.NumOutputs; i++) + { + int t_inp_id = t_RNG.RandInt(1, in.NumInputs - 1); + int t_bias_id = in.NumInputs; + int t_outp_id = in.NumInputs + 1 + i; + + // check if there already + there=false; + for(auto it = made_already.begin(); it != made_already.end(); it++) + { + if ((it->first == t_inp_id) && (it->second == t_outp_id)) + { + there = true; + break; + } + } + + if (!there) + { + // created with zero weights. needs future random initialization. !!!!!!!! + LinkGene l = LinkGene(t_inp_id, t_outp_id, t_innovnum, 0.0, false); + l.InitTraits(a_Parameters.LinkTraits, t_RNG); + m_LinkGenes.emplace_back(l); + t_innovnum++; + + if (a_Parameters.DontUseBiasNeuron == false) + { + LinkGene bl = LinkGene(t_bias_id, t_outp_id, t_innovnum, 0.0, false); + bl.InitTraits(a_Parameters.LinkTraits, t_RNG); + m_LinkGenes.emplace_back(bl); + t_innovnum++; + } + + linksmade++; + made_already.push_back(std::make_pair(t_inp_id, t_outp_id)); + } + } + } + } + } + + if (in.FS_NEAT && (in.FS_NEAT_links==1)) + { + throw std::runtime_error("Known bug - don't use FS-NEAT with just 1 link and 1/1/1 genome"); + } + + // Also initialize the Genome's traits + m_GenomeGene.InitTraits(a_Parameters.GenomeTraits, t_RNG); + + m_Evaluated = false; + m_NumInputs = in.NumInputs; + m_NumOutputs = in.NumOutputs; + m_Fitness = 0.0; + m_AdjustedFitness = 0.0; + m_OffspringAmount = 0.0; + m_Depth = 0; + m_PhenotypeBehavior = NULL; + + m_initial_num_neurons = NumNeurons(); + m_initial_num_links = NumLinks(); + } + + void Genome::SetDepth(unsigned int a_d) + { + m_Depth = a_d; + } + + unsigned int Genome::GetDepth() const + { + return m_Depth; + } + + void Genome::SetID(int a_id) + { + m_ID = a_id; + } + + int Genome::GetID() const + { + return m_ID; + } + + void Genome::SetAdjFitness(double a_af) + { + m_AdjustedFitness = a_af; + } + + void Genome::SetFitness(double a_f) + { + m_Fitness = a_f; + } + + double Genome::GetAdjFitness() const + { + return m_AdjustedFitness; + } + + double Genome::GetFitness() const + { + return m_Fitness; + } + + void Genome::SetNeuronY(unsigned int a_idx, int a_y) + { + ASSERT(a_idx < m_NeuronGenes.size()); + m_NeuronGenes[a_idx].y = a_y; + } + + void Genome::SetNeuronX(unsigned int a_idx, int a_x) + { + ASSERT(a_idx < m_NeuronGenes.size()); + m_NeuronGenes[a_idx].x = a_x; + } + + void Genome::SetNeuronXY(unsigned int a_idx, int a_x, int a_y) + { + ASSERT(a_idx < m_NeuronGenes.size()); + m_NeuronGenes[a_idx].x = a_x; + m_NeuronGenes[a_idx].y = a_y; + } + + LinkGene Genome::GetLinkByIndex(int a_idx) const + { + ASSERT(a_idx < m_LinkGenes.size()); + return m_LinkGenes[a_idx]; + } + + LinkGene Genome::GetLinkByInnovID(int a_ID) const + { + ASSERT(HasLinkByInnovID(a_ID)); + for (unsigned int i = 0; i < m_LinkGenes.size(); i++) + if (m_LinkGenes[i].InnovationID() == a_ID) + return m_LinkGenes[i]; + + // should never reach this code + throw std::exception(); + } + + NeuronGene Genome::GetNeuronByIndex(int a_idx) const + { + ASSERT(a_idx < m_NeuronGenes.size()); + return m_NeuronGenes[a_idx]; + } + + NeuronGene Genome::GetNeuronByID(int a_ID) const + { + ASSERT(HasNeuronID(a_ID)); + int t_idx = GetNeuronIndex(a_ID); + ASSERT(t_idx != -1); + return m_NeuronGenes[t_idx]; + } + + double Genome::GetOffspringAmount() const + { + return m_OffspringAmount; + } + + void Genome::SetOffspringAmount(double a_oa) + { + m_OffspringAmount = a_oa; + } + + bool Genome::IsEvaluated() const + { + return m_Evaluated; + } + + void Genome::SetEvaluated() + { + m_Evaluated = true; + } + + void Genome::ResetEvaluated() + { + m_Evaluated = false; + } + + // A little helper function to find the index of a neuron, given its ID + // returns -1 if not found + int Genome::GetNeuronIndex(int a_ID) const + { + ASSERT(a_ID > 0); + + for (unsigned int i = 0; i < NumNeurons(); i++) + { + if (m_NeuronGenes[i].ID() == a_ID) + { + return i; + } + } + + return -1; + } + + // A little helper function to find the index of a link, given its innovation ID + // returns -1 if not found + int Genome::GetLinkIndex(int a_InnovID) const + { + ASSERT(a_InnovID > 0); + ASSERT(NumLinks() > 0); + + for (unsigned int i = 0; i < NumLinks(); i++) + { + if (m_LinkGenes[i].InnovationID() == a_InnovID) + { + return i; + } + } + + return -1; + } + + + // returns the max neuron ID + int Genome::GetLastNeuronID() const + { + ASSERT(NumNeurons() > 0); + + int t_maxid = 0; + + for (unsigned int i = 0; i < NumNeurons(); i++) + { + if (m_NeuronGenes[i].ID() > t_maxid) + t_maxid = m_NeuronGenes[i].ID(); + } + + return t_maxid + 1; + } + + // returns the max innovation Id + int Genome::GetLastInnovationID() const + { + ASSERT(NumLinks() > 0); + + int t_maxid = 0; + + for (unsigned int i = 0; i < NumLinks(); i++) + { + if (m_LinkGenes[i].InnovationID() > t_maxid) + t_maxid = m_LinkGenes[i].InnovationID(); + } + + return t_maxid + 1; + } + + // Returns true if the specified neuron ID is present in the genome + bool Genome::HasNeuronID(int a_ID) const + { + ASSERT(a_ID > 0); + ASSERT(NumNeurons() > 0); + + for (unsigned int i = 0; i < NumNeurons(); i++) + { + if (m_NeuronGenes[i].ID() == a_ID) + { + return true; + } + } + + return false; + } + + + // Returns true if the specified link is present in the genome + bool Genome::HasLink(int a_n1id, int a_n2id) const + { + ASSERT((a_n1id > 0) && (a_n2id > 0)); + + for (unsigned int i = 0; i < NumLinks(); i++) + { + if ((m_LinkGenes[i].FromNeuronID() == a_n1id) && (m_LinkGenes[i].ToNeuronID() == a_n2id)) + { + return true; + } + } + + return false; + } + + bool Genome::HasLoops() + { + NeuralNetwork net; + BuildPhenotype(net); + bool has_cycles = false; + + // convert the net to a Boost::Graph object + Graph g; + for (int i = 0; i < net.m_connections.size(); i++) + { + bs::add_edge(net.m_connections[i].m_source_neuron_idx, net.m_connections[i].m_target_neuron_idx, g); + } + + typedef std::vector container; + container c; + try + { + bs::topological_sort(g, std::back_inserter(c)); + } + catch (bs::not_a_dag) + { + has_cycles = true; + } + + return has_cycles; + } + + // Returns true if the specified link is present in the genome + bool Genome::HasLinkByInnovID(int id) const + { + ASSERT(id > 0); + + for (unsigned int i = 0; i < NumLinks(); i++) + { + if (m_LinkGenes[i].InnovationID() == id) + { + return true; + } + } + + return false; + } + + + // This builds a fastnetwork structure out from the genome + void Genome::BuildPhenotype(NeuralNetwork &a_Net) + { + // first clear out the network + a_Net.Clear(); + a_Net.SetInputOutputDimentions(m_NumInputs, m_NumOutputs); + + // Fill the net with the neurons + for (unsigned int i = 0; i < NumNeurons(); i++) + { + Neuron t_n; + + t_n.m_a = m_NeuronGenes[i].m_A; + t_n.m_b = m_NeuronGenes[i].m_B; + t_n.m_timeconst = m_NeuronGenes[i].m_TimeConstant; + t_n.m_bias = m_NeuronGenes[i].m_Bias; + t_n.m_activation_function_type = m_NeuronGenes[i].m_ActFunction; + t_n.m_split_y = m_NeuronGenes[i].SplitY(); + t_n.m_type = m_NeuronGenes[i].Type(); + + a_Net.AddNeuron(t_n); + } + + // Fill the net with the connections + for (unsigned int i = 0; i < NumLinks(); i++) + { + Connection t_c; + + t_c.m_source_neuron_idx = GetNeuronIndex(m_LinkGenes[i].FromNeuronID()); + t_c.m_target_neuron_idx = GetNeuronIndex(m_LinkGenes[i].ToNeuronID()); + t_c.m_weight = m_LinkGenes[i].GetWeight(); + t_c.m_recur_flag = m_LinkGenes[i].IsRecurrent(); + + ////////////////////// + // default values + t_c.m_hebb_rate = 0.3; + t_c.m_hebb_pre_rate = 0.1; + + // if a float trait "hebb_rate" exists + if (m_LinkGenes[i].m_Traits.count("hebb_rate") == 1) + { + try + { + t_c.m_hebb_rate = boost::get(m_LinkGenes[i].m_Traits["hebb_rate"].value); + } + catch(std::exception e) + { + // do nothing + } + } + // if a float trait "hebb_pre_rate" exists + if (m_LinkGenes[i].m_Traits.count("hebb_pre_rate") == 1) + { + try + { + t_c.m_hebb_pre_rate = boost::get(m_LinkGenes[i].m_Traits["hebb_pre_rate"].value); + } + catch(std::exception e) + { + // do nothing + } + } + + ////////////////////// + + a_Net.AddConnection(t_c); + } + + a_Net.Flush(); + + // Note however that the RTRL variables are not initialized. + // The user must manually call the InitRTRLMatrix() method to do it. + // This is because of storage issues. RTRL need not to be used every time. + } + + + // Builds a HyperNEAT phenotype based on the substrate + // The CPPN input dimensionality must match the largest number of + // dimensions in the substrate + // The output dimensionality is determined according to flags set in the + // substrate + + // The procedure uses the [0] CPPN output for creating nodes, and if the substrate is leaky, [1] and [2] for time constants and biases + // Also assumes the CPPN uses signed activation outputs + void Genome::BuildHyperNEATPhenotype(NeuralNetwork &net, Substrate &subst) + { + // We need a substrate with at least one input and output + ASSERT(subst.m_input_coords.size() > 0); + ASSERT(subst.m_output_coords.size() > 0); + + int max_dims = subst.GetMaxDims(); + + // Make sure the CPPN dimensionality is right + ASSERT(subst.GetMinCPPNInputs() > 0); + ASSERT(NumInputs() >= subst.GetMinCPPNInputs()); + ASSERT(NumOutputs() >= subst.GetMinCPPNOutputs()); + if (subst.m_leaky) + { + ASSERT(NumOutputs() >= subst.GetMinCPPNOutputs()); + } + + // Now we create the substrate (net) + net.SetInputOutputDimentions(static_cast(subst.m_input_coords.size()), + static_cast(subst.m_output_coords.size())); + + // Inputs + for (unsigned int i = 0; i < subst.m_input_coords.size(); i++) + { + Neuron t_n; + + t_n.m_a = 1; + t_n.m_b = 0; + t_n.m_substrate_coords = subst.m_input_coords[i]; + ASSERT(t_n.m_substrate_coords.size() > 0); // prevent 0D points + t_n.m_activation_function_type = NEAT::LINEAR; + t_n.m_type = NEAT::INPUT; + + net.AddNeuron(t_n); + } + + // Output + for (unsigned int i = 0; i < subst.m_output_coords.size(); i++) + { + Neuron t_n; + + t_n.m_a = 1; + t_n.m_b = 0; + t_n.m_substrate_coords = subst.m_output_coords[i]; + ASSERT(t_n.m_substrate_coords.size() > 0); // prevent 0D points + t_n.m_activation_function_type = subst.m_output_nodes_activation; + t_n.m_type = NEAT::OUTPUT; + + net.AddNeuron(t_n); + } + + // Hidden + for (unsigned int i = 0; i < subst.m_hidden_coords.size(); i++) + { + Neuron t_n; + + t_n.m_a = 1; + t_n.m_b = 0; + t_n.m_substrate_coords = subst.m_hidden_coords[i]; + ASSERT(t_n.m_substrate_coords.size() > 0); // prevent 0D points + t_n.m_activation_function_type = subst.m_hidden_nodes_activation; + t_n.m_type = NEAT::HIDDEN; + + net.AddNeuron(t_n); + } + + // Begin querying the CPPN + // Create the neural network that will represent the CPPN + NeuralNetwork t_temp_phenotype(true); + BuildPhenotype(t_temp_phenotype); + t_temp_phenotype.Flush(); + + // To ensure network relaxation + int dp = 8; + if (!HasLoops()) + { + CalculateDepth(); + dp = GetDepth(); + } + + // now loop over every potential connection in the substrate and take its weight + + // For leaky substrates, first loop over the neurons and set their properties + if (subst.m_leaky) + { + for (unsigned int i = net.NumInputs(); i < net.m_neurons.size(); i++) + { + // neuron specific stuff + t_temp_phenotype.Flush(); + + // Inputs for the generation of time consts and biases across + // the nodes in the substrate + // We input only the position of the first node and ignore the other one + std::vector t_inputs; + t_inputs.resize(NumInputs()); + + for (unsigned int n = 0; n < net.m_neurons[i].m_substrate_coords.size(); n++) + { + t_inputs[n] = net.m_neurons[i].m_substrate_coords[n]; + } + + if (subst.m_with_distance) + { + // compute the Eucledian distance between the point and the origin + double sum = 0; + for (int n = 0; n < max_dims; n++) + { + sum += sqr(t_inputs[n]); + } + sum = sqrt(sum); + t_inputs[NumInputs() - 2] = sum; + } + t_inputs[NumInputs() - 1] = 1.0; // the CPPN's bias + + t_temp_phenotype.Input(t_inputs); + + // activate as many times as deep + for (int d = 0; d < dp; d++) + { + t_temp_phenotype.Activate(); + } + + double t_tc = t_temp_phenotype.Output()[NumOutputs() - 2]; + double t_bias = t_temp_phenotype.Output()[NumOutputs() - 1]; + + Clamp(t_tc, -1, 1); + Clamp(t_bias, -1, 1); + + // rescale the values + Scale(t_tc, -1, 1, subst.m_min_time_const, subst.m_max_time_const); + Scale(t_bias, -1, 1, -subst.m_max_weight_and_bias, subst.m_max_weight_and_bias); + + net.m_neurons[i].m_timeconst = t_tc; + net.m_neurons[i].m_bias = t_bias; + } + } + + // list of src_idx, dst_idx pairs of all connections to query + std::vector > t_to_query; + + // There isn't custom connectiviy scheme? + if (subst.m_custom_connectivity.size() == 0) + { + // only incoming connections, so loop only the hidden and output neurons + for (int i = net.NumInputs(); i < net.m_neurons.size(); i++) + { + // loop all neurons + for (int j = 0; j < net.m_neurons.size(); j++) + { + // this is connection "j" to "i" + + // conditions for canceling the CPPN query + if ( + ((!subst.m_allow_input_hidden_links) && + ((net.m_neurons[j].m_type == INPUT) && (net.m_neurons[i].m_type == HIDDEN))) + + || ((!subst.m_allow_input_output_links) && + ((net.m_neurons[j].m_type == INPUT) && (net.m_neurons[i].m_type == OUTPUT))) + + || ((!subst.m_allow_hidden_hidden_links) && + ((net.m_neurons[j].m_type == HIDDEN) && (net.m_neurons[i].m_type == HIDDEN) && + (i != j))) + + || ((!subst.m_allow_hidden_output_links) && + ((net.m_neurons[j].m_type == HIDDEN) && (net.m_neurons[i].m_type == OUTPUT))) + + || ((!subst.m_allow_output_hidden_links) && + ((net.m_neurons[j].m_type == OUTPUT) && (net.m_neurons[i].m_type == HIDDEN))) + + || ((!subst.m_allow_output_output_links) && + ((net.m_neurons[j].m_type == OUTPUT) && (net.m_neurons[i].m_type == OUTPUT) && + (i != j))) + + || ((!subst.m_allow_looped_hidden_links) && + ((net.m_neurons[j].m_type == HIDDEN) && (net.m_neurons[i].m_type == HIDDEN) && + (i == j))) + + || ((!subst.m_allow_looped_output_links) && + ((net.m_neurons[j].m_type == OUTPUT) && (net.m_neurons[i].m_type == OUTPUT) && + (i == j))) + + ) + { + continue; + } + + // Save potential link to query + std::vector t_link; + t_link.emplace_back(j); + t_link.emplace_back(i); + t_to_query.emplace_back(t_link); + } + } + } + else + { + // use the custom connectivity + for (unsigned int idx = 0; idx < subst.m_custom_connectivity.size(); idx++) + { + NeuronType src_type = (NeuronType) subst.m_custom_connectivity[idx][0]; + int src_idx = subst.m_custom_connectivity[idx][1]; + NeuronType dst_type = (NeuronType) subst.m_custom_connectivity[idx][2]; + int dst_idx = subst.m_custom_connectivity[idx][3]; + + // determine the indices in the NN + int j = 0; // src + int i = 0; // dst + + if ((src_type == INPUT) || (src_type == BIAS)) + { + j = src_idx; + } + else if (src_type == HIDDEN) + { + j = subst.m_input_coords.size() + subst.m_output_coords.size() + src_idx; + } + else if (src_type == OUTPUT) + { + j = subst.m_input_coords.size() + src_idx; + } + + + if ((dst_type == INPUT) || (dst_type == BIAS)) + { + i = dst_idx; + } + else if (dst_type == HIDDEN) + { + i = subst.m_input_coords.size() + subst.m_output_coords.size() + dst_idx; + } + else if (dst_type == OUTPUT) + { + i = subst.m_input_coords.size() + dst_idx; + } + + // conditions for canceling the CPPN query + if (subst.m_custom_conn_obeys_flags && ( + ((!subst.m_allow_input_hidden_links) && + ((net.m_neurons[j].m_type == INPUT) && (net.m_neurons[i].m_type == HIDDEN))) + + || ((!subst.m_allow_input_output_links) && + ((net.m_neurons[j].m_type == INPUT) && (net.m_neurons[i].m_type == OUTPUT))) + + || ((!subst.m_allow_hidden_hidden_links) && + ((net.m_neurons[j].m_type == HIDDEN) && (net.m_neurons[i].m_type == HIDDEN) && (i != j))) + + || ((!subst.m_allow_hidden_output_links) && + ((net.m_neurons[j].m_type == HIDDEN) && (net.m_neurons[i].m_type == OUTPUT))) + + || ((!subst.m_allow_output_hidden_links) && + ((net.m_neurons[j].m_type == OUTPUT) && (net.m_neurons[i].m_type == HIDDEN))) + + || ((!subst.m_allow_output_output_links) && + ((net.m_neurons[j].m_type == OUTPUT) && (net.m_neurons[i].m_type == OUTPUT) && (i != j))) + + || ((!subst.m_allow_looped_hidden_links) && + ((net.m_neurons[j].m_type == HIDDEN) && (net.m_neurons[i].m_type == HIDDEN) && (i == j))) + + || ((!subst.m_allow_looped_output_links) && + ((net.m_neurons[j].m_type == OUTPUT) && (net.m_neurons[i].m_type == OUTPUT) && (i == j))) + ) + ) + { + continue; + } + + // Save potential link to query + std::vector t_link; + t_link.emplace_back(j); + t_link.emplace_back(i); + t_to_query.emplace_back(t_link); + } + } + + + // Query and create all links + for (unsigned int conn = 0; conn < t_to_query.size(); conn++) + { + int j = t_to_query[conn][0]; + int i = t_to_query[conn][1]; + + // Take the weight of this connection by querying the CPPN + // as many times as deep (recurrent or looped CPPNs may be very slow!!!*) + std::vector t_inputs; + t_inputs.resize(NumInputs()); + + int from_dims = net.m_neurons[j].m_substrate_coords.size(); + int to_dims = net.m_neurons[i].m_substrate_coords.size(); + + // input the node positions to the CPPN + // from + for (int n = 0; n < from_dims; n++) + { + t_inputs[n] = net.m_neurons[j].m_substrate_coords[n]; + } + // to + for (int n = 0; n < to_dims; n++) + { + t_inputs[max_dims + n] = net.m_neurons[i].m_substrate_coords[n]; + } + + // the input is like + // x000|xx00|1 - 1D -> 2D connection + // xx00|xx00|1 - 2D -> 2D connection + // xx00|xxx0|1 - 2D -> 3D connection + // if max_dims is 4 and no distance input + + if (subst.m_with_distance) + { + // compute the Eucledian distance between the two points + // differing dimensionality doesn't matter as the extra dimensions are 0s + double sum = 0; + for (int n = 0; n < max_dims; n++) + { + sum += sqr(t_inputs[n] - t_inputs[max_dims + n]); + } + sum = sqrt(sum); + + t_inputs[NumInputs() - 2] = sum; + } + + t_inputs[NumInputs() - 1] = 1.0; + + + // flush between each query + t_temp_phenotype.Flush(); + t_temp_phenotype.Input(t_inputs); + + // activate as many times as deep + for (int d = 0; d < dp; d++) + { + t_temp_phenotype.Activate(); + } + + // the output is a weight + double t_link = 0; + double t_weight = 0; + + if (subst.m_query_weights_only) + { + t_weight = t_temp_phenotype.Output()[0]; + } + else + { + t_link = t_temp_phenotype.Output()[0]; + t_weight = t_temp_phenotype.Output()[1]; + } + + if (((t_link > 0) && (!subst.m_query_weights_only)) || (subst.m_query_weights_only)) + { + // now this weight will be scaled + t_weight *= subst.m_max_weight_and_bias; + + // build the connection + Connection t_c; + + t_c.m_source_neuron_idx = j; + t_c.m_target_neuron_idx = i; + t_c.m_weight = t_weight; + t_c.m_recur_flag = false; + + net.AddConnection(t_c); + } + } + } + + + // Projects the weight changes of a phenotype back to the genome. + // WARNING! Using this too often in conjuction with RTRL can confuse evolution. + void Genome::DerivePhenotypicChanges(NeuralNetwork &a_Net) + { + // the a_Net and the genome must have identical topology. + // if the topology differs, no changes will be made to the genome + + // Since we don't have a comparison operator yet, we are going to assume + // identical topolgy + // TODO: create that comparison operator for NeuralNetworks + + // Iterate through the links and replace weights + for (unsigned int i = 0; i < NumLinks(); i++) + { + m_LinkGenes[i].SetWeight(a_Net.GetConnectionByIndex(i).m_weight); + } + + // TODO: if neuron parameters were changed, derive them + // * in future expansions + } + + //std::map, double> distance_cache; + + // Returns the absolute distance between this genome and a_G + double Genome::CompatibilityDistance(Genome &a_G, Parameters &a_Parameters) + { + // first check if in cache, if so, return that + /*auto q1 = std::make_pair(this->GetID(), a_G.GetID()); + auto q2 = std::make_pair(a_G.GetID(), this->GetID()); + if (distance_cache.count(q1) > 0) + { + return distance_cache[q1]; + } + else if (distance_cache.count(q2) > 0) + { + return distance_cache[q2]; + }*/ + + // New - if there is a behavior in the genomes, return their distance +#ifdef USE_BOOST_PYTHON + // is it not None? + if ((m_behavior.ptr() != py::object().ptr()) && (a_G.m_behavior.ptr() != py::object().ptr())) + { + return py::extract(m_behavior.attr("distance_to")(a_G.m_behavior)); + } +#endif + + + // iterators for moving through the genomes' genes + std::vector::iterator t_g1; + std::vector::iterator t_g2; + + // this variable is the total distance between the genomes + // if it passes beyond the compatibility treshold, the function returns false + double t_total_distance = 0.0; + + double t_total_weight_difference = 0.0; + double t_total_timeconstant_difference = 0.0; + double t_total_bias_difference = 0.0; + double t_total_A_difference = 0.0; + double t_total_B_difference = 0.0; + double t_total_num_activation_difference = 0.0; + std::map t_total_neuron_trait_difference; + std::map t_total_link_trait_difference; + std::map t_genome_link_trait_difference; + + // count of matching genes + double t_num_excess = 0; + double t_num_disjoint = 0; + double t_num_matching_links = 0; + double t_num_matching_neurons = 0; + + // calculate genome trait difference here + t_genome_link_trait_difference = m_GenomeGene.GetTraitDistances(a_G.m_GenomeGene.m_Traits); + + // used for percentage of excess/disjoint genes calculation + int t_max_genome_size = static_cast (NumLinks() < a_G.NumLinks()) ? (a_G.NumLinks()) : (NumLinks()); + int t_max_neurons = static_cast (NumNeurons() < a_G.NumNeurons()) ? (a_G.NumNeurons()) : (NumNeurons()); + + t_g1 = m_LinkGenes.begin(); + t_g2 = a_G.m_LinkGenes.begin(); + + // Step through the genes until both genomes end + while (!((t_g1 == m_LinkGenes.end()) && ((t_g2 == a_G.m_LinkGenes.end())))) + { + // end of first genome? + if (t_g1 == m_LinkGenes.end()) + { + // add to the total distance + t_num_excess++; + t_g2++; + } + else if (t_g2 == a_G.m_LinkGenes.end()) + // end of second genome? + { + // add to the total distance + t_num_excess++; + t_g1++; + } + else + { + // extract the innovation numbers + int t_g1innov = t_g1->InnovationID(); + int t_g2innov = t_g2->InnovationID(); + + // matching genes? + if (t_g1innov == t_g2innov) + { + t_num_matching_links++; + + if (a_Parameters.WeightDiffCoeff > 0.0) + { + double t_wdiff = (t_g1->GetWeight() - t_g2->GetWeight()); + if (t_wdiff < 0) t_wdiff = -t_wdiff; // make sure it is positive + t_total_weight_difference += t_wdiff; + } + + // calculate link trait difference here + std::map link_trait_difference = t_g1->GetTraitDistances(t_g2->m_Traits); + // add to the totals + for(auto it = link_trait_difference.begin(); it != link_trait_difference.end(); it++) + { + if (t_total_link_trait_difference.count(it->first) == 0) + { + t_total_link_trait_difference[it->first] = it->second; + } + else + { + t_total_link_trait_difference[it->first] += it->second; + } + } + + t_g1++; + t_g2++; + } + else if (t_g1innov < t_g2innov) // disjoint + { + t_num_disjoint++; + t_g1++; + } + else if (t_g1innov > t_g2innov) // disjoint + { + t_num_disjoint++; + t_g2++; + } + } + } + + // find matching neuron IDs + for (unsigned int i = NumInputs(); i < NumNeurons(); i++) + { + // no inputs considered for comparison + if ((m_NeuronGenes[i].Type() != INPUT) && (m_NeuronGenes[i].Type() != BIAS)) + { + // a match + if (a_G.HasNeuronID(m_NeuronGenes[i].ID())) + { + t_num_matching_neurons++; + + if (a_Parameters.ActivationADiffCoeff > 0.0) + { + double t_A_difference = m_NeuronGenes[i].m_A - a_G.GetNeuronByID(m_NeuronGenes[i].ID()).m_A; + if (t_A_difference < 0.0f) t_A_difference = -t_A_difference; + t_total_A_difference += t_A_difference; + } + + if (a_Parameters.ActivationBDiffCoeff > 0.0) + { + double t_B_difference = m_NeuronGenes[i].m_B - a_G.GetNeuronByID(m_NeuronGenes[i].ID()).m_B; + if (t_B_difference < 0.0f) t_B_difference = -t_B_difference; + t_total_B_difference += t_B_difference; + } + + if (a_Parameters.TimeConstantDiffCoeff > 0.0) + { + double t_time_constant_difference = + m_NeuronGenes[i].m_TimeConstant - + a_G.GetNeuronByID(m_NeuronGenes[i].ID()).m_TimeConstant; + if (t_time_constant_difference < 0.0f) t_time_constant_difference = -t_time_constant_difference; + t_total_timeconstant_difference += t_time_constant_difference; + } + + if (a_Parameters.BiasDiffCoeff > 0.0) + { + double t_bias_difference = + m_NeuronGenes[i].m_Bias - a_G.GetNeuronByID(m_NeuronGenes[i].ID()).m_Bias; + if (t_bias_difference < 0.0f) t_bias_difference = -t_bias_difference; + t_total_bias_difference += t_bias_difference; + } + + // Activation function type difference is found + if (a_Parameters.ActivationFunctionDiffCoeff > 0.0) + { + if (m_NeuronGenes[i].m_ActFunction != a_G.GetNeuronByID(m_NeuronGenes[i].ID()).m_ActFunction) + { + t_total_num_activation_difference++; + } + } + + // calculate and add node trait difference here + std::map neuron_trait_difference = m_NeuronGenes[i].GetTraitDistances( a_G.GetNeuronByID(m_NeuronGenes[i].ID()).m_Traits ); + // add to the totals + for(auto it = neuron_trait_difference.begin(); it != neuron_trait_difference.end(); it++) + { + if (t_total_neuron_trait_difference.count(it->first) == 0) + { + t_total_neuron_trait_difference[it->first] = it->second; + } + else + { + t_total_neuron_trait_difference[it->first] += it->second; + } + } + } + } + } + + // choose between normalizing for genome size or not + double t_normalizer = 1.0; + if (a_Parameters.NormalizeGenomeSize) + { + t_normalizer = static_cast(t_max_genome_size); + } + + // if there are no matching links or neurons, make it 1.0 to avoid divide error + if (t_num_matching_links <= 0) t_num_matching_links = 1; + if (t_num_matching_neurons <= 0) t_num_matching_neurons = 1; + if (t_normalizer <= 0.0) t_normalizer = 1.0; + double tnrm = 1.0/t_normalizer; + double tnml = 1.0/t_num_matching_links; + double tnmn = 1.0/t_num_matching_neurons; + + t_total_distance = + (a_Parameters.ExcessCoeff * (t_num_excess * tnrm)) + + (a_Parameters.DisjointCoeff * (t_num_disjoint * tnrm)) + + (a_Parameters.WeightDiffCoeff * (t_total_weight_difference * tnml)) + + (a_Parameters.ActivationADiffCoeff * (t_total_A_difference * tnmn)) + + (a_Parameters.ActivationBDiffCoeff * (t_total_B_difference * tnmn)) + + (a_Parameters.TimeConstantDiffCoeff * (t_total_timeconstant_difference * tnmn)) + + (a_Parameters.BiasDiffCoeff * (t_total_bias_difference * tnmn)) + + (a_Parameters.ActivationFunctionDiffCoeff * (t_total_num_activation_difference * tnmn)); + + // add trait differences according to each one's coeff + + for(auto it = t_total_link_trait_difference.begin(); it != t_total_link_trait_difference.end(); it++) + { + double n = (a_Parameters.LinkTraits[it->first].m_ImportanceCoeff * it->second) * tnml; + if (std::isnan(n) || std::isinf(n)) n = 0.0; + t_total_distance += n; + } + for(auto it = t_total_neuron_trait_difference.begin(); it != t_total_neuron_trait_difference.end(); it++) + { + double n = (a_Parameters.NeuronTraits[it->first].m_ImportanceCoeff * it->second) * tnmn; + if (std::isnan(n) || std::isinf(n)) n = 0.0; + t_total_distance += n; + } + for(auto it = t_genome_link_trait_difference.begin(); it != t_genome_link_trait_difference.end(); it++) + { + double n = (a_Parameters.GenomeTraits[it->first].m_ImportanceCoeff * it->second); + if (std::isnan(n) || std::isinf(n)) n = 0.0; + t_total_distance += n; + } + + // store in cache + //distance_cache[std::make_pair(this->GetID(), a_G.GetID())] = t_total_distance; + + return t_total_distance; + } + + // Returns true if this genome and a_G are compatible (belong in the same species) + bool Genome::IsCompatibleWith(Genome &a_G, Parameters &a_Parameters) + { + // full compatibility cases + if (this == &a_G) + return true; + + if (GetID() == a_G.GetID()) + return true; + + /*if ((NumLinks() == 0) && (a_G.NumLinks() == 0)) + return true;*/ + + double t_total_distance = CompatibilityDistance(a_G, a_Parameters); + + if (t_total_distance <= a_Parameters.CompatTreshold) + return true; // compatible + else + return false; // incompatible + } + + + // Returns a random activation function from the canonical set based ot probabilities + ActivationFunction GetRandomActivation(const Parameters &a_Parameters, RNG &a_RNG) + { + std::vector t_probs; + + t_probs.emplace_back(a_Parameters.ActivationFunction_SignedSigmoid_Prob); + t_probs.emplace_back(a_Parameters.ActivationFunction_UnsignedSigmoid_Prob); + t_probs.emplace_back(a_Parameters.ActivationFunction_Tanh_Prob); + t_probs.emplace_back(a_Parameters.ActivationFunction_TanhCubic_Prob); + t_probs.emplace_back(a_Parameters.ActivationFunction_SignedStep_Prob); + t_probs.emplace_back(a_Parameters.ActivationFunction_UnsignedStep_Prob); + t_probs.emplace_back(a_Parameters.ActivationFunction_SignedGauss_Prob); + t_probs.emplace_back(a_Parameters.ActivationFunction_UnsignedGauss_Prob); + t_probs.emplace_back(a_Parameters.ActivationFunction_Abs_Prob); + t_probs.emplace_back(a_Parameters.ActivationFunction_SignedSine_Prob); + t_probs.emplace_back(a_Parameters.ActivationFunction_UnsignedSine_Prob); + t_probs.emplace_back(a_Parameters.ActivationFunction_Linear_Prob); + t_probs.emplace_back(a_Parameters.ActivationFunction_Relu_Prob); + t_probs.emplace_back(a_Parameters.ActivationFunction_Softplus_Prob); + + return (NEAT::ActivationFunction) a_RNG.Roulette(t_probs); + } + + + // Adds a new neuron to the genome + // returns true if succesful + bool Genome::Mutate_AddNeuron(InnovationDatabase &a_Innovs, const Parameters &a_Parameters, RNG &a_RNG) + { + // No links to split - go away.. + if (NumLinks() == 0) + return false; + + // Also we need at least one neuron with 2 incoming links before we split any + /*bool good=false; + for (int i=NumInputs(); i 1) + { + good = true; + break; + } + } + if (!good) + return false;*/ + + // First find a link that to be split + //////////////////// + + // Select a random link for now + bool t_link_found = false; + int t_link_num = 0; + int t_in = 0, t_out = 0; + LinkGene t_chosenlink(0, 0, -1, 0, false); // to save it for later + + // number of tries to find a good link or give up + int t_tries = 256; + while (!t_link_found) + { + if (NumLinks() == 1) + { + t_link_num = 0; + } + /*else if (NumLinks() == 2) + { + t_link_num = Rounded(a_RNG.RandFloat()); + }*/ + else + { + //if (NumLinks() > 8) + { + t_link_num = a_RNG.RandInt(0, NumLinks() - 1); // random selection + } + /*else + { + // this selects older links for splitting + double t_r = abs(RandGaussSigned()/3.0); + Clamp(t_r, 0, 1); + t_link_num = static_cast(t_r * (NumLinks()-1)); + }*/ + } + + + t_in = m_LinkGenes[t_link_num].FromNeuronID(); + t_out = m_LinkGenes[t_link_num].ToNeuronID(); + + ASSERT((t_in > 0) && (t_out > 0)); + + t_link_found = true; + + // In case there is only one link, coming from a bias - just quit + + // unless the parameter is set + if (a_Parameters.DontUseBiasNeuron == false) + { + if ((m_NeuronGenes[GetNeuronIndex(t_in)].Type() == BIAS) && (NumLinks() == 1)) + { + return false; + } + + // Do not allow splitting a link coming from a bias + if (m_NeuronGenes[GetNeuronIndex(t_in)].Type() == BIAS) + { + t_link_found = false; + } + } + + // Do not allow splitting of recurrent links + if (!a_Parameters.SplitRecurrent) + { + if (m_LinkGenes[t_link_num].IsRecurrent()) + { + if ((!a_Parameters.SplitLoopedRecurrent) && (t_in == t_out)) + { + t_link_found = false; + } + } + } + + t_tries--; + if (t_tries <= 0) + { + return false; + } + } + // Now the link has been selected + + // the weight of the link that is being split + double t_orig_weight = m_LinkGenes[t_link_num].GetWeight(); + t_chosenlink = m_LinkGenes[t_link_num]; // save the whole link + + // remove the link from the genome + // find it first and then erase it + // TODO: add option to keep the link, but disabled + std::vector::iterator t_iter; + for (t_iter = m_LinkGenes.begin(); t_iter != m_LinkGenes.end(); t_iter++) + { + if (t_iter->InnovationID() == m_LinkGenes[t_link_num].InnovationID()) + { + // found it! now erase.. + m_LinkGenes.erase(t_iter); + break; + } + } + + // Check if an innovation of this type already occured somewhere in the population + int t_innovid = a_Innovs.CheckInnovation(t_in, t_out, NEW_NEURON); + + // the new neuron and links ids + int t_nid = 0; + int t_l1id = 0; + int t_l2id = 0; + + // This is a novel innovation? + if (t_innovid == -1) + { + // Add the new neuron innovation + t_nid = a_Innovs.AddNeuronInnovation(t_in, t_out, HIDDEN); + // add the first link innovation + t_l1id = a_Innovs.AddLinkInnovation(t_in, t_nid); + // add the second innovation + t_l2id = a_Innovs.AddLinkInnovation(t_nid, t_out); + + // Adjust the SplitY + double t_sy = m_NeuronGenes[GetNeuronIndex(t_in)].SplitY() + m_NeuronGenes[GetNeuronIndex(t_out)].SplitY(); + t_sy /= 2.0; + + // Create the neuron gene + NeuronGene t_ngene(HIDDEN, t_nid, t_sy); + + double t_A = a_RNG.RandFloat(); + double t_B = a_RNG.RandFloat(); + double t_TC = a_RNG.RandFloat(); + double t_Bs = a_RNG.RandFloat(); + Scale(t_A, 0, 1, a_Parameters.MinActivationA, a_Parameters.MaxActivationA); + Scale(t_B, 0, 1, a_Parameters.MinActivationB, a_Parameters.MaxActivationB); + Scale(t_TC, 0, 1, a_Parameters.MinNeuronTimeConstant, a_Parameters.MaxNeuronTimeConstant); + Scale(t_Bs, 0, 1, a_Parameters.MinNeuronBias, a_Parameters.MaxNeuronBias); + + Clamp(t_A, a_Parameters.MinActivationA, a_Parameters.MaxActivationA); + Clamp(t_B, a_Parameters.MinActivationB, a_Parameters.MaxActivationB); + Clamp(t_TC, a_Parameters.MinNeuronTimeConstant, a_Parameters.MaxNeuronTimeConstant); + Clamp(t_Bs, a_Parameters.MinNeuronBias, a_Parameters.MaxNeuronBias); + + // Initialize the neuron gene's properties + t_ngene.Init(t_A, + t_B, + t_TC, + t_Bs, + GetRandomActivation(a_Parameters, a_RNG)); + + // Initialize the traits + //if (a_RNG.RandFloat() < 0.5) + //{ + t_ngene.InitTraits(a_Parameters.NeuronTraits, a_RNG); + //} + //else + //{ // mate instead of randomizing + // t_ngene.m_Traits = m_NeuronGenes[GetNeuronIndex(t_in)].m_Traits; + // t_ngene.MateTraits(m_NeuronGenes[GetNeuronIndex(t_out)].m_Traits, a_RNG); + //} + + // Add the NeuronGene + m_NeuronGenes.emplace_back(t_ngene); + + // Now the links + + // Make sure the recurrent flag is kept + bool t_recurrentflag = t_chosenlink.IsRecurrent(); + + // First link + LinkGene l1 = LinkGene(t_in, t_nid, t_l1id, 1.0, t_recurrentflag); + // make sure this weight is in the allowed interval + Clamp(l1.m_Weight, a_Parameters.MinWeight, a_Parameters.MaxWeight); + // Init the link's traits + l1.InitTraits(a_Parameters.LinkTraits, a_RNG); + m_LinkGenes.emplace_back(l1); + + // Second link + LinkGene l2 = LinkGene(t_nid, t_out, t_l2id, t_orig_weight, t_recurrentflag); + // Init the link's traits + l2.InitTraits(a_Parameters.LinkTraits, a_RNG); + m_LinkGenes.emplace_back(l2); + } + else + { + // This innovation already happened, so inherit it. + + // get the neuron ID + t_nid = a_Innovs.FindNeuronID(t_in, t_out); + ASSERT(t_nid != -1); + + // if such an innovation happened, these must exist + t_l1id = a_Innovs.CheckInnovation(t_in, t_nid, NEW_LINK); + t_l2id = a_Innovs.CheckInnovation(t_nid, t_out, NEW_LINK); + + ASSERT((t_l1id > 0) && (t_l2id > 0)); + + // Perhaps this innovation occured more than once. Find the + // first such innovation that had occured, but the genome + // not having the same id.. If didn't find such, then add new innovation. + std::vector t_idxs = a_Innovs.CheckAllInnovations(t_in, t_out, NEW_NEURON); + bool t_found = false; + for (unsigned int i = 0; i < t_idxs.size(); i++) + { + if (!HasNeuronID(a_Innovs.GetInnovationByIdx(t_idxs[i]).NeuronID())) + { + // found such innovation & this genome doesn't have that neuron ID + // So we are going to inherit the innovation + t_nid = a_Innovs.GetInnovationByIdx(t_idxs[i]).NeuronID(); + + // these must exist + t_l1id = a_Innovs.CheckInnovation(t_in, t_nid, NEW_LINK); + t_l2id = a_Innovs.CheckInnovation(t_nid, t_out, NEW_LINK); + + ASSERT((t_l1id > 0) && (t_l2id > 0)); + + t_found = true; + break; + } + } + + // Such an innovation was not found or the genome has all neuron IDs + // So we are going to add new innovation + if (!t_found) + { + // Add 3 new innovations and replace the variables with them + + // Add the new neuron innovation + t_nid = a_Innovs.AddNeuronInnovation(t_in, t_out, HIDDEN); + // add the first link innovation + t_l1id = a_Innovs.AddLinkInnovation(t_in, t_nid); + // add the second innovation + t_l2id = a_Innovs.AddLinkInnovation(t_nid, t_out); + } + + + // Add the neuron and the links + double t_sy = m_NeuronGenes[GetNeuronIndex(t_in)].SplitY() + m_NeuronGenes[GetNeuronIndex(t_out)].SplitY(); + t_sy /= 2.0; + + // Create the neuron gene + NeuronGene t_ngene(HIDDEN, t_nid, t_sy); + + double t_A = a_RNG.RandFloat(); + double t_B = a_RNG.RandFloat(); + double t_TC = a_RNG.RandFloat(); + double t_Bs = a_RNG.RandFloat(); + Scale(t_A, 0, 1, a_Parameters.MinActivationA, a_Parameters.MaxActivationA); + Scale(t_B, 0, 1, a_Parameters.MinActivationB, a_Parameters.MaxActivationB); + Scale(t_TC, 0, 1, a_Parameters.MinNeuronTimeConstant, a_Parameters.MaxNeuronTimeConstant); + Scale(t_Bs, 0, 1, a_Parameters.MinNeuronBias, a_Parameters.MaxNeuronBias); + + Clamp(t_A, a_Parameters.MinActivationA, a_Parameters.MaxActivationA); + Clamp(t_B, a_Parameters.MinActivationB, a_Parameters.MaxActivationB); + Clamp(t_TC, a_Parameters.MinNeuronTimeConstant, a_Parameters.MaxNeuronTimeConstant); + Clamp(t_Bs, a_Parameters.MinNeuronBias, a_Parameters.MaxNeuronBias); + + // Initialize the neuron gene's properties + t_ngene.Init(t_A, + t_B, + t_TC, + t_Bs, + GetRandomActivation(a_Parameters, a_RNG)); + + // Initialize the traits + //if (a_RNG.RandFloat() < 0.5) + //{ + t_ngene.InitTraits(a_Parameters.NeuronTraits, a_RNG); + //}// mate instead of randomizing + //else + //{ + // t_ngene.m_Traits = m_NeuronGenes[GetNeuronIndex(t_in)].m_Traits; + // t_ngene.MateTraits(m_NeuronGenes[GetNeuronIndex(t_out)].m_Traits, a_RNG); + //} + + // Make sure the recurrent flag is kept + bool t_recurrentflag = t_chosenlink.IsRecurrent(); + + // Add the NeuronGene + m_NeuronGenes.emplace_back(t_ngene); + // First link + LinkGene l1 = LinkGene(t_in, t_nid, t_l1id, 1.0, t_recurrentflag); + // make sure this weight is in the allowed interval + Clamp(l1.m_Weight, a_Parameters.MinWeight, a_Parameters.MaxWeight); + // initialize the link's traits + l1.InitTraits(a_Parameters.LinkTraits, a_RNG); + m_LinkGenes.emplace_back(l1); + // Second link + LinkGene l2 = LinkGene(t_nid, t_out, t_l2id, t_orig_weight, t_recurrentflag); + // initialize the link's traits + l2.InitTraits(a_Parameters.LinkTraits, a_RNG); + m_LinkGenes.emplace_back(l2); + } + + return true; + } + + + // Adds a new link to the genome + // returns true if succesful + bool Genome::Mutate_AddLink(InnovationDatabase &a_Innovs, const Parameters &a_Parameters, RNG &a_RNG) + { + // this variable tells where is the first noninput node + int t_first_noninput = 0; + + // The pair of neurons that has to be connected (1 - in, 2 - out) + // It may be the same neuron - this means that the connection is a looped recurrent one. + // These are indexes in the NeuronGenes array! + int t_n1idx = 0, t_n2idx = 0; + + // Should we make this connection recurrent? + bool t_MakeRecurrent = false; + + // If so, should it be a looped one? + bool t_LoopedRecurrent = false; + + // Should it come from the bias neuron? + bool t_MakeBias = false; + + // Counter of tries to find a candidate pair of neuron/s to connect. + unsigned int t_NumTries = 0; + + + // Decide whether the connection will be recurrent or not.. + if (a_RNG.RandFloat() < a_Parameters.RecurrentProb) + { + t_MakeRecurrent = true; + + if (a_RNG.RandFloat() < a_Parameters.RecurrentLoopProb) + { + t_LoopedRecurrent = true; + } + } + // if not recurrent, there is a probability that this link will be from the bias + // if such link doesn't already exist. + // in case such link exists, search for a standard feed-forward connection place + else + { + if (a_RNG.RandFloat() < a_Parameters.MutateAddLinkFromBiasProb) + { + t_MakeBias = true; + } + } + + // Try to find a good pair of neurons + bool t_Found = false; + + // Find the first noninput node + for (unsigned int i = 0; i < NumNeurons(); i++) + { + if ((m_NeuronGenes[i].Type() == INPUT) || (m_NeuronGenes[i].Type() == BIAS)) + { + t_first_noninput++; + } + else + { + break; + } + } + + // A forward link is characterized with the fact that + // the From neuron has less or equal SplitY value + + // find a good pair of nodes for a forward link + if (!t_MakeRecurrent) + { + // first see if this should come from the bias or not + bool t_found_bias = true; + t_n1idx = static_cast(NumInputs() - 1); // the bias is always the last input + // try to find a neuron that is not connected to the bias already + t_NumTries = 0; + do + { + t_n2idx = a_RNG.RandInt(t_first_noninput, static_cast(NumNeurons() - 1)); + t_NumTries++; + + if (t_NumTries >= a_Parameters.LinkTries) + { + // couldn't find anything + t_found_bias = false; + break; + } + } + while ((HasLink(m_NeuronGenes[t_n1idx].ID(), m_NeuronGenes[t_n2idx].ID()))); // already present? + + // so if we found that link, we can skip the rest of the things + if (t_found_bias && t_MakeBias) + { + t_Found = true; + } + // otherwise continue trying to find a normal forward link + else + { + t_NumTries = 0; + // try to find a standard forward connection + do + { + t_n1idx = a_RNG.RandInt(0, static_cast(NumNeurons() - 1)); + t_n2idx = a_RNG.RandInt(t_first_noninput, static_cast(NumNeurons() - 1)); + t_NumTries++; + + if (t_NumTries >= a_Parameters.LinkTries) + { + // couldn't find anything + // say goodbye + return false; + } + } + while ( + //(m_NeuronGenes[t_n1idx].SplitY() > m_NeuronGenes[t_n2idx].SplitY()) // backward? + //|| + (HasLink(m_NeuronGenes[t_n1idx].ID(), m_NeuronGenes[t_n2idx].ID())) // already present? + || + (m_NeuronGenes[t_n1idx].Type() == OUTPUT) // consider connections out of outputs recurrent + || + (t_n1idx == t_n2idx) // make sure they differ + ); + + // it found a good pair of neurons + t_Found = true; + } + } + // find a good pair of nodes for a recurrent link (non-looped) + else if (t_MakeRecurrent && !t_LoopedRecurrent) + { + t_NumTries = 0; + do + { + t_n1idx = a_RNG.RandInt(t_first_noninput, static_cast(NumNeurons() - 1)); + t_n2idx = a_RNG.RandInt(t_first_noninput, static_cast(NumNeurons() - 1)); + t_NumTries++; + + if (t_NumTries >= a_Parameters.LinkTries) + { + // couldn't find anything + // say goodbye + return false; + } + } + // NOTE: this considers output-output connections as forward. Should be fixed. + while ( + //(m_NeuronGenes[t_n1idx].SplitY() <= m_NeuronGenes[t_n2idx].SplitY()) // forward? + //|| + (HasLink(m_NeuronGenes[t_n1idx].ID(), m_NeuronGenes[t_n2idx].ID())) // already present? + || + (t_n1idx == t_n2idx) // they should differ + ); + + // it found a good pair of neurons + t_Found = true; + } + // find a good neuron to make a looped recurrent link + else if (t_MakeRecurrent && t_LoopedRecurrent) + { + t_NumTries = 0; + do + { + t_n1idx = t_n2idx = a_RNG.RandInt(t_first_noninput, static_cast(NumNeurons() - 1)); + t_NumTries++; + + if (t_NumTries >= a_Parameters.LinkTries) + { + // couldn't find anything + // say goodbye + return false; + } + } + while ( + (HasLink(m_NeuronGenes[t_n1idx].ID(), m_NeuronGenes[t_n2idx].ID())) // already present? + //|| + //(m_NeuronGenes[t_n1idx].Type() == OUTPUT) // do not allow looped recurrent on the outputs (experimental) + ); + + // it found a good pair of neurons + t_Found = true; + } + + + // To make sure it is all right + if (!t_Found) + { + return false; + } + + // This link MUST NOT be a part of the genome by any reason + ASSERT((!HasLink(m_NeuronGenes[t_n1idx].ID(), m_NeuronGenes[t_n2idx].ID()))); // already present? + + // extract the neuron IDs from the indexes + int t_n1id = m_NeuronGenes[t_n1idx].ID(); + int t_n2id = m_NeuronGenes[t_n2idx].ID(); + + // So we have a good pair of neurons to connect. See the innovation database if this is novel innovation. + int t_innovid = a_Innovs.CheckInnovation(t_n1id, t_n2id, NEW_LINK); + + // Choose the weight for this link + double t_weight = a_RNG.RandFloat(); + Scale(t_weight, 0, 1, a_Parameters.MinWeight, a_Parameters.MaxWeight); + + // A novel innovation? + if (t_innovid == -1) + { + // Make new innovation + t_innovid = a_Innovs.AddLinkInnovation(t_n1id, t_n2id); + } + + // Create and add the link + LinkGene l = LinkGene(t_n1id, t_n2id, t_innovid, t_weight, t_MakeRecurrent); + // init the link's traits + l.InitTraits(a_Parameters.LinkTraits, a_RNG); + m_LinkGenes.emplace_back(l); + + // All done. + return true; + } + + + + + /////////// + // Helper functions for the pruning procedure + + // Removes the link with the specified innovation ID + /*void Genome::RemoveLinkGene(int a_InnovID) + { + // for iterating through the genes + std::vector::iterator t_curlink = m_LinkGenes.begin(); + + while (t_curlink != m_LinkGenes.end()) + { + if (t_curlink->InnovationID() == a_InnovID) + { + // found it - erase & quit + t_curlink = m_LinkGenes.erase(t_curlink); + break; + } + + t_curlink++; + } + }*/ + + // this version uses a simple index + void Genome::RemoveLinkGene(int a_idx) + { + // for iterating through the genes + auto t_curlink = m_LinkGenes.begin(); + if (a_idx > 0) + { + m_LinkGenes.erase(m_LinkGenes.begin() + a_idx); + } + else + { + m_LinkGenes.clear(); + } + } + + + // Remove node + // Links connected to this node are also removed + void Genome::RemoveNeuronGene(int a_ID) + { + // the list of links connected to this neuron + std::vector t_link_removal_queue; + + bool removed=false; + + do + { + removed=false; + // Remove all links connected to this neuron ID + for (int i = 0; i < NumLinks(); i++) + { + if ((m_LinkGenes[i].FromNeuronID() == a_ID) || (m_LinkGenes[i].ToNeuronID() == a_ID)) + { + // found one, remove it + //t_link_removal_queue.emplace_back(i);//m_LinkGenes[i].InnovationID()); + RemoveLinkGene(i); + removed=true; + break; + } + } + } while (removed); + + // Now remove them + /*for (unsigned int i = 0; i < t_link_removal_queue.size(); i++) + { + RemoveLinkGene(t_link_removal_queue[i]); + }*/ + + // Now is safe to remove the neuron + // find it first + std::vector::iterator t_curneuron = m_NeuronGenes.begin(); + + while (t_curneuron != m_NeuronGenes.end()) + { + if (t_curneuron->ID() == a_ID) + { + // found it, erase and quit + m_NeuronGenes.erase(t_curneuron); + break; + } + + t_curneuron++; + } + } + + + // Returns true is the specified neuron ID is a dead end or isolated + bool Genome::IsDeadEndNeuron(int a_ID) const + { + bool t_no_incoming = true; + bool t_no_outgoing = true; + + // search the links and prove both are wrong + for (unsigned int i = 0; i < NumLinks(); i++) + { + // there is a link going to this neuron, so there are incoming + // don't count the link if it is recurrent or coming from a bias + if ((m_LinkGenes[i].ToNeuronID() == a_ID) + && (!m_LinkGenes[i].IsLoopedRecurrent()) + && (GetNeuronByID(m_LinkGenes[i].FromNeuronID()).Type() != BIAS)) + { + t_no_incoming = false; + } + + // there is a link going from this neuron, so there are outgoing + // don't count the link if it is recurrent or coming from a bias + if ((m_LinkGenes[i].FromNeuronID() == a_ID) + && (!m_LinkGenes[i].IsLoopedRecurrent()) + && (GetNeuronByID(m_LinkGenes[i].FromNeuronID()).Type() != BIAS)) + { + t_no_outgoing = false; + } + } + + // if just one of these is true, this neuron is a dead end + if (t_no_incoming || t_no_outgoing) + { + return true; + } + else + { + return false; + } + } + + + // Search the genome for isolated structure and clean it up + // Returns true is something was removed + bool Genome::Cleanup() + { + bool t_removed = false; + + // remove any dead-end hidden neurons + for (unsigned int i = 0; i < NumNeurons(); i++) + { + if (m_NeuronGenes[i].Type() == HIDDEN) + { + if (IsDeadEndNeuron(m_NeuronGenes[i].ID())) + { + RemoveNeuronGene(m_NeuronGenes[i].ID()); + t_removed = true; + } + } + } + + // a special case are isolated outputs - these are outputs having + // one and only one looped recurrent connection + // we simply remove these connections and leave the outputs naked. + for (unsigned int i = 0; i < NumNeurons(); i++) + { + if (m_NeuronGenes[i].Type() == OUTPUT) + { + // Only outputs with 1 input and 1 output connection are considered. + if ((LinksInputtingFrom(m_NeuronGenes[i].ID()) == 1) && (LinksOutputtingTo(m_NeuronGenes[i].ID()) == 1)) + { + // that must be a lonely looped recurrent, + // because we know that the outputs are the dead end of the network + // find this link + for (unsigned int j = 0; j < NumLinks(); j++) + { + if (m_LinkGenes[j].ToNeuronID() == m_NeuronGenes[i].ID()) + { + // Remove it. + RemoveLinkGene(m_LinkGenes[j].InnovationID()); + t_removed = true; + } + } + } + } + } + + return t_removed; + } + + + // Returns true if has any dead end + bool Genome::HasDeadEnds() const + { + // any dead-end hidden neurons? + for (unsigned int i = 0; i < NumNeurons(); i++) + { + if (m_NeuronGenes[i].Type() == HIDDEN) + { + if (IsDeadEndNeuron(m_NeuronGenes[i].ID())) + { + return true; + } + } + } + + // a special case are isolated outputs - these are outputs having + // one and only one looped recurrent connection or no connections at all + for (unsigned int i = 0; i < NumNeurons(); i++) + { + if (m_NeuronGenes[i].Type() == OUTPUT) + { + // Only outputs with 1 input and 1 output connection are considered. + if ((LinksInputtingFrom(m_NeuronGenes[i].ID()) == 1) && (LinksOutputtingTo(m_NeuronGenes[i].ID()) == 1)) + { + // that must be a lonely looped recurrent, + // because we know that the outputs are the dead end of the network + return true; + } + + // There may be cases for totally isolated outputs + // Consider this if only one output is present + if (NumOutputs() == 1) + if ((LinksInputtingFrom(m_NeuronGenes[i].ID()) == 0) && + (LinksOutputtingTo(m_NeuronGenes[i].ID()) == 0)) + { + return true; + } + } + } + + return false; + } + + + // Remove a link from the genome + // A cleanup procedure is invoked so any dead-ends or stranded neurons are also deleted + // returns true if succesful + bool Genome::Mutate_RemoveLink(RNG &a_RNG) + { + // at least 2 links must be present in the genome + if (NumLinks() < 2) + return false; + + // find a random link to remove + // with tendency to remove older connections + double t_randnum = a_RNG.RandFloat();//RandGaussSigned()/4; + Clamp(t_randnum, 0, 1); + + int t_link_index = static_cast(t_randnum * static_cast(NumLinks() - + 1));//RandInt(0, static_cast(NumLinks()-1)); + + // remove it + RemoveLinkGene(m_LinkGenes[t_link_index].InnovationID()); + + // Now cleanup + //Cleanup(); + + return true; + } + + + // Returns the count of links inputting from the specified neuron ID + int Genome::LinksInputtingFrom(int a_ID) const + { + int t_counter = 0; + for (unsigned int i = 0; i < NumLinks(); i++) + { + if (m_LinkGenes[i].FromNeuronID() == a_ID) + t_counter++; + } + + return t_counter; + } + + + // Returns the count of links outputting to the specified neuron ID + int Genome::LinksOutputtingTo(int a_ID) const + { + int t_counter = 0; + for (unsigned int i = 0; i < NumLinks(); i++) + { + if (m_LinkGenes[i].ToNeuronID() == a_ID) + t_counter++; + } + + return t_counter; + } + + + // Replaces a hidden neuron having only one input and only one output with + // a direct link between them. + bool Genome::Mutate_RemoveSimpleNeuron(InnovationDatabase &a_Innovs, const Parameters &a_Parameters, RNG &a_RNG) + { + // At least one hidden node must be present + if (NumNeurons() == (NumInputs() + NumOutputs())) + return false; + + // Build a list of candidate neurons for deletion + // Indexes! + std::vector t_neurons_to_delete; + for (int i = 0; i < NumNeurons(); i++) + { + if ((LinksInputtingFrom(m_NeuronGenes[i].ID()) == 1) && (LinksOutputtingTo(m_NeuronGenes[i].ID()) == 1) + && (m_NeuronGenes[i].Type() == HIDDEN)) + { + t_neurons_to_delete.emplace_back(i); + } + } + + // If the list is empty, say goodbye + if (t_neurons_to_delete.size() == 0) + return false; + + // Now choose a random one to delete + int t_choice; + if (t_neurons_to_delete.size() == 2) + t_choice = Rounded(a_RNG.RandFloat()); + else + t_choice = a_RNG.RandInt(0, static_cast(t_neurons_to_delete.size() - 1)); + + // the links in & out + int t_l1idx = -1, t_l2idx = -1; + + // find the link outputting to the neuron + for (unsigned int i = 0; i < NumLinks(); i++) + { + if (m_LinkGenes[i].ToNeuronID() == m_NeuronGenes[t_neurons_to_delete[t_choice]].ID()) + { + t_l1idx = i; + break; + } + } + // find the link inputting from the neuron + for (unsigned int i = 0; i < NumLinks(); i++) + { + if (m_LinkGenes[i].FromNeuronID() == m_NeuronGenes[t_neurons_to_delete[t_choice]].ID()) + { + t_l2idx = i; + break; + } + } + + ASSERT((t_l1idx >= 0) && (t_l2idx >= 0)); + + // OK now see if a link connecting the original 2 nodes is present. If it is, we will just + // delete the neuron and quit. + if (HasLink(m_LinkGenes[t_l1idx].FromNeuronID(), m_LinkGenes[t_l2idx].ToNeuronID())) + { + RemoveNeuronGene(m_NeuronGenes[t_neurons_to_delete[t_choice]].ID()); + return true; + } + // Else the link is not present and we will replace the neuron and 2 links with one link + else + { + // Remember the first link's weight + double t_weight = m_LinkGenes[t_l1idx].GetWeight(); + + // See the innovation database for an innovation number + int t_innovid = a_Innovs.CheckInnovation(m_LinkGenes[t_l1idx].FromNeuronID(), + m_LinkGenes[t_l2idx].ToNeuronID(), NEW_LINK); + + // a novel innovation? + if (t_innovid == -1) + { + // Save the IDs for a while + int from = m_LinkGenes[t_l1idx].FromNeuronID(); + int to = m_LinkGenes[t_l2idx].ToNeuronID(); + + // Remove the neuron and its links now + RemoveNeuronGene(m_NeuronGenes[t_neurons_to_delete[t_choice]].ID()); + + // Add the innovation and the link gene + int t_newinnov = a_Innovs.AddLinkInnovation(from, to); + LinkGene lg = LinkGene(from, to, t_newinnov, t_weight, false); + lg.InitTraits(a_Parameters.LinkTraits, a_RNG); + + m_LinkGenes.emplace_back(lg); + + // bye + return true; + } + // not a novel innovation + else + { + // Save the IDs for a while + int from = m_LinkGenes[t_l1idx].FromNeuronID(); + int to = m_LinkGenes[t_l2idx].ToNeuronID(); + + // Remove the neuron and its links now + RemoveNeuronGene(m_NeuronGenes[t_neurons_to_delete[t_choice]].ID()); + + // Add the link + LinkGene lg = LinkGene(from, to, t_innovid, t_weight, false); + lg.InitTraits(a_Parameters.LinkTraits, a_RNG); + m_LinkGenes.emplace_back(lg); + + // TODO: Maybe inherit the traits from one of the links + + // bye + return true; + } + } + + return false; + } + + + // Perturbs the weights + bool Genome::Mutate_LinkWeights(const Parameters &a_Parameters, RNG &a_RNG) + { + // The end part of the genome + int t_genometail = 0; + if (NumLinks() > m_initial_num_links) + { + t_genometail = (int)(((double)(NumLinks())) * 0.8); + } + if (t_genometail < m_initial_num_links) + { + t_genometail = m_initial_num_links; + } + + bool did_mutate = false; + + // This tells us if this mutation will shake things up + bool t_severe_mutation; + + if (a_RNG.RandFloat() < a_Parameters.MutateWeightsSevereProb) + { + t_severe_mutation = true; + } + else + { + t_severe_mutation = false; + } + + // For all links.. + for(unsigned int i=0; i= t_genometail); + double t_LinkGenesWeight = m_LinkGenes[i].GetWeight(); + + if (ontail || (a_RNG.RandFloat() < a_Parameters.WeightReplacementRate)) + { + t_LinkGenesWeight = a_RNG.RandFloatSigned() * a_Parameters.WeightReplacementMaxPower; + + //t_LinkGenesWeight = a_RNG.RandFloat(); + //Scale(t_LinkGenesWeight, 0.0, 1.0, a_Parameters.MinWeight, a_Parameters.MaxWeight); + } + else + { + t_LinkGenesWeight += a_RNG.RandFloatSigned() * a_Parameters.WeightMutationMaxPower; + } + + Clamp(t_LinkGenesWeight, a_Parameters.MinWeight, a_Parameters.MaxWeight); + m_LinkGenes[i].SetWeight(t_LinkGenesWeight); + + did_mutate = true; + } + else if (t_severe_mutation) + { + if (a_RNG.RandFloat() < a_Parameters.WeightMutationRate) + { + double t_LinkGenesWeight = a_RNG.RandFloat(); + Scale(t_LinkGenesWeight, 0.0, 1.0, a_Parameters.MinWeight, a_Parameters.MaxWeight); + m_LinkGenes[i].SetWeight(t_LinkGenesWeight); + + did_mutate = true; + } + } + } + + return did_mutate; + } + + + // Set all link weights to random values between [-R .. R] + void Genome::Randomize_LinkWeights(const Parameters& a_Parameters, RNG &a_RNG) + { + // For all links.. + for (unsigned int i = 0; i < NumLinks(); i++) + { + double nf=0; + nf = a_RNG.RandFloat(); + Scale(nf, 0.0, 1.0, a_Parameters.MinWeight, a_Parameters.MaxWeight); + m_LinkGenes[i].SetWeight(nf); + } + } + + // Randomize traits + void Genome::Randomize_Traits(const Parameters &a_Parameters, RNG &a_RNG) + { + for (auto &m_NeuronGene : m_NeuronGenes) + { + m_NeuronGene.InitTraits(a_Parameters.NeuronTraits, a_RNG); + } + for (auto &m_LinkGene : m_LinkGenes) + { + m_LinkGene.InitTraits(a_Parameters.LinkTraits, a_RNG); + } + + m_GenomeGene.InitTraits(a_Parameters.GenomeTraits, a_RNG); + } + + // Perturbs the A parameters of the neuron activation functions + bool Genome::Mutate_NeuronActivations_A(const Parameters &a_Parameters, RNG &a_RNG) + { + // for all neurons.. + for (unsigned int i = 0; i < NumNeurons(); i++) + { + // skip inputs and bias + if ((m_NeuronGenes[i].Type() != INPUT) && (m_NeuronGenes[i].Type() != BIAS)) + { + double t_randnum = a_RNG.RandFloatSigned() * a_Parameters.ActivationAMutationMaxPower; + + m_NeuronGenes[i].m_A += t_randnum; + + Clamp(m_NeuronGenes[i].m_A, a_Parameters.MinActivationA, a_Parameters.MaxActivationA); + } + } + + return true; + } + + + // Perturbs the B parameters of the neuron activation functions + bool Genome::Mutate_NeuronActivations_B(const Parameters &a_Parameters, RNG &a_RNG) + { + // for all neurons.. + for (unsigned int i = 0; i < NumNeurons(); i++) + { + // skip inputs and bias + if ((m_NeuronGenes[i].Type() != INPUT) && (m_NeuronGenes[i].Type() != BIAS)) + { + double t_randnum = a_RNG.RandFloatSigned() * a_Parameters.ActivationBMutationMaxPower; + + m_NeuronGenes[i].m_B += t_randnum; + + Clamp(m_NeuronGenes[i].m_B, a_Parameters.MinActivationB, a_Parameters.MaxActivationB); + } + } + + return true; + } + + + // Changes the activation function type for a random neuron + bool Genome::Mutate_NeuronActivation_Type(const Parameters &a_Parameters, RNG &a_RNG) + { + // the first non-input neuron + int t_first_idx = NumInputs(); + int t_choice = a_RNG.RandInt(t_first_idx, m_NeuronGenes.size() - 1); + + int cur = m_NeuronGenes[t_choice].m_ActFunction; + + m_NeuronGenes[t_choice].m_ActFunction = GetRandomActivation(a_Parameters, a_RNG); + if (m_NeuronGenes[t_choice].m_ActFunction == cur) // same as before? + { + return false; + } + else + { + return true; + } + } + + // Perturbs the neuron time constants + bool Genome::Mutate_NeuronTimeConstants(const Parameters &a_Parameters, RNG &a_RNG) + { + // for all neurons.. + for (unsigned int i = 0; i < NumNeurons(); i++) + { + // skip inputs and bias + if ((m_NeuronGenes[i].Type() != INPUT) && (m_NeuronGenes[i].Type() != BIAS)) + { + double t_randnum = a_RNG.RandFloatSigned() * a_Parameters.TimeConstantMutationMaxPower; + + m_NeuronGenes[i].m_TimeConstant += t_randnum; + + Clamp(m_NeuronGenes[i].m_TimeConstant, a_Parameters.MinNeuronTimeConstant, + a_Parameters.MaxNeuronTimeConstant); + } + } + + return true; + } + + // Perturbs the neuron biases + bool Genome::Mutate_NeuronBiases(const Parameters &a_Parameters, RNG &a_RNG) + { + // for all neurons.. + for (unsigned int i = 0; i < NumNeurons(); i++) + { + // skip inputs and bias + if ((m_NeuronGenes[i].Type() != INPUT) && (m_NeuronGenes[i].Type() != BIAS)) + { + double t_randnum = a_RNG.RandFloatSigned() * a_Parameters.BiasMutationMaxPower; + + m_NeuronGenes[i].m_Bias += t_randnum; + + Clamp(m_NeuronGenes[i].m_Bias, a_Parameters.MinNeuronBias, a_Parameters.MaxNeuronBias); + } + } + + return true; + } + + bool Genome::Mutate_NeuronTraits(const Parameters &a_Parameters, RNG &a_RNG) + { + bool did_mutate = false; + for(auto it = m_NeuronGenes.begin(); it != m_NeuronGenes.end(); it++) + { + // don't mutate inputs and bias + if ((it->Type() != INPUT) && (it->Type() != BIAS)) + { + did_mutate |= it->MutateTraits(a_Parameters.NeuronTraits, a_RNG); + } + } + return did_mutate; + } + + bool Genome::Mutate_LinkTraits(const Parameters &a_Parameters, RNG &a_RNG) + { + bool did_mutate = false; + for(auto it = m_LinkGenes.begin(); it != m_LinkGenes.end(); it++) + { + did_mutate |= it->MutateTraits(a_Parameters.LinkTraits, a_RNG); + } + return did_mutate; + } + + bool Genome::Mutate_GenomeTraits(const Parameters &a_Parameters, RNG &a_RNG) + { + return m_GenomeGene.MutateTraits(a_Parameters.GenomeTraits, a_RNG); + } + + // Mate this genome with dad and return the baby + // This is multipoint mating - genes inherited randomly + // Disjoint and excess genes are inherited from the fittest parent + // If fitness is equal, the smaller genome is assumed to be the better one + Genome Genome::Mate(Genome &a_Dad, bool a_MateAverage, bool a_InterSpecies, RNG &a_RNG, Parameters &a_Parameters) + { + // Cannot mate with itself + if (GetID() == a_Dad.GetID()) + return *this; + + // helps make the code clearer + enum t_parent_type + { + MOM, DAD, + }; + + // This is the fittest genome. + t_parent_type t_better; + + // This empty genome will hold the baby + Genome t_baby; + + // create iterators so we can step through each parents genes and set + // them to the first gene of each parent + std::vector::iterator t_curMom = m_LinkGenes.begin(); + std::vector::iterator t_curDad = a_Dad.m_LinkGenes.begin(); + + // this will hold a copy of the gene we wish to add at each step + LinkGene t_selectedgene(0, 0, -1, 0, false); + + // Mate the GenomeGene first + // Determine if it will pick either gene or mate it + if (a_RNG.RandFloat() < a_Parameters.MultipointCrossoverRate) + { + // pick + Gene n; + + if (a_RNG.RandFloat() < a_Parameters.PreferFitterParentRate) + { + n = (GetFitness() > a_Dad.GetFitness()) ? m_GenomeGene : a_Dad.m_GenomeGene; + } + else + { + n = (a_RNG.RandFloat() < 0.5) ? m_GenomeGene : a_Dad.m_GenomeGene; + } + t_baby.m_GenomeGene = n; + } + else + { + // mate + Gene n = m_GenomeGene; + n.MateTraits(a_Dad.m_GenomeGene.m_Traits, a_RNG); + t_baby.m_GenomeGene = n; + } + + + // Make sure all inputs/outputs are present in the baby + // Essential to FS-NEAT + + if (!a_Parameters.DontUseBiasNeuron) + { + // the inputs + unsigned int i = 0; + for (i = 0; i < m_NumInputs - 1; i++) + { + // Determine if it will pick either gene or mate it + /*if (a_RNG.RandFloat() < a_Parameters.MultipointCrossoverRate) + { + // pick + NeuronGene n; + // most of the time pick from the fitter parent + if (a_RNG.RandFloat() < a_Parameters.PreferFitterParentRate) + { + n = (GetFitness() > a_Dad.GetFitness())? m_NeuronGenes[i] : a_Dad.m_NeuronGenes[i]; + } + else + { + // pick randomly + n = (a_RNG.RandFloat() < 0.5)? m_NeuronGenes[i] : a_Dad.m_NeuronGenes[i]; + } + + t_baby.m_NeuronGenes.emplace_back(n); + } + else + {*/ + // mate + //n.MateTraits(a_Dad.m_NeuronGenes[i].m_Traits, a_RNG); + t_baby.m_NeuronGenes.emplace_back(m_NeuronGenes[i]); + //} + + } + /*if (a_RNG.RandFloat() < a_Parameters.MultipointCrossoverRate) + { + // the bias + NeuronGene nb; + if (a_RNG.RandFloat() < a_Parameters.PreferFitterParentRate) + { + nb = (GetFitness() > a_Dad.GetFitness())? m_NeuronGenes[i] : a_Dad.m_NeuronGenes[i]; + } + else + { + nb = (a_RNG.RandFloat() < 0.5) ? m_NeuronGenes[i] : a_Dad.m_NeuronGenes[i]; + } + t_baby.m_NeuronGenes.emplace_back(nb); + } + else + {*/ + // mate + //nb.MateTraits(a_Dad.m_NeuronGenes[i].m_Traits, a_RNG); + t_baby.m_NeuronGenes.emplace_back(m_NeuronGenes[i]); + //} + } + else + { + // the inputs + for (unsigned int i = 0; i < m_NumInputs; i++) + { + /*if (a_RNG.RandFloat() < a_Parameters.MultipointCrossoverRate) + { + NeuronGene n; + if (a_RNG.RandFloat() < a_Parameters.PreferFitterParentRate) + { + n = (GetFitness() > a_Dad.GetFitness())? m_NeuronGenes[i] : a_Dad.m_NeuronGenes[i]; + } + else + { + n = (a_RNG.RandFloat() < 0.5) ? m_NeuronGenes[i] : a_Dad.m_NeuronGenes[i]; + } + t_baby.m_NeuronGenes.emplace_back(n); + } + else + {*/ + //n.MateTraits(a_Dad.m_NeuronGenes[i].m_Traits, a_RNG); + t_baby.m_NeuronGenes.emplace_back(m_NeuronGenes[i]); + //} + } + } + + // the outputs + for (unsigned int i = 0; i < m_NumOutputs; i++) + { + NeuronGene t_tempneuron(OUTPUT, 0, 1); + + if (a_RNG.RandFloat() < a_Parameters.MultipointCrossoverRate) + { + if (a_RNG.RandFloat() < a_Parameters.PreferFitterParentRate) + { + if (GetFitness() > a_Dad.GetFitness()) + { + // from mother + t_tempneuron = GetNeuronByIndex(i + m_NumInputs); + } + else + { + // from father + t_tempneuron = a_Dad.GetNeuronByIndex(i + m_NumInputs); + } + } + else + { + // random pick + if (a_RNG.RandFloat() < 0.5) + { + // from mother + t_tempneuron = GetNeuronByIndex(i + m_NumInputs); + } + else + { + // from father + t_tempneuron = a_Dad.GetNeuronByIndex(i + m_NumInputs); + } + } + } + else + { + // mating + // from mother + t_tempneuron = GetNeuronByIndex(i + m_NumInputs); + t_tempneuron.MateTraits(a_Dad.GetNeuronByIndex(i + m_NumInputs).m_Traits, a_RNG); + } + + t_baby.m_NeuronGenes.emplace_back(t_tempneuron); + } + + // if they are of equal fitness use the shorter (because we want to keep + // the networks as small as possible) + if (GetFitness() == a_Dad.GetFitness()) + { + // if they are of equal fitness and length just choose one at + // random + if (NumLinks() == a_Dad.NumLinks()) + { + if (a_RNG.RandFloat() < 0.5) + { + t_better = MOM; + } + else + { + t_better = DAD; + } + } + else + { + if (NumLinks() < a_Dad.NumLinks()) + { + t_better = MOM; + } + else + { + t_better = DAD; + } + } + } + else + { + if (GetFitness() > a_Dad.GetFitness()) + { + t_better = MOM; + } + else + { + t_better = DAD; + } + } + + ////////////////////////////////////////////////////////// + // The better genome has been chosen. Now we mate them. + ////////////////////////////////////////////////////////// + + // for cleaning up + LinkGene t_emptygene(0, 0, -1, 0, false); + bool t_skip = false; + int t_innov_mom, t_innov_dad; + + // step through each parents link genes until we reach the end of both + while (!((t_curMom == m_LinkGenes.end()) && (t_curDad == a_Dad.m_LinkGenes.end()))) + { + t_selectedgene = t_emptygene; + t_skip = false; + t_innov_mom = t_innov_dad = 0; + + // the end of mum's genes have been reached + // EXCESS + if (t_curMom == m_LinkGenes.end()) + { + // select dads gene + t_selectedgene = *t_curDad; + // move onto dad's next gene + t_curDad++; + + // if mom is fittest, abort adding + if (t_better == MOM) + { + t_skip = true; + } + } + + // the end of dads's genes have been reached + // EXCESS + else if (t_curDad == a_Dad.m_LinkGenes.end()) + { + // add mums gene + t_selectedgene = *t_curMom; + // move onto mum's next gene + t_curMom++; + + // if dad is fittest, abort adding + if (t_better == DAD) + { + t_skip = true; + } + } + else + { + // extract the innovation numbers + t_innov_mom = t_curMom->InnovationID(); + t_innov_dad = t_curDad->InnovationID(); + + // if both innovations match + if (t_innov_mom == t_innov_dad) + { + // get a gene from either parent or average + if (a_RNG.RandFloat() < a_Parameters.MultipointCrossoverRate) + { + if (a_RNG.RandFloat() < a_Parameters.PreferFitterParentRate) + { + if (GetFitness() < a_Dad.GetFitness()) + { + t_selectedgene = *t_curMom; + } + else + { + t_selectedgene = *t_curDad; + } + } + else + { + if (a_RNG.RandFloat() < 0.5) + { + t_selectedgene = *t_curMom; + } + else + { + t_selectedgene = *t_curDad; + } + } + } + else + { + t_selectedgene = *t_curMom; + const double t_Weight = (t_curDad->GetWeight() + t_curMom->GetWeight()) / 2.0; + t_selectedgene.SetWeight(t_Weight); + // Mate traits here + t_selectedgene.MateTraits(t_curDad->m_Traits, a_RNG); + } + + // move onto next gene of each parent + t_curMom++; + t_curDad++; + } + else // DISJOINT + if (t_innov_mom < t_innov_dad) + { + t_selectedgene = *t_curMom; + t_curMom++; + + if (t_better == DAD) + { + t_skip = true; + } + } + else // DISJOINT + if (t_innov_dad < t_innov_mom) + { + t_selectedgene = *t_curDad; + t_curDad++; + + if (t_better == MOM) + { + t_skip = true; + } + } + } + + // for interspecies mating, allow all genes through + if (a_InterSpecies) + { + t_skip = false; + } + + // If the selected gene's innovation number is negative, + // this means that no gene is selected (should be skipped) + // also check the baby if it already has this link (maybe unnecessary) + if ((t_selectedgene.InnovationID() > 0) && + (!t_baby.HasLink(t_selectedgene.FromNeuronID(), t_selectedgene.ToNeuronID()))) + { + if (!t_skip) + { + t_baby.m_LinkGenes.emplace_back(t_selectedgene); + + // Check if we already have the nodes referred to in t_selectedgene. + // If not, they need to be added. + + //NeuronGene t_ngene1(NONE, 0, 0); + //NeuronGene t_ngene2(NONE, 0, 0); + + // mom has a neuron ID not present in the baby? + // From + if ((!t_baby.HasNeuronID(t_selectedgene.FromNeuronID())) && + (HasNeuronID(t_selectedgene.FromNeuronID()))) + { + // See if dad has the same neuron. + if (a_Dad.HasNeuronID(t_selectedgene.FromNeuronID())) + { + // if so, then choose randomly which neuron the baby shoud inherit + if (a_RNG.RandFloat() < a_Parameters.MultipointCrossoverRate) + { + if (a_RNG.RandFloat() < a_Parameters.PreferFitterParentRate) + { + if (GetFitness() > a_Dad.GetFitness()) + { + // add mom's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + m_NeuronGenes[GetNeuronIndex(t_selectedgene.FromNeuronID())]); + } + else + { + // add dad's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex( + t_selectedgene.FromNeuronID())]); + } + } + else + { + if (a_RNG.RandFloat() < 0.5) + { + // add mom's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + m_NeuronGenes[GetNeuronIndex(t_selectedgene.FromNeuronID())]); + } + else + { + // add dad's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex( + t_selectedgene.FromNeuronID())]); + } + } + } + else + { + // mate the neurons + NeuronGene t_1 = m_NeuronGenes[GetNeuronIndex(t_selectedgene.FromNeuronID())]; + NeuronGene t_2 = a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.FromNeuronID())]; + t_1.MateTraits(t_2.m_Traits, a_RNG); + t_baby.m_NeuronGenes.emplace_back(t_1); + } + } + else + { + // add mom's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + m_NeuronGenes[GetNeuronIndex(t_selectedgene.FromNeuronID())]); + } + } + + // To + if ((!t_baby.HasNeuronID(t_selectedgene.ToNeuronID())) && + (HasNeuronID(t_selectedgene.ToNeuronID()))) + { + // See if dad has the same neuron. + if (a_Dad.HasNeuronID(t_selectedgene.ToNeuronID())) + { + if (a_RNG.RandFloat() < a_Parameters.MultipointCrossoverRate) + { + if (a_RNG.RandFloat() < a_Parameters.PreferFitterParentRate) + { + if (GetFitness() > a_Dad.GetFitness()) + { + // add mom's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + m_NeuronGenes[GetNeuronIndex(t_selectedgene.ToNeuronID())]); + } + else + { + // add dad's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.ToNeuronID())]); + } + } + else + { + // if so, then choose randomly which neuron the baby shoud inherit + if (a_RNG.RandFloat() < 0.5) + { + // add mom's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + m_NeuronGenes[GetNeuronIndex(t_selectedgene.ToNeuronID())]); + } + else + { + // add dad's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.ToNeuronID())]); + } + } + } + else + { + // mate the neurons + NeuronGene t_1 = m_NeuronGenes[GetNeuronIndex(t_selectedgene.ToNeuronID())]; + NeuronGene t_2 = a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.ToNeuronID())]; + t_1.MateTraits(t_2.m_Traits, a_RNG); + t_baby.m_NeuronGenes.emplace_back(t_1); + } + } + else + { + // add mom's neuron to the baby + t_baby.m_NeuronGenes.emplace_back(m_NeuronGenes[GetNeuronIndex(t_selectedgene.ToNeuronID())]); + } + } + + // dad has a neuron ID not present in the baby? + // From + if ((!t_baby.HasNeuronID(t_selectedgene.FromNeuronID())) && + (a_Dad.HasNeuronID(t_selectedgene.FromNeuronID()))) + { + // See if mom has the same neuron + if (HasNeuronID(t_selectedgene.FromNeuronID())) + { + if (a_RNG.RandFloat() < a_Parameters.MultipointCrossoverRate) + { + if (a_RNG.RandFloat() < a_Parameters.PreferFitterParentRate) + { + if (GetFitness() < a_Dad.GetFitness()) + { + // add dad's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex( + t_selectedgene.FromNeuronID())]); + } + else + { + // add mom's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + m_NeuronGenes[GetNeuronIndex(t_selectedgene.FromNeuronID())]); + } + } + else + { + // if so, then choose randomly which neuron the baby shoud inherit + if (a_RNG.RandFloat() < 0.5) + { + // add dad's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex( + t_selectedgene.FromNeuronID())]); + } + else + { + // add mom's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + m_NeuronGenes[GetNeuronIndex(t_selectedgene.FromNeuronID())]); + } + } + } + else + { + // mate the neurons + NeuronGene t_1 = a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.FromNeuronID())]; + NeuronGene t_2 = m_NeuronGenes[GetNeuronIndex(t_selectedgene.FromNeuronID())]; + t_1.MateTraits(t_2.m_Traits, a_RNG); + t_baby.m_NeuronGenes.emplace_back(t_1); + } + } + else + { + // add dad's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.FromNeuronID())]); + } + } + + // To + if ((!t_baby.HasNeuronID(t_selectedgene.ToNeuronID())) && + (a_Dad.HasNeuronID(t_selectedgene.ToNeuronID()))) + { + // See if mom has the same neuron + if (HasNeuronID(t_selectedgene.ToNeuronID())) + { + if (a_RNG.RandFloat() < a_Parameters.MultipointCrossoverRate) + { + if (a_RNG.RandFloat() < a_Parameters.PreferFitterParentRate) + { + if (GetFitness() < a_Dad.GetFitness()) + { + // add dad's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.ToNeuronID())]); + } + else + { + // add mom's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + m_NeuronGenes[GetNeuronIndex(t_selectedgene.ToNeuronID())]); + } + } + else + { + // if so, then choose randomly which neuron the baby shoud inherit + if (a_RNG.RandFloat() < 0.5) + { + // add dad's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.ToNeuronID())]); + } + else + { + // add mom's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + m_NeuronGenes[GetNeuronIndex(t_selectedgene.ToNeuronID())]); + } + } + } + else + { + // mate neurons + NeuronGene t_1 = a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.ToNeuronID())]; + NeuronGene t_2 = m_NeuronGenes[GetNeuronIndex(t_selectedgene.ToNeuronID())]; + t_1.MateTraits(t_2.m_Traits, a_RNG); + t_baby.m_NeuronGenes.emplace_back(t_1); + } + } + else + { + // add dad's neuron to the baby + t_baby.m_NeuronGenes.emplace_back( + a_Dad.m_NeuronGenes[a_Dad.GetNeuronIndex(t_selectedgene.ToNeuronID())]); + } + } + } + } + } //end while + + t_baby.m_NumInputs = m_NumInputs; + t_baby.m_NumOutputs = m_NumOutputs; + + // Sort the baby's genes + t_baby.SortGenes(); + + return t_baby; + } + + + // Sorts the genes of the genome + // The neurons by IDs and the links by innovation numbers. + bool neuron_compare(NeuronGene& a_ls, NeuronGene& a_rs) + { + return a_ls.ID() < a_rs.ID(); + } + + bool link_compare(LinkGene& a_ls, LinkGene& a_rs) + { + return a_ls.InnovationID() < a_rs.InnovationID(); + } + + void Genome::SortGenes() + { + std::sort(m_NeuronGenes.begin(), m_NeuronGenes.end(), neuron_compare); + std::sort(m_LinkGenes.begin(), m_LinkGenes.end(), link_compare); + } + + unsigned int Genome::NeuronDepth(int a_NeuronID, unsigned int a_Depth) + { + unsigned int t_current_depth; + unsigned int t_max_depth = a_Depth; + + if (a_Depth > 16384) + { + // oops! a possible loop in the network! + // DBG(" ERROR! Trying to get the depth of a looped network!"); + return 16384; + } + + // Base case + if ((GetNeuronByID(a_NeuronID).Type() == INPUT) || (GetNeuronByID(a_NeuronID).Type() == BIAS)) + { + return a_Depth; + } + + // Find all links outputting to this neuron ID + std::vector t_inputting_links_idx; + for (unsigned int i = 0; i < NumLinks(); i++) + { + if (m_LinkGenes[i].ToNeuronID() == a_NeuronID) + t_inputting_links_idx.emplace_back(i); + } + + // For all incoming links.. + for (unsigned int i = 0; i < t_inputting_links_idx.size(); i++) + { + LinkGene t_link = GetLinkByIndex(t_inputting_links_idx[i]); + + // RECURSION + t_current_depth = NeuronDepth(t_link.FromNeuronID(), a_Depth + 1); + if (t_current_depth > t_max_depth) + t_max_depth = t_current_depth; + } + + return t_max_depth; + } + + + void Genome::CalculateDepth() + { + unsigned int t_max_depth = 0; + unsigned int t_cur_depth = 0; + + // The quick case - if no hidden neurons, + // the depth is 1 + if (NumNeurons() == (m_NumInputs + m_NumOutputs)) + { + m_Depth = 1; + return; + } + + // make a list of all output IDs + std::vector t_output_ids; + for (unsigned int i = 0; i < NumNeurons(); i++) + { + if (m_NeuronGenes[i].Type() == OUTPUT) + { + t_output_ids.emplace_back(m_NeuronGenes[i].ID()); + } + } + + // For each output + for (unsigned int i = 0; i < t_output_ids.size(); i++) + { + t_cur_depth = NeuronDepth(t_output_ids[i], 0); + + if (t_cur_depth > t_max_depth) + t_max_depth = t_cur_depth; + } + + m_Depth = t_max_depth; + } + + + + ////////////////////////////////////////////////////////////////////////////////// + // Saving/Loading methods + ////////////////////////////////////////////////////////////////////////////////// + + // Builds this genome from a file + Genome::Genome(const char *a_FileName) + { + std::ifstream t_DataFile(a_FileName); + *this = Genome(t_DataFile); + t_DataFile.close(); + } + + // Builds the genome from an *opened* file + Genome::Genome(std::ifstream &a_DataFile) + { + std::string t_Str; + + if (!a_DataFile) + { + ostringstream tStream; + tStream << "Genome file error!" << std::endl; + throw std::runtime_error("Genome file error!"); + } + + // search for GenomeStart + do + { + a_DataFile >> t_Str; + } + while (t_Str != "GenomeStart"); + + // read the genome ID + unsigned int t_gid; + a_DataFile >> t_gid; + m_ID = t_gid; + + // read the genome until GenomeEnd is encountered + do + { + a_DataFile >> t_Str; + + if (t_Str == "Neuron") + { + int t_id, t_type, t_activationfunc; + double t_splity, t_a, t_b, t_timeconst, t_bias; + + a_DataFile >> t_id; + a_DataFile >> t_type; + a_DataFile >> t_splity; + + a_DataFile >> t_activationfunc; + a_DataFile >> t_a; + a_DataFile >> t_b; + a_DataFile >> t_timeconst; + a_DataFile >> t_bias; + + // TODO read neuron traits + + NeuronGene t_neuron(static_cast(t_type), t_id, t_splity); + t_neuron.Init(t_a, t_b, t_timeconst, t_bias, static_cast(t_activationfunc)); + + m_NeuronGenes.emplace_back(t_neuron); + } + + if (t_Str == "Link") + { + int t_from, t_to, t_innov, t_isrecur; + double t_weight; + + a_DataFile >> t_from; + a_DataFile >> t_to; + a_DataFile >> t_innov; + a_DataFile >> t_isrecur; + a_DataFile >> t_weight; + + // TODO read link traits + + m_LinkGenes.emplace_back(LinkGene(t_from, t_to, t_innov, t_weight, static_cast(t_isrecur))); + } + } + while (t_Str != "GenomeEnd"); + + // Init additional stuff + // count inputs/outputs + m_NumInputs = 0; + m_NumOutputs = 0; + for (unsigned int i = 0; i < NumNeurons(); i++) + { + if ((m_NeuronGenes[i].Type() == INPUT) || (m_NeuronGenes[i].Type() == BIAS)) + { + m_NumInputs++; + } + + if (m_NeuronGenes[i].Type() == OUTPUT) + { + m_NumOutputs++; + } + } + + m_Fitness = 0.0; + m_AdjustedFitness = 0.0; + m_OffspringAmount = 0.0; + m_Depth = 0; + m_PhenotypeBehavior = NULL; + m_Evaluated = false; + } + + + // Saves this genome to a file + void Genome::Save(const char *a_FileName) + { + FILE *t_file; + t_file = fopen(a_FileName, "w"); + Save(t_file); + fclose(t_file); + } + + // Saves this genome to an already opened file for writing + void Genome::Save(FILE *a_file) + { + fprintf(a_file, "GenomeStart %d\n", GetID()); + + // loop over the neurons and save each one + for (unsigned int i = 0; i < NumNeurons(); i++) + { + // Save neuron + fprintf(a_file, "Neuron %d %d %3.8f %d %3.8f %3.8f %3.8f %3.8f\n", + m_NeuronGenes[i].ID(), static_cast(m_NeuronGenes[i].Type()), m_NeuronGenes[i].SplitY(), + static_cast(m_NeuronGenes[i].m_ActFunction), m_NeuronGenes[i].m_A, m_NeuronGenes[i].m_B, + m_NeuronGenes[i].m_TimeConstant, m_NeuronGenes[i].m_Bias); + // TODO write neuron traits + } + + // loop over the connections and save each one + for (unsigned int i = 0; i < NumLinks(); i++) + { + fprintf(a_file, "Link %d %d %d %d %3.8f\n", m_LinkGenes[i].FromNeuronID(), m_LinkGenes[i].ToNeuronID(), + m_LinkGenes[i].InnovationID(), static_cast(m_LinkGenes[i].IsRecurrent()), + m_LinkGenes[i].GetWeight()); + // TODO write link traits + } + + fprintf(a_file, "GenomeEnd\n\n"); + } + + void Genome::PrintTraits(std::map< std::string, Trait>& traits) + { + for(auto t = traits.begin(); t != traits.end(); t++) + { + bool doit = false; + std::string s = t->second.dep_key; + //std::string sv = bs::get(t->second.dep_values); + if (s != "") + { + // there is such trait.. + if (traits.count(s) != 0) + { + /*int a; double b; std::string c; + if ((*it).m_Traits[s].value.type() == typeid(int)) + a = bs::get((*it).m_Traits[s].value); + if ((*it).m_Traits[s].value.type() == typeid(double)) + b = bs::get((*it).m_Traits[s].value); + if ((*it).m_Traits[s].value.type() == typeid(std::string)) + c = bs::get((*it).m_Traits[s].value); + + int a1; double b1; std::string c1; + if ((t->second.dep_values).type() == typeid(int)) + a1 = bs::get((t->second.dep_values)); + if ((t->second.dep_values).type() == typeid(double)) + b1 = bs::get((t->second.dep_values)); + if ((t->second.dep_values).type() == typeid(std::string)) + c1 = bs::get((t->second.dep_values));*/ + + // and it has the right value? + for(int ix=0; ixsecond.dep_values.size(); ix++) + { + if (traits[s].value == (t->second.dep_values[ix])) + { + doit = true; + break; + } + } + } + } + else + { + doit = true; + } + + if (doit) + { + std::cout << t->first << " - "; + if (t->second.value.type() == typeid(int)) + { + std::cout << bs::get(t->second.value); + } + if (t->second.value.type() == typeid(double)) + { + std::cout << bs::get(t->second.value); + } + if (t->second.value.type() == typeid(std::string)) + { + std::cout << "\"" << bs::get(t->second.value) << "\""; + } + if (t->second.value.type() == typeid(intsetelement)) + { + std::cout << (bs::get(t->second.value)).value; + } + if (t->second.value.type() == typeid(floatsetelement)) + { + std::cout << (bs::get(t->second.value)).value; + } + + std::cout << ", "; + } + } + } + + void Genome::PrintAllTraits() + { + std::cout << "====================================================================\n"; + std::cout << "Genome:\n" + << "==================================\n"; + PrintTraits(m_GenomeGene.m_Traits); + + std::cout << "\n"; + + std::cout << "====================================================================\n"; + std::cout << "Neurons:\n" + << "==================================\n"; + for(auto it = m_NeuronGenes.begin(); it != m_NeuronGenes.end(); it++) + { + std::cout << "ID: " << it->ID() << " : "; + PrintTraits((*it).m_Traits); + + std::cout << "\n"; + } + std::cout << "==================================\n"; + + std::cout << "Links:\n" + << "==================================\n"; + for(auto it = m_LinkGenes.begin(); it != m_LinkGenes.end(); it++) + { + std::cout << "ID: " << it->InnovationID() << " : "; + PrintTraits((*it).m_Traits); + std::cout << "\n"; + } + std::cout << "==================================\n"; + std::cout << "====================================================================\n"; + } + + + //////////////////////////////////////////// + // Evovable Substrate Hyper NEAT. + // For more info on the algorithm check: http://eplex.cs.ucf.edu/ESHyperNEAT/ + //////////////////////////////////////////// + +#if 0 + + //divide and init for n dimensions + + void Genome::BuildESHyperNEATPhenotypeND(NeuralNetwork &net, Substrate &subst, Parameters ¶ms) + { + ASSERT(subst.m_input_coords.size() > 0); + ASSERT(subst.m_output_coords.size() > 0); + + unsigned int input_count = subst.m_input_coords.size(); + unsigned int output_count = subst.m_output_coords.size(); + unsigned int hidden_index = input_count + output_count; + unsigned int source_index = 0; + unsigned int target_index = 0; + unsigned int hidden_counter = 0; + unsigned int maxNodes = std::pow(4, params.MaxDepth); + unsigned int coord_len = subst.m_input_coords.at(0).size(); + std::vector TempConnections; + TempConnections.reserve(maxNodes + 1); + + std::vector point; + + point.reserve(coord_len); + + boost::shared_ptr root; + + boost::unordered_map, int> hidden_nodes; + hidden_nodes.reserve(maxNodes); + + boost::unordered_map, int> temp; + temp.reserve(maxNodes); + + boost::unordered_map, int> unexplored_nodes; + unexplored_nodes.reserve(maxNodes); + + net.m_neurons.reserve(maxNodes); + net.m_connections.reserve((maxNodes * (maxNodes - 1)) / 2); + net.SetInputOutputDimentions(static_cast(input_count), + static_cast(output_count)); + + + NeuralNetwork t_temp_phenotype(true); + BuildPhenotype(t_temp_phenotype); + + // Find Inputs to Hidden connections. + for (unsigned int i = 0; i < input_count; i++) + { + // Get the nTree + std::vector root_coord; + root_coord.reserve(coord_len); + for(unsigned int c_len = 0; c_len < coord_len; c_len++) + { + root_coord.push(0.0); + } + root = boost::shared_ptr( + new nTree(params.nTreeCoord, params.Width, params.Height, 1)); + DivideInitializeND(subst.m_input_coords[i], root, t_temp_phenotype, params, true, 0.0); + TempConnections.clear(); + PruneExpressND(subst.m_input_coords[i], root, t_temp_phenotype, params, TempConnections, true); + + for (unsigned int j = 0; j < TempConnections.size(); j++) + { + if (std::abs(TempConnections[j].weight * subst.m_max_weight_and_bias) < + 0.2/*subst.m_link_threshold*/) // TODO: fix this + continue; + + // Find the hidden node in the hidden nodes. If it is not there add it. + if (hidden_nodes.find(TempConnections[j].target) == hidden_nodes.end()) + { + target_index = hidden_counter++; + hidden_nodes.insert(std::make_pair(TempConnections[j].target, target_index)); + } + // Add connection + else + { + target_index = hidden_nodes.find(TempConnections[j].target)->second; + } + + Connection tc; + tc.m_source_neuron_idx = i; + tc.m_target_neuron_idx = target_index + hidden_index; + tc.m_weight = TempConnections[j].weight * subst.m_max_weight_and_bias; + tc.m_recur_flag = false; + + net.m_connections.push_back(tc); + + } + } + // Hidden to hidden. + // Basically the same procedure as above repeated IterationLevel times (see the params) + unexplored_nodes = hidden_nodes; + for (unsigned int i = 0; i < params.IterationLevel; i++) + { + boost::unordered_map, int>::iterator itr_hid; + for (itr_hid = unexplored_nodes.begin(); itr_hid != unexplored_nodes.end(); itr_hid++) + { + root = boost::shared_ptr( + new nTree(params.nTreeCoord, params.Width, params.Height, 1)); + DivideInitializeND(itr_hid->first, root, t_temp_phenotype, params, true, 0.0); + TempConnections.clear(); + PruneExpress(itr_hid->first, root, t_temp_phenotype, params, TempConnections, true); + //root.reset(); + + for (unsigned int k = 0; k < TempConnections.size(); k++) + { + if (std::abs(TempConnections[k].weight * subst.m_max_weight_and_bias) < + 0.2/*subst.m_link_threshold*/) // TODO: fix this + continue; + + if (hidden_nodes.find(TempConnections[k].target) == hidden_nodes.end()) + { + target_index = hidden_counter++; + hidden_nodes.insert(std::make_pair(TempConnections[k].target, target_index)); + } + else if(!params.feed_forward) // TODO: This can be skipped if building a feed forwad network. + { + target_index = hidden_nodes.find(TempConnections[k].target)->second; + } + + Connection tc; + tc.m_source_neuron_idx = itr_hid->second + hidden_index; // NO!!! + tc.m_target_neuron_idx = target_index + hidden_index; + tc.m_weight = TempConnections[k].weight * subst.m_max_weight_and_bias; + tc.m_recur_flag = false; + + net.m_connections.push_back(tc); + + } + } + // Now get the newly discovered hidden nodes + boost::unordered_map, int>::iterator itr1; + for (itr1 = hidden_nodes.begin(); itr1 != hidden_nodes.end(); itr1++) + { + if (unexplored_nodes.find(itr1->first) == unexplored_nodes.end()) + { + temp.insert(std::make_pair(itr1->first, itr1->second)); + } + } + unexplored_nodes = temp; + } + + // Finally Output to Hidden. Note that unlike before, here we connect the outputs to + // existing hidden nodes and no new nodes are added. + for (unsigned int i = 0; i < output_count; i++) + { + root = boost::shared_ptr( + new nTree(params.nTreeCoord, params.Width, params.Height, 1)); + DivideInitialize(subst.m_output_coords[i], root, t_temp_phenotype, params, false, 0.0); + TempConnections.clear(); + PruneExpress(subst.m_output_coords[i], root, t_temp_phenotype, params, TempConnections, false); + + for (unsigned int j = 0; j < TempConnections.size(); j++) + { + // Make sure the link weight is above the expected threshold. + if (std::abs(TempConnections[j].weight * subst.m_max_weight_and_bias) < + 0.2 /*subst.m_link_threshold*/) // TODO: fix this + continue; + + if (hidden_nodes.find(TempConnections[j].source) != hidden_nodes.end()) + { + source_index = hidden_nodes.find(TempConnections[j].source)->second; + + Connection tc; + tc.m_source_neuron_idx = source_index + hidden_index; + tc.m_target_neuron_idx = i + input_count; + + tc.m_weight = TempConnections[j].weight * subst.m_max_weight_and_bias; + tc.m_recur_flag = false; + + net.m_connections.push_back(tc); + } + } + } + // Add the neurons.Input first, followed by bias, output and hidden. In this order. + + for (unsigned int i = 0; i < input_count - 1; i++) + { + Neuron t_n; + t_n.m_a = 1; + t_n.m_b = 0; + t_n.m_substrate_coords = subst.m_input_coords[i]; + t_n.m_activation_function_type = NEAT::LINEAR; + t_n.m_type = NEAT::INPUT; + net.m_neurons.push_back(t_n); + } + // Bias n. + Neuron t_n; + t_n.m_a = 1; + t_n.m_b = 0; + t_n.m_substrate_coords = subst.m_input_coords[input_count - 1]; + t_n.m_activation_function_type = NEAT::LINEAR; + t_n.m_type = NEAT::BIAS; + net.m_neurons.push_back(t_n); + + for (unsigned int i = 0; i < output_count; i++) + { + Neuron t_n; + t_n.m_a = 1; + t_n.m_b = 0; + t_n.m_substrate_coords = subst.m_output_coords[i]; + t_n.m_activation_function_type = subst.m_output_nodes_activation; + t_n.m_type = NEAT::OUTPUT; + net.m_neurons.push_back(t_n); + } + + boost::unordered_map, int>::iterator itr; + for (itr = hidden_nodes.begin(); itr != hidden_nodes.end(); itr++) + { + Neuron t_n; + t_n.m_a = 1; + t_n.m_b = 0; + t_n.m_substrate_coords = itr->first; + + ASSERT(t_n.m_substrate_coords.size() > 0); // prevent 0D points + t_n.m_activation_function_type = subst.m_hidden_nodes_activation; + t_n.m_type = NEAT::HIDDEN; + net.m_neurons.push_back(t_n); + } + + // Clean the generated network from dangling connections and we're good to go. + Clean_Net(net.m_connections, input_count, output_count, hidden_nodes.size()); + } + + void Genome::BuildESHyperNEATPhenotype(NeuralNetwork &net, Substrate &subst, Parameters ¶ms) + { + ASSERT(subst.m_input_coords.size() > 0); + ASSERT(subst.m_output_coords.size() > 0); + + unsigned int input_count = subst.m_input_coords.size(); + unsigned int output_count = subst.m_output_coords.size(); + unsigned int hidden_index = input_count + output_count; + unsigned int source_index = 0; + unsigned int target_index = 0; + unsigned int hidden_counter = 0; + unsigned int maxNodes = std::pow(4, params.MaxDepth); + + std::vector TempConnections; + TempConnections.reserve(maxNodes + 1); + + std::vector point; + point.reserve(3); + + boost::shared_ptr root; + + boost::unordered_map, int> hidden_nodes; + hidden_nodes.reserve(maxNodes); + + boost::unordered_map, int> temp; + temp.reserve(maxNodes); + + boost::unordered_map, int> unexplored_nodes; + unexplored_nodes.reserve(maxNodes); + + net.m_neurons.reserve(maxNodes); + net.m_connections.reserve((maxNodes * (maxNodes - 1)) / 2); + net.SetInputOutputDimentions(static_cast(input_count), + static_cast(output_count)); + + + NeuralNetwork t_temp_phenotype(true); + BuildPhenotype(t_temp_phenotype); + + // Find Inputs to Hidden connections. + for (unsigned int i = 0; i < input_count; i++) + { + // Get the Quadtree and express the connections in it for this input + root = boost::shared_ptr( + new QuadPoint(params.Qtree_X, params.Qtree_Y, params.Width, params.Height, 1)); + DivideInitialize(subst.m_input_coords[i], root, t_temp_phenotype, params, true, 0.0); + TempConnections.clear(); + PruneExpress(subst.m_input_coords[i], root, t_temp_phenotype, params, TempConnections, true); + + for (unsigned int j = 0; j < TempConnections.size(); j++) + { + if (std::abs(TempConnections[j].weight * subst.m_max_weight_and_bias) < + 0.2/*subst.m_link_threshold*/) // TODO: fix this + continue; + + // Find the hidden node in the hidden nodes. If it is not there add it. + if (hidden_nodes.find(TempConnections[j].target) == hidden_nodes.end()) + { + target_index = hidden_counter++; + hidden_nodes.insert(std::make_pair(TempConnections[j].target, target_index)); + } + // Add connection + else + { + target_index = hidden_nodes.find(TempConnections[j].target)->second; + } + + Connection tc; + tc.m_source_neuron_idx = i; + tc.m_target_neuron_idx = target_index + hidden_index; + tc.m_weight = TempConnections[j].weight * subst.m_max_weight_and_bias; + tc.m_recur_flag = false; + + net.m_connections.emplace_back(tc); + + } + } + // Hidden to hidden. + // Basically the same procedure as above repeated IterationLevel times (see the params) + unexplored_nodes = hidden_nodes; + for (unsigned int i = 0; i < params.IterationLevel; i++) + { + boost::unordered_map, int>::iterator itr_hid; + for (itr_hid = unexplored_nodes.begin(); itr_hid != unexplored_nodes.end(); itr_hid++) + { + root = boost::shared_ptr( + new QuadPoint(params.Qtree_X, params.Qtree_Y, params.Width, params.Height, 1)); + DivideInitialize(itr_hid->first, root, t_temp_phenotype, params, true, 0.0); + TempConnections.clear(); + PruneExpress(itr_hid->first, root, t_temp_phenotype, params, TempConnections, true); + //root.reset(); + + for (unsigned int k = 0; k < TempConnections.size(); k++) + { + if (std::abs(TempConnections[k].weight * subst.m_max_weight_and_bias) < + 0.2/*subst.m_link_threshold*/) // TODO: fix this + continue; + + if (hidden_nodes.find(TempConnections[k].target) == hidden_nodes.end()) + { + target_index = hidden_counter++; + hidden_nodes.insert(std::make_pair(TempConnections[k].target, target_index)); + } + else // TODO: This can be skipped if building a feed forwad network. + { + target_index = hidden_nodes.find(TempConnections[k].target)->second; + } + + Connection tc; + tc.m_source_neuron_idx = itr_hid->second + hidden_index; // NO!!! + tc.m_target_neuron_idx = target_index + hidden_index; + tc.m_weight = TempConnections[k].weight * subst.m_max_weight_and_bias; + tc.m_recur_flag = false; + + net.m_connections.emplace_back(tc); + + } + } + // Now get the newly discovered hidden nodes + boost::unordered_map, int>::iterator itr1; + for (itr1 = hidden_nodes.begin(); itr1 != hidden_nodes.end(); itr1++) + { + if (unexplored_nodes.find(itr1->first) == unexplored_nodes.end()) + { + temp.insert(std::make_pair(itr1->first, itr1->second)); + } + } + unexplored_nodes = temp; + } + + // Finally Output to Hidden. Note that unlike before, here we connect the outputs to + // existing hidden nodes and no new nodes are added. + for (unsigned int i = 0; i < output_count; i++) + { + root = boost::shared_ptr( + new QuadPoint(params.Qtree_X, params.Qtree_Y, params.Width, params.Height, 1)); + DivideInitialize(subst.m_output_coords[i], root, t_temp_phenotype, params, false, 0.0); + TempConnections.clear(); + PruneExpress(subst.m_output_coords[i], root, t_temp_phenotype, params, TempConnections, false); + + for (unsigned int j = 0; j < TempConnections.size(); j++) + { + // Make sure the link weight is above the expected threshold. + if (std::abs(TempConnections[j].weight * subst.m_max_weight_and_bias) < + 0.2 /*subst.m_link_threshold*/) // TODO: fix this + continue; + + if (hidden_nodes.find(TempConnections[j].source) != hidden_nodes.end()) + { + source_index = hidden_nodes.find(TempConnections[j].source)->second; + + Connection tc; + tc.m_source_neuron_idx = source_index + hidden_index; + tc.m_target_neuron_idx = i + input_count; + + tc.m_weight = TempConnections[j].weight * subst.m_max_weight_and_bias; + tc.m_recur_flag = false; + + net.m_connections.emplace_back(tc); + } + } + } + // Add the neurons.Input first, followed by bias, output and hidden. In this order. + + for (unsigned int i = 0; i < input_count - 1; i++) + { + Neuron t_n; + t_n.m_a = 1; + t_n.m_b = 0; + t_n.m_substrate_coords = subst.m_input_coords[i]; + t_n.m_activation_function_type = NEAT::LINEAR; + t_n.m_type = NEAT::INPUT; + net.m_neurons.emplace_back(t_n); + } + // Bias n. + Neuron t_n; + t_n.m_a = 1; + t_n.m_b = 0; + t_n.m_substrate_coords = subst.m_input_coords[input_count - 1]; + t_n.m_activation_function_type = NEAT::LINEAR; + t_n.m_type = NEAT::BIAS; + net.m_neurons.emplace_back(t_n); + + for (unsigned int i = 0; i < output_count; i++) + { + Neuron t_n; + t_n.m_a = 1; + t_n.m_b = 0; + t_n.m_substrate_coords = subst.m_output_coords[i]; + t_n.m_activation_function_type = subst.m_output_nodes_activation; + t_n.m_type = NEAT::OUTPUT; + net.m_neurons.emplace_back(t_n); + } + + boost::unordered_map, int>::iterator itr; + for (itr = hidden_nodes.begin(); itr != hidden_nodes.end(); itr++) + { + Neuron t_n; + t_n.m_a = 1; + t_n.m_b = 0; + t_n.m_substrate_coords = itr->first; + + ASSERT(t_n.m_substrate_coords.size() > 0); // prevent 0D points + t_n.m_activation_function_type = subst.m_hidden_nodes_activation; + t_n.m_type = NEAT::HIDDEN; + net.m_neurons.emplace_back(t_n); + } + + // Clean the generated network from dangling connections and we're good to go. + Clean_Net(net.m_connections, input_count, output_count, hidden_nodes.size()); + } + // uses n dimensional sub division tree to determine placement of hidden nodes in the substrate + void Genome::DivideInitializeND(const std::vector &node, + boost::shared_ptr &root, + NeuralNetwork &cppn, + Parameters ¶ms, + const bool &outgoing) + { + int cpp_depth = 8; + + // some of the division, the permutation of center points in particular + // has been included with the tree struct + // and will simply be called here + std::vector t_inputs; + + boost::shared_ptr p; + std::queue > q; + q.push(p); + while(!q.empty()) + { + p = q.front(); + p.set_children(); + for (unsigned int i = 0; i < p->children.size(); i++) + { + t_inputs.clear(); + t_inputs.reserve(cppn.NumInputs()); + if(outgoing) + { + t_inputs = node; + for(unsigned int ci = 0; ci < node.size(); i++) + { + t_inputs.push_back(p->children[i]->coord[ci]); + } + } + else + { + t_inputs = p->children[i]->coord; + for(unsigned int ci = 0; ci < node.size(); i++) + { + t_inputs.push_back(node[ci]); + } + } + t_inputs[t_inputs.size() - 1] = (params.CPPN_Bias); + cppn.Flush(); + cppn.Input(t_inputs); + + for (int d = 0; d < cppn_depth; d++) + { + cppn.Activate(); + } + p->children[i]->weight = cppn.Output()[0]; + if (params.Leo) + { + p->children[i]->leo = cppn.Output()[cppn.Output().size() - 1]; + } + cppn.Flush(); + + } + + if ((p->level < params.InitialDepth) || + ((p->level < params.MaxDepth) && Variance(p) > params.DivisionThreshold)) + { + for(unsigned int add_idx = 0; add_idx < p->children.size(); add_idx) + { + q.push(p->children[add_idx]); + } + } + q.pop(); + } + return; + + } + // Used to determine the placement of hidden neurons in the Evolvable Substrate. + void Genome::DivideInitialize(const std::vector &node, + boost::shared_ptr &root, + NeuralNetwork &cppn, + Parameters ¶ms, + const bool &outgoing, + const double &z_coord) + { // Have to check if this actually does something useful here + //CalculateDepth(); + int cppn_depth = 8;//GetDepth(); + + std::vector t_inputs; + + // Standard Tree stuff. Create children, check their output with the CPPN + // and if they have higher variance add them to their parent. Repeat with the children + // until maxDepth has been reached or if the variance isn't high enough. + boost::shared_ptr p; + + std::queue > q; + q.push(root); + while (!q.empty()) + { + p = q.front(); + // Add children + p->children.emplace_back(boost::shared_ptr( + new QuadPoint(p->x - p->width / 2, p->y - p->height / 2, p->width / 2, p->height / 2, + p->level + 1))); + p->children.emplace_back(boost::shared_ptr( + new QuadPoint(p->x - p->width / 2, p->y + p->height / 2, p->width / 2, p->height / 2, + p->level + 1))); + p->children.emplace_back(boost::shared_ptr( + new QuadPoint(p->x + p->width / 2, p->y + p->height / 2, p->width / 2, p->height / 2, + p->level + 1))); + p->children.emplace_back(boost::shared_ptr( + new QuadPoint(p->x + p->width / 2, p->y - p->height / 2, p->width / 2, p->height / 2, + p->level + 1))); + + for (unsigned int i = 0; i < p->children.size(); i++) + { + t_inputs.clear(); + t_inputs.reserve(cppn.NumInputs()); + + if (outgoing) + { + // node goes here + t_inputs = node; + + t_inputs.emplace_back(p->children[i]->x); + t_inputs.emplace_back(p->children[i]->y); + t_inputs.emplace_back(p->children[i]->z); + } + + else + { + // QuadPoint goes first + t_inputs.emplace_back(p->children[i]->x); + t_inputs.emplace_back(p->children[i]->y); + t_inputs.emplace_back(p->children[i]->z); + + t_inputs.emplace_back(node[0]); + t_inputs.emplace_back(node[1]); + t_inputs.emplace_back(node[2]); + } + + // Bias + t_inputs[t_inputs.size() - 1] = (params.CPPN_Bias); + + cppn.Flush(); + cppn.Input(t_inputs); + + for (int d = 0; d < cppn_depth; d++) + { + cppn.Activate(); + } + p->children[i]->weight = cppn.Output()[0]; + if (params.Leo) + { + p->children[i]->leo = cppn.Output()[cppn.Output().size() - 1]; + } + cppn.Flush(); + + } + + if ((p->level < params.InitialDepth) || + ((p->level < params.MaxDepth) && Variance(p) > params.DivisionThreshold)) + { + for (unsigned int i = 0; i < 4; i++) + { + q.push(p->children[i]); + } + } + q.pop(); + + } + + return; + } + + void Genome::PruneExpressND(const std::vector &node, + boost::shared_ptr &root, + NeuralNetwork &cppn, + Parameters ¶ms, + std::vector &connections, + const bool &outgoing) + { + if (root->children[0] == NULL) + { + return; + } + + else + { + for (unsigned int i = 0; i < root->children.size(); i++) + { + if(Variance(root->children[i]) > params.VarianceThreshold) + { + PruneExpressND(node, root->children[i], cppn, params, connections, outgoing); + } + + else if(!params.Leo || (params.Leo && root->children[i]->leo > params.LeoThreshold)) + { + int cpp_depth = 8; //seems to be hard coded across the codebase, seems like plenty of depth to me! + std::vector child_array; + for(unsigned int c_ix = 0; c_ix < root->children[i]->coord.size(); c_ix++) + { + std::vector full_in; + std::vector full_in2; + std::vector inputs2; + std::vector inputs; + int root_index = 0; + int sign = -1; + double dimen_split1 = root->children[i]->coord[c_ix] - root->width; + double dimen_split2 = root->children[i]->coord[c_ix] + root->width; + for(unsigned int c2_ix = 0; c2_ix < node.size(); c2_ix++) + { + if(c2_ix == c_ix) + { + inputs.append(root->children[i].coord.at(c2_ix)); + inputs2.append(root->children[i]->coord.at(c2_ix)); + } else { + inputs.append(dimen_split2); + inputs2.append(dimen_split1); + } + } + if(outgoing) + { + full_in = node; + full_in2 = full_in; + fulll_in.insert(full_in.end(), inputs.begin(), inputs.end()); + full_in2.insert(full_in2.end(), inputs2.begin(), inputs2.end()); + } + else + { + full_in2 = inputs2; + full_in = inputs; + full_in2.insert(full_in2.end(), node.begin(), node.end()); + full_in.insert(full_in.end(), node.begin(), node.end()); + } + full_in.push_back(params.CPPN_Bias); + full_in2.push_back(params.CPPN_Bias); + cppn.Inputs(full_in); + child_array.append(cppn.Activate()[0]); + for (int d = 0; d < cppn_depth; d++) + { + cppn.Activate(); + } + child_array.append(Abs(root->child[i]->weight - Output()[0])); + cppn.Flush(); + cppn.Inputs(full_in2); + child_array.append(cppn.Activate()[0]); + for (int d = 0; d < cppn_depth; d++) + { + cppn.Activate(); + } + child_array.append(Abs(root->child[i]->weight - Output()[0])); + } + double biggest_smallest = std::min(child_array[0], child_array[1]); + unsigned int pair_idx = 2; + while(pair_idx < child_array.size()/2) + { + unsigned int new_min = std::min(child_array[pair_idx], child_array[pair_idx + 1]); + if(new_min > biggest_smallest) + { + biggest_smallest = new_min; + } + pair_idx += 2; + } + if(biggest_smallest > params.BandThreshold) + { + if(outgoing) + { + TempConnection tc(node, root->children[i]->coord, root->children[i]->weight, node.size()); + } + else + { + TempConnection tc(root->children[i]->coord, node, root->children[i]->weight, node.size()); + } + connections.push_back(tc); + } + } + } + } + // We take the tree generated above and see which connections can be expressed on the basis of Variance threshold, + // Band threshold and LEO. + void Genome::PruneExpress(const std::vector &node, + boost::shared_ptr &root, + NeuralNetwork &cppn, + Parameters ¶ms, + std::vector &connections, + const bool &outgoing) + { + if (root->children[0] == NULL) + { + return; + } + + else + { + for (unsigned int i = 0; i < 4; i++) + { + if (Variance(root->children[i]) > params.VarianceThreshold) + { + PruneExpress(node, root->children[i], cppn, params, connections, outgoing); + } + + // Band Pruning phase. + // If LEO is turned off this should always happen. + // If it is not it should only happen if the LEO output is greater than a specified threshold + else if (!params.Leo || (params.Leo && root->children[i]->leo > params.LeoThreshold)) + { + //CalculateDepth(); + int cppn_depth = 8;//GetDepth(); + + double d_left, d_right, d_top, d_bottom; + std::vector inputs; + + int root_index = 0; + + if (outgoing) + { + inputs = node; + inputs.emplace_back(root->children[i]->x); + inputs.emplace_back(root->children[i]->y); + inputs.emplace_back(root->children[i]->z); + + root_index = node.size(); + } + + else + { + inputs.emplace_back(root->children[i]->x); + inputs.emplace_back(root->children[i]->y); + inputs.emplace_back(root->children[i]->z); + inputs.emplace_back(node[0]); + inputs.emplace_back(node[1]); + inputs.emplace_back(node[2]); + } + + // Left + inputs.emplace_back(params.CPPN_Bias); + inputs[root_index] -= root->width; + + cppn.Input(inputs); + + for (int d = 0; d < cppn_depth; d++) + { + cppn.Activate(); + } + + d_left = Abs(root->children[i]->weight - cppn.Output()[0]); + cppn.Flush(); + + // Right + inputs[root_index] += 2 * (root->width); + cppn.Input(inputs); + + for (int d = 0; d < cppn_depth; d++) + { + cppn.Activate(); + } + + d_right = Abs(root->children[i]->weight - cppn.Output()[0]); + cppn.Flush(); + + // Top + inputs[root_index] -= root->width; + inputs[root_index + 1] -= root->width; + cppn.Input(inputs); + + for (int d = 0; d < cppn_depth; d++) + { + cppn.Activate(); + } + + d_top = Abs(root->children[i]->weight - cppn.Output()[0]); + cppn.Flush(); + // Bottom + inputs[root_index + 1] += 2 * root->width; + cppn.Input(inputs); + + for (int d = 0; d < cppn_depth; d++) + { + cppn.Activate(); + } + + d_bottom = Abs(root->children[i]->weight - cppn.Output()[0]); + cppn.Flush(); + + if (std::max(std::min(d_top, d_bottom), std::min(d_left, d_right)) > params.BandThreshold) + { + Genome::TempConnection tc; + //Yeah its ugly + if (outgoing) + { + tc.source = node; + + tc.target.emplace_back(root->children[i]->x); + tc.target.emplace_back(root->children[i]->y); + tc.target.emplace_back(root->children[i]->z); + } + else + { + tc.source.emplace_back(root->children[i]->x); + tc.source.emplace_back(root->children[i]->y); + tc.source.emplace_back(root->children[i]->z); + + tc.target = node; + } + // Normalize + // TODO: Put in Parameters + tc.weight = root->children[i]->weight; + connections.emplace_back(tc); + } + } + } + } + return; + } + + double Genome::VarianceND(boost::shared_ptr &point){ + if(point->children.size() == 0){ + return 0.0; + } + + boost::accumulators::accumulator_set > acc; + for (unsigned int i = 0; i < point->children.size(); i++){ + acc(point->children[i]->weight);) + } + return boost::accumulators::variance(acc); + } + // Calculates the variance of a given Quadpoint. + // Maybe an alternative solution would be to add this in the Quadpoint const. + double Genome::Variance(boost::shared_ptr &point) + { + if (point->children.size() == 0) + { + return 0.0; + } + + boost::accumulators::accumulator_set > acc; + for (unsigned int i = 0; i < 4; i++) + { + acc(point->children[i]->weight); + } + + return boost::accumulators::variance(acc); + } + + // Helper method for Variance + void Genome::CollectValues(std::vector &vals, boost::shared_ptr &point) + { + //In theory we shouldn't get here at all. + if (point == NULL) + { + return; + } + + if (point->children.size() > 0) + { + for (unsigned int i = 0; i < 4; i++) + { + CollectValues(vals, point->children[i]); + } + } + + else + { // Here, Apparently it treats the point a if it is not initialized + vals.emplace_back(point->weight); + } + } + + + // Removes all the dangling connections. This still leaves the nodes though, + void Genome::Clean_Net(std::vector &connections, unsigned int input_count, + unsigned int output_count, unsigned int hidden_count) + { + bool loose_connections = true; + int node_count = input_count + output_count + hidden_count; + std::vector temp; + temp.reserve(connections.size()); + while (loose_connections) + { + std::vector hasOutgoing(node_count, false); + std::vector hasIncoming(node_count, false); + // Make sure inputs and outputs are covered. + for (unsigned int i = 0; i < output_count + input_count; i++) + { + hasOutgoing[i] = true; + hasIncoming[i] = true; + } + + // Move on to the nodes. + for (unsigned int i = 0; i < connections.size(); i++) + { + if (connections[i].m_source_neuron_idx != connections[i].m_target_neuron_idx) + { + hasOutgoing[connections[i].m_source_neuron_idx] = true; + hasIncoming[connections[i].m_target_neuron_idx] = true; + } + + } + + loose_connections = false; + + std::vector::iterator itr; + for (itr = connections.begin(); itr < connections.end();) + { + if (!hasOutgoing[itr->m_target_neuron_idx] || !hasIncoming[itr->m_source_neuron_idx]) + { + itr = connections.erase(itr); + if (!loose_connections) + { + loose_connections = true; + } + + } + else + { + itr++; + } + } + } + } +#endif + +} // namespace NEAT diff --git a/src/Genome.h b/src/Genome.h index e07c18ef..15221dbe 100644 --- a/src/Genome.h +++ b/src/Genome.h @@ -1,815 +1,886 @@ -#ifndef _GENOME_H -#define _GENOME_H - -/////////////////////////////////////////////////////////////////////////////////////////// -// MultiNEAT - Python/C++ NeuroEvolution of Augmenting Topologies Library -// -// Copyright (C) 2012 Peter Chervenski -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRbbbbbbbbbbANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see < http://www.gnu.org/licenses/ >. -// -// Contact info: -// -// Peter Chervenski < spookey@abv.bg > -// Shane Ryan < shane.mcdonald.ryan@gmail.com > -/////////////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// File: Genome.h -// Description: Definition for the Genome class. -/////////////////////////////////////////////////////////////////////////////// - -#ifdef USE_BOOST_PYTHON - -#include -#include -#include -#include -#include - -#endif - -#include - -#include -#include -#include - -#include -#include - -#include "NeuralNetwork.h" -#include "Substrate.h" -#include "Innovation.h" -#include "Genes.h" -#include "Assert.h" -#include "PhenotypeBehavior.h" -#include "Random.h" - -namespace NEAT -{ - - ////////////////////////////////////////////// - // The Genome class - ////////////////////////////////////////////// - - // forward - class Innovation; - - class InnovationDatabase; - - class PhenotypeBehavior; - - extern ActivationFunction GetRandomActivation(Parameters &a_Parameters, RNG &a_RNG); - - namespace bs = boost; - - typedef bs::adjacency_list Graph; - typedef bs::graph_traits::vertex_descriptor Vertex; - - class Genome - { - ///////////////////// - // Members - ///////////////////// - private: - - // ID of genome - unsigned int m_ID; - - // How many inputs/outputs - unsigned int m_NumInputs; - unsigned int m_NumOutputs; - - // The genome's fitness score - double m_Fitness; - - // The genome's adjusted fitness score - double m_AdjustedFitness; - - // The depth of the network - unsigned int m_Depth; - - // how many individuals this genome should spawn - double m_OffspringAmount; - - //////////////////// - // Private methods - - // Returns true if the specified neuron ID is present in the genome - bool HasNeuronID(int a_id) const; - - // Returns true if the specified link is present in the genome - bool HasLink(int a_n1id, int a_n2id) const; - - // Returns true if the specified link is present in the genome - bool HasLinkByInnovID(int a_id) const; - - // Removes the link with the specified innovation ID - void RemoveLinkGene(int a_innovid); - - // Remove node - // Links connected to this node are also removed - void RemoveNeuronGene(int a_id); - - // Returns the count of links inputting from the specified neuron ID - int LinksInputtingFrom(int a_id) const; - - // Returns the count of links outputting to the specified neuron ID - int LinksOutputtingTo(int a_id) const; - - // A recursive function returning the max depth from the specified neuron to the inputs - unsigned int NeuronDepth(int a_NeuronID, unsigned int a_Depth); - - // Returns true is the specified neuron ID is a dead end or isolated - bool IsDeadEndNeuron(int a_id) const; - - public: - - // The two lists of genes - std::vector m_NeuronGenes; - std::vector m_LinkGenes; - - // To have traits that belong to the genome itself - Gene m_GenomeGene; - - // tells whether this genome was evaluated already - // used in steady state evolution - bool m_Evaluated; - - // the initial genome complexity - int m_initial_num_neurons; - int m_initial_num_links; - - // A pointer to a class representing the phenotype's behavior - // Used in novelty searches - PhenotypeBehavior *m_PhenotypeBehavior; - // A Python object behavior -#ifdef USE_BOOST_PYTHON - py::object m_behavior; -#endif - - //////////////////////////// - // Constructors - //////////////////////////// - - Genome(); - - // copy constructor - Genome(const Genome &a_g); - - // assignment operator - Genome &operator=(const Genome &a_g); - - // comparison operator (nessesary for boost::python) - // todo: implement a better comparison technique - bool operator==(Genome const &other) const - { - return m_ID == other.m_ID; - } - - // Builds this genome from a file - Genome(const char *a_filename); - - // Builds this genome from an opened file - Genome(std::ifstream &a_DataFile); - - // This creates a CTRNN fully-connected genome - Genome(unsigned int a_ID, unsigned int a_NumInputs, unsigned int a_NumHidden, unsigned int a_NumOutputs, - ActivationFunction a_OutputActType, ActivationFunction a_HiddenActType, const Parameters &a_Parameters); - - // This creates a standart minimal genome - perceptron-like structure - Genome(unsigned int a_ID, - unsigned int a_NumInputs, - unsigned int a_NumHidden, // ignored for seed_type == 0, specifies number of hidden units if seed_type == 1 - unsigned int a_NumOutputs, - bool a_FS_NEAT, ActivationFunction a_OutputActType, - ActivationFunction a_HiddenActType, - unsigned int a_SeedType, - const Parameters &a_Parameters, - unsigned int a_NumLayers); - - ///////////// - // Other possible constructors for different types of networks go here - // TODO - - - //////////////////////////// - // Destructor - //////////////////////////// - - //////////////////////////// - // Methods - //////////////////////////// - - //////////////////// - // Accessor methods - - NeuronGene GetNeuronByID(int a_ID) const; - - NeuronGene GetNeuronByIndex(int a_idx) const; - - LinkGene GetLinkByInnovID(int a_ID) const; - - LinkGene GetLinkByIndex(int a_idx) const; - - // A little helper function to find the index of a neuron, given its ID - int GetNeuronIndex(int a_id) const; - - // A little helper function to find the index of a link, given its innovation ID - int GetLinkIndex(int a_innovid) const; - - unsigned int NumNeurons() const - { return static_cast(m_NeuronGenes.size()); } - - unsigned int NumLinks() const - { return static_cast(m_LinkGenes.size()); } - - unsigned int NumInputs() const - { return m_NumInputs; } - - unsigned int NumOutputs() const - { return m_NumOutputs; } - - void SetNeuronXY(unsigned int a_idx, int a_x, int a_y); - - void SetNeuronX(unsigned int a_idx, int a_x); - - void SetNeuronY(unsigned int a_idx, int a_y); - - double GetFitness() const; - - double GetAdjFitness() const; - - void SetFitness(double a_f); - - void SetAdjFitness(double a_af); - - unsigned int GetID() const; - - void SetID(unsigned int a_id); - - unsigned int GetDepth() const; - - void SetDepth(unsigned int a_d); - - // Returns true if there is any dead end in the network - bool HasDeadEnds() const; - - // Returns true if there is any looping path in the network - bool HasLoops(); - - bool FailsConstraints(const Parameters &a_Parameters) - { - bool fails = false; - - if (HasDeadEnds() || (NumLinks() == 0)) - { - return true; // no reason to continue - } - - if ((HasLoops() && (a_Parameters.AllowLoops == false))) - { - return true; - } - - // Custom constraints - if (a_Parameters.CustomConstraints != NULL) - { - if (a_Parameters.CustomConstraints(*this)) - { - return true; - } - } - - // for Python-based custom constraint callbacks -#ifdef USE_BOOST_PYTHON - if (a_Parameters.pyCustomConstraints.ptr() != py::object().ptr()) // is it not None? - { - return py::extract(a_Parameters.pyCustomConstraints(*this)); - } -#endif - // add more constraints here - return false; - } - - double GetOffspringAmount() const; - - void SetOffspringAmount(double a_oa); - - // This builds a fastnetwork structure out from the genome - void BuildPhenotype(NeuralNetwork &net); - - // Projects the phenotype's weights back to the genome - void DerivePhenotypicChanges(NeuralNetwork &a_Net); - - //////////// - // Other possible methods for building a phenotype go here - // Like CPPN/HyperNEAT stuff - //////////// - void BuildHyperNEATPhenotype(NeuralNetwork &net, Substrate &subst); - -#ifdef USE_BOOST_PYTHON - - py::dict TraitMap2Dict(std::map< std::string, Trait>& tmap) - { - py::dict traits; - for(auto tit=tmap.begin(); tit!=tmap.end(); tit++) - { - bool doit = false; - if (tit->second.dep_key != "") - { - // there is such trait.. - if (tmap.count(tit->second.dep_key) != 0) - { - // and it has the right value? - for(int ix=0; ix < tit->second.dep_values.size(); ix++) - { - if (tmap[tit->second.dep_key].value == tit->second.dep_values[ix]) - { - doit = true; - break; - } - } - } - } - else - { - doit = true; - } - - if (doit) - { - TraitType t = tit->second.value; - if (t.type() == typeid(int)) - { - traits[tit->first] = bs::get(t); - } - if (t.type() == typeid(double)) - { - traits[tit->first] = bs::get(t); - } - if (t.type() == typeid(std::string)) - { - traits[tit->first] = bs::get(t); - } - if (t.type() == typeid(intsetelement)) - { - traits[tit->first] = (bs::get(t)).value; - } - if (t.type() == typeid(floatsetelement)) - { - traits[tit->first] = (bs::get(t)).value; - } - if (t.type() == typeid(py::object)) - { - traits[tit->first] = bs::get(t); - } - } - } - - return traits; - } - - py::object GetNeuronTraits() - { - py::list neurons; - for(auto it=m_NeuronGenes.begin(); it != m_NeuronGenes.end(); it++) - { - - py::dict traits = TraitMap2Dict((*it).m_Traits); - - py::list little; - little.append( (*it).ID() ); - - if ((*it).Type() == INPUT) - { - little.append( "input" ); - } - else if ((*it).Type() == BIAS) - { - little.append( "bias" ); - } - else if ((*it).Type() == HIDDEN) - { - little.append( "hidden" ); - } - else if ((*it).Type() == OUTPUT) - { - little.append( "output" ); - } - little.append( traits ); - neurons.append( little ); - } - - return neurons; - } - - py::object GetLinkTraits() - { - py::list links; - for(auto it=m_LinkGenes.begin(); it != m_LinkGenes.end(); it++) - { - py::dict traits = TraitMap2Dict((*it).m_Traits); - - py::list little; - little.append( (*it).FromNeuronID() ); - little.append( (*it).ToNeuronID() ); - little.append( traits ); - links.append( little ); - } - - return links; - } - - py::dict GetGenomeTraits() - { - return TraitMap2Dict(m_GenomeGene.m_Traits); - } - -#endif - - // Saves this genome to a file - void Save(const char *a_filename); - - // Saves this genome to an already opened file for writing - void Save(FILE *a_fstream); - - void PrintTraits(std::map< std::string, Trait>& traits); - void PrintAllTraits(); - - // returns the max neuron ID - int GetLastNeuronID() const; - - // returns the max innovation Id - int GetLastInnovationID() const; - - // Sorts the genes of the genome - // The neurons by IDs and the links by innovation numbers. - void SortGenes(); - - // overload '<' used for sorting. From fittest to poorest. - friend bool operator<(const Genome &a_lhs, const Genome &a_rhs) - { - return (a_lhs.m_Fitness > a_rhs.m_Fitness); - } - - // Returns true if this genome and a_G are compatible (belong in the same species) - bool IsCompatibleWith(Genome &a_G, Parameters &a_Parameters); - - // returns the absolute compatibility distance between this genome and a_G - double CompatibilityDistance(Genome &a_G, Parameters &a_Parameters); - - // Calculates the network depth - void CalculateDepth(); - - //////////// - // Mutation - //////////// - - // Adds a new neuron to the genome - // returns true if succesful - bool Mutate_AddNeuron(InnovationDatabase &a_Innovs, const Parameters &a_Parameters, RNG &a_RNG); - - // Adds a new link to the genome - // returns true if succesful - bool Mutate_AddLink(InnovationDatabase &a_Innovs, const Parameters &a_Parameters, RNG &a_RNG); - - // Remove a random link from the genome - // A cleanup procedure is invoked so any dead-ends or stranded neurons are also deleted - // returns true if succesful - bool Mutate_RemoveLink(RNG &a_RNG); - - // Removes a hidden neuron having only one input and only one output with - // a direct link between them. - bool Mutate_RemoveSimpleNeuron(InnovationDatabase &a_Innovs, RNG &a_RNG); - - // Perturbs the weights - bool Mutate_LinkWeights(const Parameters &a_Parameters, RNG &a_RNG); - - // Set all link weights to random values between [-R .. R] - void Randomize_LinkWeights(double a_Range, RNG &a_RNG); - - // Set all traits to random values - void Randomize_Traits(const Parameters& a_Parameters, RNG &a_RNG); - - // Perturbs the A parameters of the neuron activation functions - bool Mutate_NeuronActivations_A(const Parameters &a_Parameters, RNG &a_RNG); - - // Perturbs the B parameters of the neuron activation functions - bool Mutate_NeuronActivations_B(const Parameters &a_Parameters, RNG &a_RNG); - - // Changes the activation function type for a random neuron - bool Mutate_NeuronActivation_Type(const Parameters &a_Parameters, RNG &a_RNG); - - // Perturbs the neuron time constants - bool Mutate_NeuronTimeConstants(const Parameters &a_Parameters, RNG &a_RNG); - - // Perturbs the neuron biases - bool Mutate_NeuronBiases(const Parameters &a_Parameters, RNG &a_RNG); - - // Perturbs the neuron traits - bool Mutate_NeuronTraits(const Parameters &a_Parameters, RNG &a_RNG); - - // Perturbs the link traits - bool Mutate_LinkTraits(const Parameters &a_Parameters, RNG &a_RNG); - - // Perturbs the genome traits - bool Mutate_GenomeTraits(const Parameters &a_Parameters, RNG &a_RNG); - - /////////// - // Mating - /////////// - - - // Mate this genome with dad and return the baby - // If this is multipoint mating, genes are inherited randomly - // If the a_averagemating bool is true, then the genes are averaged - // Disjoint and excess genes are inherited from the fittest parent - // If fitness is equal, the smaller genome is assumed to be the better one - Genome Mate(Genome &a_dad, bool a_averagemating, bool a_interspecies, RNG &a_RNG, Parameters &a_Parameters); - - - ////////// - // Utility - ////////// - - // Search the genome for isolated structure and clean it up - // Returns true is something was removed - bool Cleanup(); - - //////////////////// - // new stuff - bool IsEvaluated() const; - - void SetEvaluated(); - - void ResetEvaluated(); - - - ///////////////////////////////////////////// - // Evolvable Substrate HyperNEAT - //////////////////////////////////////////// - - // A connection between two points. Stores weight and the coordinates of the points - struct TempConnection - { - std::vector source; - std::vector target; - double weight; - - TempConnection() - { - source.reserve(3); - target.reserve(3); - weight = 0; - } - - TempConnection(std::vector t_source, std::vector t_target, - double t_weight) - { - source = t_source; - target = t_target; - weight = t_weight; - source.reserve(3); - target.reserve(3); - } - - TempConnection(std::vector t_source, std::vector t_target, double t_weight, unsigned int coord_size) - { - source = t_source; - target = t_target; - weight = t_weight; - } - - ~TempConnection() - {}; - - bool operator==(const TempConnection &rhs) const - { - return (source == rhs.source && target == rhs.target); - } - - bool operator!=(const TempConnection &rhs) const - { - return (source != rhs.source && target != rhs.target); - } - }; - - // A quadpoint in the HyperCube. - struct QuadPoint - { - double x; - double y; - double z; - double width; - double weight; - double height; - double variance; - int level; - // Do I use this? - double leo; - - - std::vector > children; - - QuadPoint() - { - x = y = z = width = height = weight = variance = leo = 0; - level = 0; - children.reserve(4); - } - - QuadPoint(double t_x, double t_y, double t_width, double t_height, int t_level) - { - x = t_x; - y = t_y; - z = 0.0; - width = t_width; - height = t_height; - level = t_level; - weight = 0.0; - leo = 0.0; - variance = 0.0; - children.reserve(4); - children.clear(); - } - - // Mind the Z - QuadPoint(double t_x, double t_y, double t_z, double t_width, double t_height, - int t_level) - { - x = t_x; - y = t_y; - z = t_z; - width = t_width; - height = t_height; - level = t_level; - weight = 0.0; - variance = 0.0; - leo = 0.0; - children.reserve(4); - children.clear(); - } - - ~QuadPoint() - { - }; - }; - - - struct nTree - { - std::vector coord; - double weight; - double varience; - int lvl; - double width; - double leo = 0.0; - std::vector > children; - - nTree(std::vector coord_in, double wdth, double level) - { - width = wdth; - lvl = level; - coord = coord_in; - }; - - public void set_children() - { - for(unsigned int ix = 0; ix < 2**coord.size(); ix++){ - std::string sum_permute = toBinary(ix, coord.size()); - std::vector child_coords; - int child_param_len = sum_permute.length(); - child_coords.reserve(child_param_len); - for(unsigned int sign_ix = 0; sign_ix < child_param_len; sign_ix++) - { - if(sum_permute[sign_ix] == "0") - { - child_coords.push_back(coord[sign_ix] + width/2.0); - } - else - { - child_coords.push_back(coord[sign_ix] - width/2.0); - } - children.push_back(new nTree(child_coords, width/2.0, sslvl+1)); - } - } - } - - string toBinary(unsigned int n, int min_len) - { - std::string r; - while(n!=0) - { - r=(n%2==0 ?"0":"1")+r; n/=2; - - } - if(r.length() < min_len) - { - int diff = min_len - r.length(); - for(unsigned int x = 0; x < diff; x++) - { - r = '0' +r; - } - } - return r; - } - }; - void BuildESHyperNEATPhenotypeND(NeuralNetwork &a_net, Substrate &subst, Parameters ¶ms); - void BuildESHyperNEATPhenotype(NeuralNetwork &a_net, Substrate &subst, Parameters ¶ms); - - void DivideInitialize(const std::vector &node, - boost::shared_ptr &root, - NeuralNetwork &cppn, Parameters ¶ms, - const bool &outgoing, const double &z_coord); - - void PruneExpress(const std::vector &node, - boost::shared_ptr &root, NeuralNetwork &cppn, - Parameters ¶ms, std::vector &connections, - const bool &outgoing); - void DivideInitializeND(const std::vector &node, - boost::shared_ptr &root, - NeuralNetwork &cppn, Parameters ¶ms, - const bool &outgoing, const double &z_coord); - - void PruneExpressND(const std::vector &node, - boost::shared_ptr &root, NeuralNetwork &cppn, - Parameters ¶ms, std::vector &connections, - const bool &outgoing); - - - void CollectValues(std::vector &vals, boost::shared_ptr &point); - - double Variance(boost::shared_ptr &point); - - void Clean_Net(std::vector &connections, unsigned int input_count, - unsigned int output_count, unsigned int hidden_count); - -#ifdef USE_BOOST_PYTHON - - // Serialization - friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int version) - { - ar & m_ID; - ar & m_NeuronGenes; - ar & m_LinkGenes; - ar & m_NumInputs; - ar & m_NumOutputs; - ar & m_Fitness; - ar & m_AdjustedFitness; - ar & m_Depth; - ar & m_OffspringAmount; - ar & m_Evaluated; - //ar & m_PhenotypeBehavior; // todo: think about how we will handle the behaviors with pickle - } - -#endif - - }; - - -#ifdef USE_BOOST_PYTHON - - struct Genome_pickle_suite : py::pickle_suite - { - static py::object getstate(const Genome& a) - { - std::ostringstream os; - boost::archive::text_oarchive oa(os); - oa << a; - return py::str (os.str()); - } - - static void setstate(Genome& a, py::object entries) - { - py::str s = py::extract (entries)(); - std::string st = py::extract (s)(); - std::istringstream is (st); - - boost::archive::text_iarchive ia (is); - ia >> a; - } - }; - -#endif - -#define DBG(x) { std::cerr << x << std::endl; } - - -} // namespace NEAT - -#endif +#ifndef _GENOME_H +#define _GENOME_H + +/////////////////////////////////////////////////////////////////////////////////////////// +// MultiNEAT - Python/C++ NeuroEvolution of Augmenting Topologies Library +// +// Copyright (C) 2012 Peter Chervenski +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRbbbbbbbbbbANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see < http://www.gnu.org/licenses/ >. +// +// Contact info: +// +// Peter Chervenski < spookey@abv.bg > +// Shane Ryan < shane.mcdonald.ryan@gmail.com > +/////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// File: Genome.h +// Description: Definition for the Genome class. +/////////////////////////////////////////////////////////////////////////////// + +#ifdef USE_BOOST_PYTHON + +#include +#include +#include +#include +#include + +#endif + +#include + +#include +#include +#include + +#include +#include + +#include "NeuralNetwork.h" +#include "Substrate.h" +#include "Innovation.h" +#include "Genes.h" +#include "Assert.h" +#include "PhenotypeBehavior.h" +#include "Random.h" + +namespace NEAT +{ + + ////////////////////////////////////////////// + // The Genome class + ////////////////////////////////////////////// + + // forward + class Innovation; + + class InnovationDatabase; + + class PhenotypeBehavior; + + extern ActivationFunction GetRandomActivation(Parameters &a_Parameters, RNG &a_RNG); + + namespace bs = boost; + + typedef bs::adjacency_list Graph; + typedef bs::graph_traits::vertex_descriptor Vertex; + + enum GenomeSeedType + { + PERCEPTRON = 0, + LAYERED = 1 + }; + + class GenomeInitStruct + { + public: + int NumInputs; + int NumHidden; // ignored for seed_type == 0, specifies number of hidden units if seed_type == 1 + int NumOutputs; + bool FS_NEAT; + ActivationFunction OutputActType; + ActivationFunction HiddenActType; + GenomeSeedType SeedType; + int NumLayers; + int FS_NEAT_links; + + GenomeInitStruct() + { + NumInputs = 1; + NumHidden = 0; + NumOutputs = 1; + FS_NEAT = 0; + FS_NEAT_links = 1; + HiddenActType = UNSIGNED_SIGMOID; + OutputActType = UNSIGNED_SIGMOID; + SeedType = GenomeSeedType::PERCEPTRON; + NumLayers = 0; + } + }; + + + class Genome + { + ///////////////////// + // Members + ///////////////////// + private: + + // ID of genome + int m_ID; + + // How many inputs/outputs + int m_NumInputs; + int m_NumOutputs; + + // The genome's fitness score + double m_Fitness; + + // The genome's adjusted fitness score + double m_AdjustedFitness; + + // The depth of the network + int m_Depth; + + // how many individuals this genome should spawn + double m_OffspringAmount; + + //////////////////// + // Private methods + + // Returns true if the specified neuron ID is present in the genome + bool HasNeuronID(int a_id) const; + + // Returns true if the specified link is present in the genome + bool HasLink(int a_n1id, int a_n2id) const; + + // Returns true if the specified link is present in the genome + bool HasLinkByInnovID(int a_id) const; + + // Removes the link with the specified innovation ID + void RemoveLinkGene(int a_innovid); + + // Remove node + // Links connected to this node are also removed + void RemoveNeuronGene(int a_id); + + // Returns the count of links inputting from the specified neuron ID + int LinksInputtingFrom(int a_id) const; + + // Returns the count of links outputting to the specified neuron ID + int LinksOutputtingTo(int a_id) const; + + // A recursive function returning the max depth from the specified neuron to the inputs + unsigned int NeuronDepth(int a_NeuronID, unsigned int a_Depth); + + // Returns true is the specified neuron ID is a dead end or isolated + bool IsDeadEndNeuron(int a_id) const; + + public: + + // The two lists of genes + std::vector m_NeuronGenes; + std::vector m_LinkGenes; + + // To have traits that belong to the genome itself + Gene m_GenomeGene; + + // tells whether this genome was evaluated already + // used in steady state evolution + bool m_Evaluated; + + // the initial genome complexity + int m_initial_num_neurons; + int m_initial_num_links; + + // A pointer to a class representing the phenotype's behavior + // Used in novelty searches + PhenotypeBehavior *m_PhenotypeBehavior; + // A Python object behavior +#ifdef USE_BOOST_PYTHON + py::object m_behavior; +#endif + + //////////////////////////// + // Constructors + //////////////////////////// + + Genome(); + + // copy constructor + Genome(const Genome &a_g); + + // assignment operator + Genome &operator=(const Genome &a_g); + + // comparison operator (nessesary for boost::python) + // todo: implement a better comparison technique + bool operator==(Genome const &other) const + { + return m_ID == other.m_ID; + } + + // Builds this genome from a file + Genome(const char *a_filename); + + // Builds this genome from an opened file + Genome(std::ifstream &a_DataFile); + + // This creates a CTRNN fully-connected genome + + //Genome(int a_ID, int a_NumInputs, int a_NumHidden, int a_NumOutputs, + // ActivationFunction a_OutputActType, ActivationFunction a_HiddenActType, const Parameters &a_Parameters); + + //Genome(unsigned int a_ID, unsigned int a_NumInputs, unsigned int a_NumHidden, unsigned int a_NumOutputs, + // ActivationFunction a_OutputActType, ActivationFunction a_HiddenActType, const Parameters &a_Parameters); + + + // This creates a standart minimal genome - perceptron-like structure + Genome(const Parameters &a_Parameters, + const GenomeInitStruct &init_struct); + + ///////////// + // Other possible constructors for different types of networks go here + // TODO + + + //////////////////////////// + // Destructor + //////////////////////////// + + //////////////////////////// + // Methods + //////////////////////////// + + //////////////////// + // Accessor methods + + NeuronGene GetNeuronByID(int a_ID) const; + + NeuronGene GetNeuronByIndex(int a_idx) const; + + LinkGene GetLinkByInnovID(int a_ID) const; + + LinkGene GetLinkByIndex(int a_idx) const; + + // A little helper function to find the index of a neuron, given its ID + int GetNeuronIndex(int a_id) const; + + // A little helper function to find the index of a link, given its innovation ID + int GetLinkIndex(int a_innovid) const; + + unsigned int NumNeurons() const + { return static_cast(m_NeuronGenes.size()); } + + unsigned int NumLinks() const + { return static_cast(m_LinkGenes.size()); } + + unsigned int NumInputs() const + { return m_NumInputs; } + + unsigned int NumOutputs() const + { return m_NumOutputs; } + + void SetNeuronXY(unsigned int a_idx, int a_x, int a_y); + + void SetNeuronX(unsigned int a_idx, int a_x); + + void SetNeuronY(unsigned int a_idx, int a_y); + + double GetFitness() const; + + double GetAdjFitness() const; + + void SetFitness(double a_f); + + void SetAdjFitness(double a_af); + + int GetID() const; + + void SetID(int a_id); + + unsigned int GetDepth() const; + + void SetDepth(unsigned int a_d); + + // Returns true if there is any dead end in the network + bool HasDeadEnds() const; + + // Returns true if there is any looping path in the network + bool HasLoops(); + + bool FailsConstraints(const Parameters &a_Parameters) + { + bool fails = false; + + if (HasDeadEnds() || (NumLinks() == 0)) + { + return true; // no reason to continue + } + + + if ((HasLoops() && (a_Parameters.AllowLoops == false))) + { + return true; + } + + // Custom constraints + if (a_Parameters.CustomConstraints != NULL) + { + if (a_Parameters.CustomConstraints(*this)) + { + return true; + } + } + + // for Python-based custom constraint callbacks +#ifdef USE_BOOST_PYTHON + if (a_Parameters.pyCustomConstraints.ptr() != py::object().ptr()) // is it not None? + { + return py::extract(a_Parameters.pyCustomConstraints(*this)); + } +#endif + // add more constraints here + return false; + } + + double GetOffspringAmount() const; + + void SetOffspringAmount(double a_oa); + + // This builds a fastnetwork structure out from the genome + void BuildPhenotype(NeuralNetwork &net); + + // Projects the phenotype's weights back to the genome + void DerivePhenotypicChanges(NeuralNetwork &a_Net); + + //////////// + // Other possible methods for building a phenotype go here + // Like CPPN/HyperNEAT stuff + //////////// + void BuildHyperNEATPhenotype(NeuralNetwork &net, Substrate &subst); + +#ifdef USE_BOOST_PYTHON + + py::dict TraitMap2Dict(std::map< std::string, Trait>& tmap) + { + py::dict traits; + for(auto tit=tmap.begin(); tit!=tmap.end(); tit++) + { + bool doit = false; + if (tit->second.dep_key != "") + { + // there is such trait.. + if (tmap.count(tit->second.dep_key) != 0) + { + // and it has the right value? + for(int ix=0; ix < tit->second.dep_values.size(); ix++) + { + if (tmap[tit->second.dep_key].value == tit->second.dep_values[ix]) + { + doit = true; + break; + } + } + } + } + else + { + doit = true; + } + + if (doit) + { + TraitType t = tit->second.value; + if (t.type() == typeid(int)) + { + traits[tit->first] = bs::get(t); + } + if (t.type() == typeid(double)) + { + traits[tit->first] = bs::get(t); + } + if (t.type() == typeid(std::string)) + { + traits[tit->first] = bs::get(t); + } + if (t.type() == typeid(intsetelement)) + { + traits[tit->first] = (bs::get(t)).value; + } + if (t.type() == typeid(floatsetelement)) + { + traits[tit->first] = (bs::get(t)).value; + } + if (t.type() == typeid(py::object)) + { + traits[tit->first] = bs::get(t); + } + } + } + + return traits; + } + + std::map< std::string, Trait> Dict2TraitMap(py::dict d) + { + py::list ks = d.keys(); + std::map< std::string, Trait> ts; + + for(int i=0 ; i(key)] = t; + } + + return ts; + }; + + + py::object GetNeuronTraits() + { + py::list neurons; + for(auto it=m_NeuronGenes.begin(); it != m_NeuronGenes.end(); it++) + { + + py::dict traits = TraitMap2Dict((*it).m_Traits); + + py::list little; + little.append( (*it).ID() ); + + if ((*it).Type() == INPUT) + { + little.append( "input" ); + } + else if ((*it).Type() == BIAS) + { + little.append( "bias" ); + } + else if ((*it).Type() == HIDDEN) + { + little.append( "hidden" ); + } + else if ((*it).Type() == OUTPUT) + { + little.append( "output" ); + } + little.append( traits ); + neurons.append( little ); + } + + return neurons; + } + + py::object GetLinkTraits(bool with_weights=false) + { + py::list links; + for(auto it=m_LinkGenes.begin(); it != m_LinkGenes.end(); it++) + { + py::dict traits = TraitMap2Dict((*it).m_Traits); + + py::list little; + little.append( (*it).FromNeuronID() ); + little.append( (*it).ToNeuronID() ); + little.append( traits ); + if (with_weights) + { + little.append( (*it).m_Weight ); + } + links.append( little ); + } + + return links; + } + + py::dict GetGenomeTraits() + { + return TraitMap2Dict(m_GenomeGene.m_Traits); + } + + void SetGenomeTraits(py::dict traits) + { + m_GenomeGene.m_Traits = Dict2TraitMap(traits); + } + +#endif + + // Saves this genome to a file + void Save(const char *a_filename); + + // Saves this genome to an already opened file for writing + void Save(FILE *a_fstream); + + void PrintTraits(std::map< std::string, Trait>& traits); + void PrintAllTraits(); + + // returns the max neuron ID + int GetLastNeuronID() const; + + // returns the max innovation Id + int GetLastInnovationID() const; + + // Sorts the genes of the genome + // The neurons by IDs and the links by innovation numbers. + void SortGenes(); + + // overload '<' used for sorting. From fittest to poorest. + friend bool operator<(const Genome &a_lhs, const Genome &a_rhs) + { + return (a_lhs.m_Fitness > a_rhs.m_Fitness); + } + + // Returns true if this genome and a_G are compatible (belong in the same species) + bool IsCompatibleWith(Genome &a_G, Parameters &a_Parameters); + + // returns the absolute compatibility distance between this genome and a_G + double CompatibilityDistance(Genome &a_G, Parameters &a_Parameters); + + // Calculates the network depth + void CalculateDepth(); + + //////////// + // Mutation + //////////// + + // Adds a new neuron to the genome + // returns true if succesful + bool Mutate_AddNeuron(InnovationDatabase &a_Innovs, const Parameters &a_Parameters, RNG &a_RNG); + + // Adds a new link to the genome + // returns true if succesful + bool Mutate_AddLink(InnovationDatabase &a_Innovs, const Parameters &a_Parameters, RNG &a_RNG); + + // Remove a random link from the genome + // A cleanup procedure is invoked so any dead-ends or stranded neurons are also deleted + // returns true if succesful + bool Mutate_RemoveLink(RNG &a_RNG); + + // Removes a hidden neuron having only one input and only one output with + // a direct link between them. + bool Mutate_RemoveSimpleNeuron(InnovationDatabase &a_Innovs, const Parameters &a_Parameters, RNG &a_RNG); + + // Perturbs the weights + bool Mutate_LinkWeights(const Parameters &a_Parameters, RNG &a_RNG); + + // Set all link weights to random values between [-R .. R] + void Randomize_LinkWeights(const Parameters &a_Parameters, RNG &a_RNG); + + // Set all traits to random values + void Randomize_Traits(const Parameters& a_Parameters, RNG &a_RNG); + + // Perturbs the A parameters of the neuron activation functions + bool Mutate_NeuronActivations_A(const Parameters &a_Parameters, RNG &a_RNG); + + // Perturbs the B parameters of the neuron activation functions + bool Mutate_NeuronActivations_B(const Parameters &a_Parameters, RNG &a_RNG); + + // Changes the activation function type for a random neuron + bool Mutate_NeuronActivation_Type(const Parameters &a_Parameters, RNG &a_RNG); + + // Perturbs the neuron time constants + bool Mutate_NeuronTimeConstants(const Parameters &a_Parameters, RNG &a_RNG); + + // Perturbs the neuron biases + bool Mutate_NeuronBiases(const Parameters &a_Parameters, RNG &a_RNG); + + // Perturbs the neuron traits + bool Mutate_NeuronTraits(const Parameters &a_Parameters, RNG &a_RNG); + + // Perturbs the link traits + bool Mutate_LinkTraits(const Parameters &a_Parameters, RNG &a_RNG); + + // Perturbs the genome traits + bool Mutate_GenomeTraits(const Parameters &a_Parameters, RNG &a_RNG); + + /////////// + // Mating + /////////// + + + // Mate this genome with dad and return the baby + // If this is multipoint mating, genes are inherited randomly + // If the a_averagemating bool is true, then the genes are averaged + // Disjoint and excess genes are inherited from the fittest parent + // If fitness is equal, the smaller genome is assumed to be the better one + Genome Mate(Genome &a_dad, bool a_averagemating, bool a_interspecies, RNG &a_RNG, Parameters &a_Parameters); + + + ////////// + // Utility + ////////// + + // Search the genome for isolated structure and clean it up + // Returns true is something was removed + bool Cleanup(); + + //////////////////// + // new stuff + bool IsEvaluated() const; + + void SetEvaluated(); + + void ResetEvaluated(); + +#if 0 // disabling because of errors I can't fix right now + + ///////////////////////////////////////////// + // Evolvable Substrate HyperNEAT + //////////////////////////////////////////// + + + // A connection between two points. Stores weight and the coordinates of the points + struct TempConnection + { + std::vector source; + std::vector target; + double weight; + + TempConnection() + { + source.reserve(3); + target.reserve(3); + weight = 0; + } + + TempConnection(std::vector t_source, std::vector t_target, + double t_weight) + { + source = t_source; + target = t_target; + weight = t_weight; + source.reserve(3); + target.reserve(3); + } + + TempConnection(std::vector t_source, std::vector t_target, double t_weight, unsigned int coord_size) + { + source = t_source; + target = t_target; + weight = t_weight; + } + + ~TempConnection() + {}; + + bool operator==(const TempConnection &rhs) const + { + return (source == rhs.source && target == rhs.target); + } + + bool operator!=(const TempConnection &rhs) const + { + return (source != rhs.source && target != rhs.target); + } + }; + + // A quadpoint in the HyperCube. + struct QuadPoint + { + double x; + double y; + double z; + double width; + double weight; + double height; + double variance; + int level; + // Do I use this? + double leo; + + + std::vector > children; + + QuadPoint() + { + x = y = z = width = height = weight = variance = leo = 0; + level = 0; + children.reserve(4); + } + + QuadPoint(double t_x, double t_y, double t_width, double t_height, int t_level) + { + x = t_x; + y = t_y; + z = 0.0; + width = t_width; + height = t_height; + level = t_level; + weight = 0.0; + leo = 0.0; + variance = 0.0; + children.reserve(4); + children.clear(); + } + + // Mind the Z + QuadPoint(double t_x, double t_y, double t_z, double t_width, double t_height, + int t_level) + { + x = t_x; + y = t_y; + z = t_z; + width = t_width; + height = t_height; + level = t_level; + weight = 0.0; + variance = 0.0; + leo = 0.0; + children.reserve(4); + children.clear(); + } + + ~QuadPoint() + { + }; + }; + + + struct nTree + { + std::vector coord; + double weight; + double varience; + int lvl; + double width; + double leo = 0.0; + std::vector > children; + + nTree(std::vector coord_in, double wdth, double level) + { + width = wdth; + lvl = level; + coord = coord_in; + }; + + public: + + void set_children() + { + for(unsigned int ix = 0; ix < 2**coord.size(); ix++){ + std::string sum_permute = toBinary(ix, coord.size()); + std::vector child_coords; + int child_param_len = sum_permute.length(); + child_coords.reserve(child_param_len); + for(unsigned int sign_ix = 0; sign_ix < child_param_len; sign_ix++) + { + if(sum_permute[sign_ix] == "0") + { + child_coords.push_back(coord[sign_ix] + width/2.0); + } + else + { + child_coords.push_back(coord[sign_ix] - width/2.0); + } + children.push_back(new nTree(child_coords, width/2.0, sslvl+1)); + } + } + } + + string toBinary(unsigned int n, int min_len) + { + std::string r; + while(n!=0) + { + r=(n%2==0 ?"0":"1")+r; n/=2; + + } + if(r.length() < min_len) + { + int diff = min_len - r.length(); + for(unsigned int x = 0; x < diff; x++) + { + r = '0' +r; + } + } + return r; + } + }; + void BuildESHyperNEATPhenotypeND(NeuralNetwork &a_net, Substrate &subst, Parameters ¶ms); + void BuildESHyperNEATPhenotype(NeuralNetwork &a_net, Substrate &subst, Parameters ¶ms); + + void DivideInitialize(const std::vector &node, + boost::shared_ptr &root, + NeuralNetwork &cppn, Parameters ¶ms, + const bool &outgoing, const double &z_coord); + + void PruneExpress(const std::vector &node, + boost::shared_ptr &root, NeuralNetwork &cppn, + Parameters ¶ms, std::vector &connections, + const bool &outgoing); + void DivideInitializeND(const std::vector &node, + boost::shared_ptr &root, + NeuralNetwork &cppn, Parameters ¶ms, + const bool &outgoing, const double &z_coord); + + void PruneExpressND(const std::vector &node, + boost::shared_ptr &root, NeuralNetwork &cppn, + Parameters ¶ms, std::vector &connections, + const bool &outgoing); + + + void CollectValues(std::vector &vals, boost::shared_ptr &point); + + double Variance(boost::shared_ptr &point); + + void Clean_Net(std::vector &connections, unsigned int input_count, + unsigned int output_count, unsigned int hidden_count); +#endif + +#ifdef USE_BOOST_PYTHON + + // Serialization + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version) + { + ar & m_ID; + ar & m_NeuronGenes; + ar & m_LinkGenes; + //ar & m_GenomeGene; + ar & m_NumInputs; + ar & m_NumOutputs; + ar & m_Fitness; + ar & m_AdjustedFitness; + ar & m_Depth; + ar & m_OffspringAmount; + ar & m_Evaluated; + + ar & m_initial_num_neurons; + ar & m_initial_num_links; + + //ar & m_PhenotypeBehavior; // todo: think about how we will handle the behaviors with pickle + } + +#endif + }; + + +#ifdef USE_BOOST_PYTHON + + struct Genome_pickle_suite : py::pickle_suite + { + static py::object getstate(const Genome& a) + { + std::ostringstream os; + boost::archive::text_oarchive oa(os); + oa << a; + return py::str (os.str()); + } + + static void setstate(Genome& a, py::object entries) + { + py::str s = py::extract (entries)(); + std::string st = py::extract (s)(); + std::istringstream is (st); + + boost::archive::text_iarchive ia (is); + ia >> a; + } + }; + +#endif + +#define DBG(x) { std::cerr << x << std::endl; } + + +} // namespace NEAT + +#endif diff --git a/src/Innovation.cpp b/src/Innovation.cpp index 1f763382..78a101fe 100644 --- a/src/Innovation.cpp +++ b/src/Innovation.cpp @@ -1,4 +1,4 @@ -/////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// // MultiNEAT - Python/C++ NeuroEvolution of Augmenting Topologies Library // // Copyright (C) 2012 Peter Chervenski @@ -76,7 +76,7 @@ void InnovationDatabase::Init(const Genome& a_Genome) for(unsigned int i=0; i> t_neurontype; a_DataFile >> t_nid; - m_Innovations.push_back( Innovation(t_id, static_cast(t_innovtype), t_from, t_to, static_cast(t_neurontype), t_nid) ); + m_Innovations.emplace_back( Innovation(t_id, static_cast(t_innovtype), t_from, t_to, static_cast(t_neurontype), t_nid) ); } } @@ -207,7 +207,7 @@ std::vector InnovationDatabase::CheckAllInnovations(int a_In, int a_Out, In if ((m_Innovations[i].FromNeuronID() == a_In) && (m_Innovations[i].ToNeuronID() == a_Out) && (m_Innovations[i].InnovType() == a_Type)) { // match found? - t_idxs.push_back( i ); + t_idxs.emplace_back( i ); } } @@ -261,7 +261,7 @@ int InnovationDatabase::AddLinkInnovation(int a_In, int a_Out) { ASSERT((a_In > 0) && (a_Out > 0)); - m_Innovations.push_back( Innovation(m_NextInnovationNum, NEW_LINK, a_In, a_Out, NONE, -1) ); + m_Innovations.emplace_back( Innovation(m_NextInnovationNum, NEW_LINK, a_In, a_Out, NONE, -1) ); m_NextInnovationNum++; return (m_NextInnovationNum - 1); @@ -279,7 +279,7 @@ int InnovationDatabase::AddNeuronInnovation(int a_In, int a_Out, NeuronType a_NT ASSERT((a_In > 0) && (a_Out > 0)); ASSERT(!((a_NType == INPUT) || (a_NType == BIAS) || (a_NType == OUTPUT))); - m_Innovations.push_back( Innovation(m_NextInnovationNum, NEW_NEURON, a_In, a_Out, a_NType, m_NextNeuronID) ); + m_Innovations.emplace_back( Innovation(m_NextInnovationNum, NEW_NEURON, a_In, a_Out, a_NType, m_NextNeuronID) ); m_NextInnovationNum++; m_NextNeuronID++; diff --git a/src/Innovation.h b/src/Innovation.h index 17a0d63e..da0a70fe 100644 --- a/src/Innovation.h +++ b/src/Innovation.h @@ -1,3 +1,6 @@ +#include +#include + #ifndef _INNOVATION_H #define _INNOVATION_H @@ -91,6 +94,14 @@ class Innovation m_NeuronID = a_NID; } + Innovation() + { + m_ID = 0; + m_FromNeuronID = 0; + m_ToNeuronID = 0; + m_NeuronID = 0; + } + //////////////////////////// // Destructor //////////////////////////// @@ -124,7 +135,22 @@ class Innovation { return m_NeuronType; } -}; + +#ifdef USE_BOOST_PYTHON + // Serialization + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version) + { + ar & m_ID; + ar & m_InnovType; + ar & m_FromNeuronID; + ar & m_ToNeuronID; + ar & m_NeuronType; + ar & m_NeuronID; + } +#endif + }; // forward @@ -212,7 +238,20 @@ class InnovationDatabase // Saves the database to an already opened file void Save(FILE* a_file); -}; + +#ifdef USE_BOOST_PYTHON + // Serialization + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version) + { + ar & m_NextNeuronID; + ar & m_NextInnovationNum; + ar & m_Innovations; + } +#endif + + }; diff --git a/src/Main.cpp b/src/Main.cpp index 9213cc7d..c4290f16 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -9,6 +9,8 @@ * Ignore this file. I use it to test stuff. * */ +#include +#include #include "Genome.h" #include "Population.h" @@ -35,12 +37,12 @@ double abs(double x) bool constraints(Genome& g) { - for(auto it=g.m_NeuronGenes.begin(); it!=g.m_NeuronGenes.end(); it++) + /*for(auto it=g.m_NeuronGenes.begin(); it!=g.m_NeuronGenes.end(); it++) { if (boost::get(it->m_Traits["z"].value).value == 64) // don't allow 4 to appear anywhere return true; - } + }*/ return false; } @@ -68,9 +70,9 @@ double xortest(Genome& g) if (boost::get(g.m_GenomeGene.m_Traits["y"].value) == "c") f += 1 * (double)(boost::get(g.m_GenomeGene.m_Traits["v"].value)); else - f = 0.1; + f += 1 * (double)(boost::get(g.m_GenomeGene.m_Traits["x"].value)); - return f; + return f+1000; } @@ -78,6 +80,7 @@ int main() { Parameters params; +#if 1 params.PopulationSize = 32; params.DynamicCompatibility = true; params.WeightDiffCoeff = 0.0; @@ -87,23 +90,24 @@ int main() params.OldAgeTreshold = 35; params.OldAgePenalty = 0.1; params.MinSpecies = 2; - params.MaxSpecies = 4; + params.MaxSpecies = 3; params.RouletteWheelSelection = false; params.RecurrentProb = 0.0; params.OverallMutationRate = 0.4; - params.MutateWeightsProb = 0.0; + params.MutateWeightsProb = 0.3; params.WeightMutationMaxPower = 2.5; params.WeightReplacementMaxPower = 5.0; params.MutateWeightsSevereProb = 0.5; params.WeightMutationRate = 0.25; + + params.MinWeight = -4; + params.MaxWeight = 4; - params.MaxWeight = 8; - - params.MutateAddNeuronProb = 0.003; - params.MutateAddLinkProb = 0.05; - params.MutateRemLinkProb = 0.0; + params.MutateAddNeuronProb = 0.1; + params.MutateAddLinkProb = 0;//0.05; + params.MutateRemLinkProb = 0;//0.01; params.MinActivationA = 4.9; params.MaxActivationA = 4.9; @@ -113,23 +117,45 @@ int main() params.ActivationFunction_Tanh_Prob = 0.0; params.ActivationFunction_SignedStep_Prob = 0.0; - params.CrossoverRate = 0.75 ; + params.CrossoverRate = 0.75; + params.InterspeciesCrossoverRate = 0.01; params.MultipointCrossoverRate = 0.4; params.SurvivalRate = 0.2; + params.OverallMutationRate = 1.0; - params.AllowClones = false; + params.AllowClones = true; params.AllowLoops = false; params.DontUseBiasNeuron = true; - params.MutateNeuronTraitsProb = 0.2; - params.MutateLinkTraitsProb = 0.2; + params.MutateNeuronTraitsProb = 0;//0.2; + params.MutateLinkTraitsProb = 0;//0.2; + params.MutateGenomeTraitsProb = 0; + + params.ExcessCoeff = 1.2; + params.DisjointCoeff = 1.2; + params.WeightDiffCoeff = 0.0; + params.CompatTreshold = 0.0; + params.MinCompatTreshold = 0.0; + params.CompatTreshChangeInterval_Evaluations = 1; + params.NormalizeGenomeSize = false; - params.ArchiveEnforcement = true; + params.ArchiveEnforcement = false; params.CustomConstraints = constraints; + + params.MinWeight = -12.0; + params.MaxWeight = 12.0; + params.MutateWeightsProb = 0.0; + params.MutateWeightsSevereProb = 0.2; + params.WeightMutationRate = 0.333; + params.WeightMutationMaxPower = 3.0; + params.WeightReplacementRate = 0.25; + params.WeightReplacementMaxPower = 6.0; + + params.MutateRemSimpleNeuronProb = 1.001; TraitParameters tp1; - tp1.m_ImportanceCoeff = 1.0; + tp1.m_ImportanceCoeff = 0.0; tp1.m_MutationProb = 0.9; tp1.type = "int"; tp1.dep_key = "y"; @@ -142,7 +168,7 @@ int main() tp1.m_Details = itp1; TraitParameters tp2; - tp2.m_ImportanceCoeff = 0.2; + tp2.m_ImportanceCoeff = 0.0;//2; tp2.m_MutationProb = 0.9; tp2.type = "float"; FloatTraitParameters itp2; @@ -153,7 +179,7 @@ int main() tp2.m_Details = itp2; TraitParameters tp3; - tp3.m_ImportanceCoeff = 0.02; + tp3.m_ImportanceCoeff = 0.0;//2; tp3.m_MutationProb = 0.9; tp3.type = "intset"; IntSetTraitParameters itp3; @@ -176,7 +202,7 @@ int main() tp3.m_Details = itp3; TraitParameters tps; - tps.m_ImportanceCoeff = 0.02; + tps.m_ImportanceCoeff = 0.0;//2; tps.m_MutationProb = 0.9; tps.type = "str"; StringTraitParameters itps; @@ -185,11 +211,11 @@ int main() itps.set.push_back("c"); itps.set.push_back("d"); itps.set.push_back("e"); - itps.probs.push_back(1); - itps.probs.push_back(1); - itps.probs.push_back(1); - itps.probs.push_back(1); - itps.probs.push_back(1); + itps.probs.push_back(0.02); + itps.probs.push_back(0.9); + itps.probs.push_back(0.1); + itps.probs.push_back(0.1); + itps.probs.push_back(0.8); tps.m_Details = itps; /*TraitParameters tp3; @@ -207,23 +233,57 @@ int main() params.GenomeTraits["x"] = tp2; params.GenomeTraits["y"] = tps; params.NeuronTraits["z"] = tp3; +#endif + + GenomeInitStruct ints; + ints.NumInputs = 4; + ints.NumOutputs = 1; + ints.NumHidden = 0; + ints.SeedType = PERCEPTRON; + ints.FS_NEAT = false; + ints.FS_NEAT_links = 0; + ints.HiddenActType = UNSIGNED_SIGMOID; + ints.OutputActType = UNSIGNED_SIGMOID; - Genome s(0, 1, - 1, - 1, - false, - UNSIGNED_SIGMOID, - UNSIGNED_SIGMOID, - 1, - params, - 2); + Genome s(params, ints); Population pop(s, params, true, 1.0, time(0)); + + //pop.m_Parameters.AllowClones = false; + + for(unsigned int i=0; i < pop.m_Species.size(); i++) + { + for (unsigned int j = 0; j < pop.m_Species[i].m_Individuals.size(); j++) + { + double f = xortest(pop.m_Species[i].m_Individuals[j]); + pop.m_Species[i].m_Individuals[j].SetFitness(pop.m_RNG.RandFloat()); + if ((pop.m_RNG.RandFloat() < 0.15) || (j==0)) + { + pop.m_Species[i].m_Individuals[j].SetEvaluated(); + } + } + } - for(int k=0; k<5000; k++) + for(int k=0; k<2500; k++) { double bestf = -999999; - for(unsigned int i=0; i < pop.m_Species.size(); i++) + Genome gx; + + Genome* baby; + baby = pop.Tick(gx); + + double f = xortest(*baby); + baby->SetFitness(f); + if (pop.m_RNG.RandFloat() < 0.5) + { + baby->SetEvaluated(); + } + if (f > bestf) + { + bestf = f; + } + + /*for(unsigned int i=0; i < pop.m_Species.size(); i++) { for(unsigned int j=0; j < pop.m_Species[i].m_Individuals.size(); j++) { @@ -241,15 +301,21 @@ int main() bestf = f; } } - } + }*/ Genome g = pop.GetBestGenome(); - g.PrintAllTraits(); + //g.PrintAllTraits(); - printf("Generation: %d, best fitness: %3.5f\n", k, bestf); - printf("Species: %d\n", pop.m_Species.size()); - pop.Epoch(); + printf("Tick: %d, best fitness: %3.5f\n", k, bestf); + printf("Species: %d CT: %3.3f\n", pop.m_Species.size(), pop.m_Parameters.CompatTreshold); + //pop.Epoch(); } + +/*for(int i=0; i<100; i++) + { + std::cout << pop.m_RNG.Roulette(itps.probs) << " "; + }*/ + std::cout << "\n"; return 0; } diff --git a/src/NeuralNetwork.cpp b/src/NeuralNetwork.cpp index 82ce796e..9713a9f3 100644 --- a/src/NeuralNetwork.cpp +++ b/src/NeuralNetwork.cpp @@ -173,11 +173,11 @@ NeuralNetwork::NeuralNetwork(bool a_Minimal) // The hidden neuron // index 4 Neuron t_h1; - m_neurons.push_back(t_i1); - m_neurons.push_back(t_i2); - m_neurons.push_back(t_i3); - m_neurons.push_back(t_o1); - m_neurons.push_back(t_h1); + m_neurons.emplace_back(t_i1); + m_neurons.emplace_back(t_i2); + m_neurons.emplace_back(t_i3); + m_neurons.emplace_back(t_o1); + m_neurons.emplace_back(t_h1); // The connections Connection t_c; @@ -185,37 +185,37 @@ NeuralNetwork::NeuralNetwork(bool a_Minimal) t_c.m_source_neuron_idx = 0; t_c.m_target_neuron_idx = 3; t_c.m_weight = 0; - m_connections.push_back(t_c); + m_connections.emplace_back(t_c); t_c.m_source_neuron_idx = 1; t_c.m_target_neuron_idx = 3; t_c.m_weight = 0; - m_connections.push_back(t_c); + m_connections.emplace_back(t_c); t_c.m_source_neuron_idx = 2; t_c.m_target_neuron_idx = 3; t_c.m_weight = 0; - m_connections.push_back(t_c); + m_connections.emplace_back(t_c); t_c.m_source_neuron_idx = 0; t_c.m_target_neuron_idx = 4; t_c.m_weight = 0; - m_connections.push_back(t_c); + m_connections.emplace_back(t_c); t_c.m_source_neuron_idx = 1; t_c.m_target_neuron_idx = 4; t_c.m_weight = 0; - m_connections.push_back(t_c); + m_connections.emplace_back(t_c); t_c.m_source_neuron_idx = 2; t_c.m_target_neuron_idx = 4; t_c.m_weight = 0; - m_connections.push_back(t_c); + m_connections.emplace_back(t_c); t_c.m_source_neuron_idx = 4; t_c.m_target_neuron_idx = 3; t_c.m_weight = 0; - m_connections.push_back(t_c); + m_connections.emplace_back(t_c); m_num_inputs = 3; m_num_outputs = 1; @@ -625,6 +625,8 @@ void NeuralNetwork::Input_python_list(const py::list& a_Inputs) Input(inp); } +#ifdef USE_BOOST_NUMPY + void NeuralNetwork::Input_numpy(const pyndarray& a_Inputs) { int len = py::len(a_Inputs); @@ -647,12 +649,14 @@ void NeuralNetwork::Input_numpy(const pyndarray& a_Inputs) #endif +#endif + std::vector NeuralNetwork::Output() { std::vector t_output; for (int i = 0; i < m_num_outputs; i++) { - t_output.push_back(m_neurons[i + m_num_inputs].m_activation); + t_output.emplace_back(m_neurons[i + m_num_inputs].m_activation); } return t_output; } @@ -902,7 +906,7 @@ bool NeuralNetwork::Load(std::ifstream& a_DataFile) t_n.m_type = static_cast(t_type); t_n.m_activation_function_type = static_cast(t_aftype); - m_neurons.push_back(t_n); + m_neurons.emplace_back(t_n); } // a connection? @@ -922,7 +926,7 @@ bool NeuralNetwork::Load(std::ifstream& a_DataFile) t_c.m_recur_flag = static_cast(t_isrecur); - m_connections.push_back(t_c); + m_connections.emplace_back(t_c); } diff --git a/src/NeuralNetwork.h b/src/NeuralNetwork.h index de8e1f5f..cf189ef1 100644 --- a/src/NeuralNetwork.h +++ b/src/NeuralNetwork.h @@ -35,11 +35,14 @@ #include #include + +#ifdef USE_BOOST_NUMPY #if BOOST_VERSION < 106500 #include #else #include #endif +#endif #include #include @@ -47,11 +50,13 @@ namespace py = boost::python; +#ifdef USE_BOOST_NUMPY #if BOOST_VERSION < 106500 typedef typename py::numeric::array pyndarray; #else typedef typename py::numpy::ndarray pyndarray; #endif +#endif #endif @@ -170,8 +175,13 @@ class NeuralNetwork #ifdef USE_BOOST_PYTHON void Input_python_list(const py::list& a_Inputs); + +#ifdef USE_BOOST_NUMPY + void Input_numpy(const pyndarray& a_Inputs); +#endif + #endif std::vector Output(); diff --git a/src/Parameters.cpp b/src/Parameters.cpp index 1fc554a1..f1e4ddd5 100644 --- a/src/Parameters.cpp +++ b/src/Parameters.cpp @@ -48,6 +48,9 @@ namespace NEAT // Size of population PopulationSize = 300; + + // Speciation on/off + Speciation = true; // If true, this enables dynamic compatibility thresholding // It will keep the number of species between MinSpecies and MaxSpecies @@ -80,7 +83,7 @@ namespace NEAT AllowLoops = true; // Normalize genome size when calculating compatibility - NormalizeGenomeSize = true; + NormalizeGenomeSize = false; // Pointer to a function that specifies custom topology/trait constraints // Should return true if the genome FAILS to meet the constraints @@ -97,8 +100,8 @@ namespace NEAT // Make sure it is >= 1.0 to avoid confusion YoungAgeFitnessBoost = 1.1; - // Number of generations without improvement (stagnation) allowed for a species - SpeciesMaxStagnation = 50; + // Number of generations or evaluations without improvement (stagnation) allowed for a species + SpeciesMaxStagnation = 25000; // Minimum jump in fitness necessary to be considered as improvement. // Setting this value to 0.0 makes the system to behave like regular NEAT. @@ -120,7 +123,7 @@ namespace NEAT KillWorstAge = 10; // Percent of best individuals that are allowed to reproduce. 1.0 = 100% - SurvivalRate = 0.25; + SurvivalRate = 0.2; // Probability for a baby to result from sexual reproduction (crossover/mating). 1.0 = 100% // If asexual reprodiction is chosen, the baby will be mutated 100% @@ -128,7 +131,7 @@ namespace NEAT // If a baby results from sexual reproduction, this probability determines if mutation will // be performed after crossover. 1.0 = 100% (always mutate after crossover) - OverallMutationRate = 0.25; + OverallMutationRate = 0.75; // Probability for a baby to result from inter-species mating. InterspeciesCrossoverRate = 0.0001; @@ -136,20 +139,28 @@ namespace NEAT // Probability for a baby to result from Multipoint Crossover when mating. 1.0 = 100% // The default is the Average mating. MultipointCrossoverRate = 0.75; + + // Probability that when doing multipoint crossover, + // the gene of the fitter parent will be prefered, instead of choosing one at random + PreferFitterParentRate = 0.25; // Performing roulette wheel selection or not? RouletteWheelSelection = false; + + // If true, will do tournament selection + TournamentSelection = true; // For tournament selection - TournamentSize = 4; + TournamentSize = 5; // Fraction of individuals to be copied unchanged - EliteFraction = 0.01; - - - + EliteFraction = 0.000001; + + // How many times to test a genome for constraint failure or being a clone (when AllowClones=False) + ConstraintTrials = 2000000; + /////////////////////////////////// // Phased Search parameters // /////////////////////////////////// @@ -218,10 +229,10 @@ namespace NEAT MutateAddNeuronProb = 0.01; // Allow splitting of any recurrent links - SplitRecurrent = true; + SplitRecurrent = false; // Allow splitting of looped recurrent links - SplitLoopedRecurrent = true; + SplitLoopedRecurrent = false; // Probability for a baby to be mutated with the Add-Link mutation MutateAddLinkProb = 0.03; @@ -237,7 +248,13 @@ namespace NEAT MutateRemSimpleNeuronProb = 0.0; // Maximum number of tries to find 2 neurons to add/remove a link - LinkTries = 32; + LinkTries = 64; + + // Maximum number of links in the genome (originals not counted). -1 is unlimited + MaxLinks = -1; + + // Maximum number of neurons in the genome (originals not counted). -1 is unlimited + MaxNeurons = -1; // Probability that a link mutation will be made recurrent RecurrentProb = 0.25; @@ -271,8 +288,11 @@ namespace NEAT // Maximum magnitude of a replaced weight WeightReplacementMaxPower = 1.0; - // Maximum absolute magnitude of a weight + // Maximum weight MaxWeight = 8.0; + + // Minimum weight + MinWeight = -8.0; // Probability for a baby's A activation function parameters to be perturbed MutateActivationAProb = 0.0; @@ -314,31 +334,6 @@ namespace NEAT MinNeuronBias = 0.0; MaxNeuronBias = 0.0; - // Some default traits for testing - /*TraitParameters tp1; - tp1.m_ImportanceCoeff = 0.0; - tp1.m_MutationProb = 0.8; - tp1.type = "int"; - IntTraitParameters itp1; - itp1.min = -5; - itp1.max = 5; - itp1.mut_power = 1; - itp1.mut_replace_prob = 0.1; - tp1.m_Details = itp1; - NeuronTraits["px"] = tp1; - - TraitParameters tp2; - tp2.m_ImportanceCoeff = 0.0; - tp2.m_MutationProb = 0.8; - tp2.type = "int"; - IntTraitParameters itp2; - itp2.min = -5; - itp2.max = 5; - itp2.mut_power = 1; - itp2.mut_replace_prob = 0.1; - tp2.m_Details = itp2; - NeuronTraits["py"] = tp2;*/ - // Probability for a baby that an activation function type will be changed for a single neuron // considered a structural mutation because of the large impact on fitness MutateNeuronActivationTypeProb = 0.0; @@ -361,9 +356,9 @@ namespace NEAT // Trait mutation probabilities - MutateNeuronTraitsProb = 1.0; - MutateLinkTraitsProb = 1.0; - MutateGenomeTraitsProb = 1.0; + MutateNeuronTraitsProb = 0.0; + MutateLinkTraitsProb = 0.0; + MutateGenomeTraitsProb = 0.0; ///////////////////////////// @@ -400,13 +395,13 @@ namespace NEAT ActivationFunctionDiffCoeff = 0.0; // Compatibility treshold - CompatTreshold = 5.0; + CompatTreshold = 3.0; // Minumal value of the compatibility treshold - MinCompatTreshold = 0.2; + MinCompatTreshold = 0.0; // Modifier per generation for keeping the species stable - CompatTresholdModifier = 0.3; + CompatTresholdModifier = 0.1; // Per how many generations to change the treshold // (used in generational mode) @@ -414,7 +409,10 @@ namespace NEAT // Per how many evaluations to change the treshold // (used in steady state mode) - CompatTreshChangeInterval_Evaluations = 10; + CompatTreshChangeInterval_Evaluations = 1; + + // Minimal distance for two individuals to be considered different (as in clones or not) + MinDeltaCompatEqualGenomes = 0.0000001; @@ -483,6 +481,15 @@ namespace NEAT if (s == "PopulationSize") a_DataFile >> PopulationSize; + + if (s == "Speciation") + { + a_DataFile >> tf; + if (tf == "true" || tf == "1" || tf == "1.0") + Speciation = true; + else + Speciation = false; + } if (s == "DynamicCompatibility") { @@ -526,14 +533,16 @@ namespace NEAT NormalizeGenomeSize = false; } - + if (s == "ConstraintTrials") + a_DataFile >> ConstraintTrials; + if (s == "YoungAgeTreshold") a_DataFile >> YoungAgeTreshold; if (s == "YoungAgeFitnessBoost") a_DataFile >> YoungAgeFitnessBoost; - if (s == "SpeciesDropoffAge") + if (s == "SpeciesMaxStagnation") a_DataFile >> SpeciesMaxStagnation; if (s == "StagnationDelta") @@ -574,6 +583,9 @@ namespace NEAT if (s == "MultipointCrossoverRate") a_DataFile >> MultipointCrossoverRate; + + if (s == "PreferFitterParentRate") + a_DataFile >> PreferFitterParentRate; if (s == "RouletteWheelSelection") { @@ -583,7 +595,17 @@ namespace NEAT else RouletteWheelSelection = false; } - + + if (s == "TournamentSelection") + { + a_DataFile >> tf; + if (tf == "true" || tf == "1" || tf == "1.0") + TournamentSelection = true; + else + TournamentSelection = false; + } + + if (s == "PhasedSearching") { a_DataFile >> tf; @@ -679,6 +701,11 @@ namespace NEAT if (s == "LinkTries") a_DataFile >> LinkTries; + + if (s == "MaxLinks") + a_DataFile >> MaxLinks; + if (s == "MaxNeurons") + a_DataFile >> MaxNeurons; if (s == "RecurrentProb") a_DataFile >> RecurrentProb; @@ -706,6 +733,9 @@ namespace NEAT if (s == "MaxWeight") a_DataFile >> MaxWeight; + + if (s == "MinWeight") + a_DataFile >> MinWeight; if (s == "MutateActivationAProb") a_DataFile >> MutateActivationAProb; @@ -852,7 +882,10 @@ namespace NEAT if (s == "CompatTreshChangeInterval_Evaluations") a_DataFile >> CompatTreshChangeInterval_Evaluations; - + + if (s == "MinDeltaCompatEqualGenomes") + a_DataFile >> MinDeltaCompatEqualGenomes; + if (s == "DivisionThreshold") a_DataFile >> DivisionThreshold; @@ -908,6 +941,9 @@ namespace NEAT if (s == "LeoThreshold") a_DataFile >> LeoThreshold; + + if (s == "TournamentSize") + a_DataFile >> TournamentSize; if (s == "LeoSeed") { @@ -951,15 +987,17 @@ namespace NEAT fprintf(a_fstream, "NEAT_ParametersStart\n"); fprintf(a_fstream, "PopulationSize %d\n", PopulationSize); + fprintf(a_fstream, "Speciation %s\n", Speciation == true ? "true" : "false"); fprintf(a_fstream, "DynamicCompatibility %s\n", DynamicCompatibility == true ? "true" : "false"); fprintf(a_fstream, "MinSpecies %d\n", MinSpecies); fprintf(a_fstream, "MaxSpecies %d\n", MaxSpecies); fprintf(a_fstream, "InnovationsForever %s\n", InnovationsForever == true ? "true" : "false"); fprintf(a_fstream, "AllowClones %s\n", AllowClones == true ? "true" : "false"); fprintf(a_fstream, "NormalizeGenomeSize %s\n", NormalizeGenomeSize == true ? "true" : "false"); + fprintf(a_fstream, "ConstraintTrials %d\n", ConstraintTrials); fprintf(a_fstream, "YoungAgeTreshold %d\n", YoungAgeTreshold); fprintf(a_fstream, "YoungAgeFitnessBoost %3.20f\n", YoungAgeFitnessBoost); - fprintf(a_fstream, "SpeciesDropoffAge %d\n", SpeciesMaxStagnation); + fprintf(a_fstream, "SpeciesMaxStagnation %d\n", SpeciesMaxStagnation); fprintf(a_fstream, "StagnationDelta %3.20f\n", StagnationDelta); fprintf(a_fstream, "OldAgeTreshold %d\n", OldAgeTreshold); fprintf(a_fstream, "OldAgePenalty %3.20f\n", OldAgePenalty); @@ -972,6 +1010,7 @@ namespace NEAT fprintf(a_fstream, "OverallMutationRate %3.20f\n", OverallMutationRate); fprintf(a_fstream, "InterspeciesCrossoverRate %3.20f\n", InterspeciesCrossoverRate); fprintf(a_fstream, "MultipointCrossoverRate %3.20f\n", MultipointCrossoverRate); + fprintf(a_fstream, "PreferFitterParentRate %3.20f\n", PreferFitterParentRate); fprintf(a_fstream, "RouletteWheelSelection %s\n", RouletteWheelSelection == true ? "true" : "false"); fprintf(a_fstream, "PhasedSearching %s\n", PhasedSearching == true ? "true" : "false"); fprintf(a_fstream, "DeltaCoding %s\n", DeltaCoding == true ? "true" : "false"); @@ -998,6 +1037,8 @@ namespace NEAT fprintf(a_fstream, "MutateRemLinkProb %3.20f\n", MutateRemLinkProb); fprintf(a_fstream, "MutateRemSimpleNeuronProb %3.20f\n", MutateRemSimpleNeuronProb); fprintf(a_fstream, "LinkTries %d\n", LinkTries); + fprintf(a_fstream, "MaxLinks %d\n", MaxLinks); + fprintf(a_fstream, "MaxNeurons %d\n", MaxNeurons); fprintf(a_fstream, "RecurrentProb %3.20f\n", RecurrentProb); fprintf(a_fstream, "RecurrentLoopProb %3.20f\n", RecurrentLoopProb); fprintf(a_fstream, "MutateWeightsProb %3.20f\n", MutateWeightsProb); @@ -1007,6 +1048,7 @@ namespace NEAT fprintf(a_fstream, "WeightReplacementRate %3.20f\n", WeightReplacementRate); fprintf(a_fstream, "WeightReplacementMaxPower %3.20f\n", WeightReplacementMaxPower); fprintf(a_fstream, "MaxWeight %3.20f\n", MaxWeight); + fprintf(a_fstream, "MinWeight %3.20f\n", MinWeight); fprintf(a_fstream, "MutateActivationAProb %3.20f\n", MutateActivationAProb); fprintf(a_fstream, "MutateActivationBProb %3.20f\n", MutateActivationBProb); fprintf(a_fstream, "ActivationAMutationMaxPower %3.20f\n", ActivationAMutationMaxPower); @@ -1054,6 +1096,7 @@ namespace NEAT fprintf(a_fstream, "CompatTresholdModifier %3.20f\n", CompatTresholdModifier); fprintf(a_fstream, "CompatTreshChangeInterval_Generations %d\n", CompatTreshChangeInterval_Generations); fprintf(a_fstream, "CompatTreshChangeInterval_Evaluations %d\n", CompatTreshChangeInterval_Evaluations); + fprintf(a_fstream, "MinDeltaCompatEqualGenomes %3.20f\n", MinDeltaCompatEqualGenomes); fprintf(a_fstream, "DivisionThreshold %3.20f\n", DivisionThreshold); @@ -1062,6 +1105,7 @@ namespace NEAT fprintf(a_fstream, "InitialDepth %d\n", InitialDepth); fprintf(a_fstream, "MaxDepth %d\n", MaxDepth); fprintf(a_fstream, "IterationLevel %d\n", IterationLevel); + fprintf(a_fstream, "TournamentSelection %s\n", TournamentSelection == true ? "true" : "false"); fprintf(a_fstream, "TournamentSize %d\n", TournamentSize); fprintf(a_fstream, "CPPN_Bias %3.20f\n", CPPN_Bias); fprintf(a_fstream, "Width %3.20f\n", Width); diff --git a/src/Parameters.h b/src/Parameters.h index 0ca7da7c..d66b0e67 100644 --- a/src/Parameters.h +++ b/src/Parameters.h @@ -31,7 +31,9 @@ /////////////////////////////////////////////////////////////////////////////// #include +//#include "Genes.h" #include "Traits.h" +//#include "Species.h" #ifdef USE_BOOST_PYTHON @@ -67,6 +69,9 @@ class Parameters // Size of population unsigned int PopulationSize; + + // Controls the use of speciation. When off, the population will consist of only one species. + bool Speciation; // If true, this enables dynamic compatibility thresholding // It will keep the number of species between MinSpecies and MaxSpecies @@ -102,6 +107,9 @@ class Parameters #ifdef USE_BOOST_PYTHON // same as above, but for Python py::object pyCustomConstraints; + + // This one computes a behavior based on a genome, for use in behavior speciation + py::object pyBehaviorGetter; #endif //////////////////////////////// @@ -152,12 +160,19 @@ class Parameters // Probability for a baby to result from inter-species mating. double InterspeciesCrossoverRate; - // Probability for a baby to result from Multipoint Crossover when mating. 1.0 = 100% + // Probability for a baby gene to result from Multipoint Crossover when mating. 1.0 = 100% // The default if the Average mating. double MultipointCrossoverRate; - + + // Probability that when doing multipoint crossover, + // the gene of the fitter parent will be prefered, instead of choosing one at random + double PreferFitterParentRate; + // Performing roulette wheel selection or not? bool RouletteWheelSelection; + + // If true, will do tournament selection + bool TournamentSelection; // For tournament selection unsigned int TournamentSize; @@ -252,7 +267,13 @@ class Parameters // Maximum number of tries to find 2 neurons to add/remove a link unsigned int LinkTries; - + + // Maximum number of links in the genome (originals not counted). -1 is unlimited + int MaxLinks; + + // Maximum number of neurons in the genome (originals not counted). -1 is unlimited + int MaxNeurons; + // Probability that a link mutation will be made recurrent double RecurrentProb; @@ -277,8 +298,11 @@ class Parameters // Maximum magnitude of a replaced weight double WeightReplacementMaxPower; - // Maximum absolute magnitude of a weight + // Maximum weight double MaxWeight; + + // Minimum weight + double MinWeight; // Probability for a baby's A activation function parameters to be perturbed double MutateActivationAProb; @@ -383,6 +407,12 @@ class Parameters // Per how many evaluations to change the treshold unsigned int CompatTreshChangeInterval_Evaluations; + // What is the minimal difference needed for not to be a clone + double MinDeltaCompatEqualGenomes; + + // How many times to test a genome for constraint failure or being a clone (when AllowClones=False) + int ConstraintTrials; + ///////////////////////////// // Genome properties params ///////////////////////////// @@ -619,6 +649,11 @@ class Parameters py::object itp = py::extract(trait_params["details"]); t.m_Details = itp; } + else if (t.type == "pyclassset") + { + py::object itp = py::extract(trait_params["details"]); + t.m_Details = itp; + } return t; } @@ -705,6 +740,11 @@ class Parameters t["type"] = "pyobject"; dt = bs::get(pms.m_Details); } + if (pms.type == "pyclassset") + { + t["type"] = "pyclassset"; + dt = bs::get(pms.m_Details); + } t["details"] = dt; @@ -808,6 +848,7 @@ class Parameters void serialize(Archive & ar, const unsigned int version) { ar & PopulationSize; + ar & Speciation; ar & DynamicCompatibility; ar & MinSpecies; ar & MaxSpecies; @@ -818,6 +859,7 @@ class Parameters ar & YoungAgeFitnessBoost; ar & SpeciesMaxStagnation; ar & StagnationDelta; + ar & ConstraintTrials; ar & OldAgeTreshold; ar & OldAgePenalty; ar & DetectCompetetiveCoevolutionStagnation; @@ -828,6 +870,7 @@ class Parameters ar & OverallMutationRate; ar & InterspeciesCrossoverRate; ar & MultipointCrossoverRate; + ar & PreferFitterParentRate; ar & RouletteWheelSelection; ar & PhasedSearching; ar & DeltaCoding; @@ -852,6 +895,8 @@ class Parameters ar & MutateRemLinkProb; ar & MutateRemSimpleNeuronProb; ar & LinkTries; + ar & MaxLinks; + ar & MaxNeurons; ar & RecurrentProb; ar & RecurrentLoopProb; ar & MutateWeightsProb; @@ -861,6 +906,7 @@ class Parameters ar & WeightReplacementRate; ar & WeightReplacementMaxPower; ar & MaxWeight; + ar & MinWeight; ar & MutateActivationAProb; ar & MutateActivationBProb; ar & ActivationAMutationMaxPower; @@ -933,11 +979,12 @@ class Parameters ar & EliteFraction; ar & ArchiveEnforcement; + ar & MinDeltaCompatEqualGenomes; } #endif -}; + }; #ifdef USE_BOOST_PYTHON @@ -973,4 +1020,3 @@ struct Parameters_pickle_suite : py::pickle_suite #endif - diff --git a/src/Population.cpp b/src/Population.cpp index a652d3ef..456103fd 100644 --- a/src/Population.cpp +++ b/src/Population.cpp @@ -31,6 +31,8 @@ #include #include +#include +#include #include "Genome.h" #include "Species.h" @@ -65,10 +67,21 @@ Population::Population(const Genome& a_Seed, const Parameters& a_Parameters, { Genome t_clone = a_Seed; t_clone.SetID(i); - m_Genomes.push_back( t_clone ); + m_Genomes.emplace_back( t_clone ); } - // Now now initialize each genome's weights +#ifdef USE_BOOST_PYTHON + // is it not None? + if (a_Parameters.pyBehaviorGetter.ptr() != py::object().ptr()) + { + for(int i=0; i 0) { - // Compatible, add to species - m_Species[j].AddIndividual( m_Genomes[i] ); - t_added = true; - - break; + if (m_Genomes[i].IsCompatibleWith(m_Species[j].GetRepresentative(), m_Parameters)) + { + // Compatible, add to species + m_Species[j].AddIndividual(m_Genomes[i]); + t_added = true; + + break; + } } } if (!t_added) { // didn't find compatible species, create new species - m_Species.push_back( Species(m_Genomes[i], m_NextSpeciesID)); + m_Species.push_back( Species(m_Genomes[i], m_Parameters, m_NextSpeciesID)); m_NextSpeciesID++; } } // Remove all empty species (cleanup routine for every case..) - std::vector::iterator t_cs = m_Species.begin(); - while(t_cs != m_Species.end()) - { - if (t_cs->NumIndividuals() == 0) - { - // remove the dead species - t_cs = m_Species.erase( t_cs ); - - if (t_cs != m_Species.begin()) // in case the first species are dead - t_cs--; - } - - t_cs++; - } + ClearEmptySpecies(); } @@ -314,7 +340,7 @@ void Population::AdjustFitness() for(unsigned int i=0; i 0); ASSERT(m_Genomes.size() == m_Parameters.PopulationSize); - double t_total_adjusted_fitness = 0; - double t_average_adjusted_fitness = 0; + double t_total_adjusted_fitness = 0.0; + double t_average_adjusted_fitness = 0.0; Genome t_t; // get the total adjusted fitness for all individuals @@ -336,13 +362,22 @@ void Population::CountOffspring() for(unsigned int j=0; j 0); + ASSERT(t_total_adjusted_fitness > 0.0); t_average_adjusted_fitness = t_total_adjusted_fitness / static_cast(m_Parameters.PopulationSize); + if (t_average_adjusted_fitness == 0.0) + { + t_average_adjusted_fitness = 1.0; + } + + + //std::cout << t_average_adjusted_fitness << "\n"; // Calculate how much offspring each individual should have for(unsigned int i=0; i (rs.GetBestFitness())); } @@ -379,6 +414,10 @@ void Population::Sort() // Now sort the species by fitness (best first) std::sort(m_Species.begin(), m_Species.end(), species_greater); + + //for(int i=0;i::min(); for(unsigned int i=0; i 0); - double t_total_fitness = 0; - double t_marble=0, t_spin=0; // roulette wheel variables + /*if (m_Species.size() == 1) + { + return 0; + }*/ + unsigned int t_curspecies = 0; + //do + std::vector probs; + for(int i=0; i a_genome_idx) + { + // it's here + t_genome_rel_idx = a_genome_idx - t_counter; + break; + } + else + { + t_counter += m_Species[i].m_Individuals.size(); + t_species_idx++; + } + /*for(unsigned int j=0; j::iterator t_cur_species = m_Species.begin(); + auto t_cur_species = m_Species.begin(); // No species yet? if (t_cur_species == m_Species.end()) { // create the first species and place the baby there - m_Species.push_back( Species(t_genome, GetNextSpeciesID())); + m_Species.emplace_back( Species(t_genome, m_Parameters, GetNextSpeciesID())); IncrementNextSpeciesID(); } else { // try to find a compatible species - Genome t_to_compare = t_cur_species->GetRepresentative(); + Genome& t_to_compare = t_cur_species->GetRepresentative(); // was GetRepresentative() t_found = false; while((t_cur_species != m_Species.end()) && (!t_found)) @@ -896,15 +940,28 @@ void Population::ReassignSpecies(unsigned int a_genome_idx) { // found a compatible species t_cur_species->AddIndividual(t_genome); + /*if (t_cur_species->m_Individuals.size() == 0) + { + t_cur_species->SetRepresentative(t_genome); // also set it as representative if the species is empty + }*/ t_found = true; // the search is over } else { - // keep searching for a matching species - t_cur_species++; - if (t_cur_species != m_Species.end()) + // keep searching for a matching non-empty species + + while(1) { - t_to_compare = t_cur_species->GetRepresentative(); + t_cur_species++; + if (t_cur_species == m_Species.end()) + { + break; + } + if (t_cur_species->NumIndividuals() > 0) + { + t_to_compare = t_cur_species->GetRepresentative(); + break; + } } } } @@ -912,7 +969,7 @@ void Population::ReassignSpecies(unsigned int a_genome_idx) // if couldn't find a match, make a new species if (!t_found) { - m_Species.push_back( Species(t_genome, GetNextSpeciesID())); + m_Species.emplace_back( Species(t_genome, m_Parameters, GetNextSpeciesID())); IncrementNextSpeciesID(); } } @@ -924,44 +981,60 @@ void Population::ReassignSpecies(unsigned int a_genome_idx) // Set the m_Evaluated flag of the baby to true after evaluation! Genome* Population::Tick(Genome& a_deleted_genome) { - // Make sure all individuals are evaluated - /*for(unsigned int i=0; i m_BestFitnessEver) + + if (t_fitness > m_BestFitnessEver) { // Reset the stagnation counter only if the fitness jump is greater or equal to the delta. - if (fabs(t_Fitness - m_BestFitnessEver) >= m_Parameters.StagnationDelta) + if (fabs(t_fitness - m_BestFitnessEver) >= m_Parameters.StagnationDelta) { m_EvalsSinceBestFitnessLastChanged = 0; } - m_BestFitnessEver = t_Fitness; - m_BestGenomeEver = m_Species[i].m_Individuals[j]; + m_BestFitnessEver = t_fitness; + m_BestGenomeEver = m_Species[i].m_Individuals[j]; } } } double t_f = std::numeric_limits::min(); - for(unsigned int i=0; i t_f) { @@ -969,7 +1042,7 @@ Genome* Population::Tick(Genome& a_deleted_genome) m_BestGenome = m_Species[i].m_Individuals[j]; } - if (m_Species[i].m_Individuals[j].GetFitness() >= m_Species[i].GetBestFitness()) + if (m_Species[i].m_Individuals[j].GetFitness() > m_Species[i].GetBestFitness()) { m_Species[i].m_BestFitness = m_Species[i].m_Individuals[j].GetFitness(); m_Species[i].m_EvalsNoImprovement = 0; @@ -982,64 +1055,195 @@ Genome* Population::Tick(Genome& a_deleted_genome) bool t_changed = false; if (m_Parameters.DynamicCompatibility == true) { + double t_oldcompat = m_Parameters.CompatTreshold; if ((m_NumEvaluations % m_Parameters.CompatTreshChangeInterval_Evaluations) == 0) { if (m_Species.size() > m_Parameters.MaxSpecies) { m_Parameters.CompatTreshold += m_Parameters.CompatTresholdModifier; - t_changed = true; } else if (m_Species.size() < m_Parameters.MinSpecies) { m_Parameters.CompatTreshold -= m_Parameters.CompatTresholdModifier; - t_changed = true; } - if (m_Parameters.CompatTreshold < m_Parameters.MinCompatTreshold) m_Parameters.CompatTreshold = m_Parameters.MinCompatTreshold; + if (m_Parameters.CompatTreshold < m_Parameters.MinCompatTreshold) + m_Parameters.CompatTreshold = m_Parameters.MinCompatTreshold; + + if (m_Parameters.CompatTreshold != t_oldcompat) + { + t_changed = true; + } } } + + // Sort individuals within species by fitness + //Sort(); + // If the compatibility treshold was changed, reassign all individuals by species if (t_changed) { - for(unsigned int i=0; i allgenomes; + for(int i=0; iGetRepresentative(); // was GetRepresentative() + + t_found = false; + while((t_cur_species != m_TempSpecies.end()) && (!t_found)) + { + if (baby.IsCompatibleWith( t_to_compare, m_Parameters )) + { + // found a compatible species + t_cur_species->AddIndividual(baby); + t_found = true; // the search is over + } + else + { + // keep searching for a matching species + t_cur_species++; + if (t_cur_species != m_TempSpecies.end()) + { + t_to_compare = t_cur_species->GetRepresentative(); // was GetRepresentative() + } + } + } + + // if couldn't find a match, make a new species + if (!t_found) + { + m_TempSpecies.push_back( Species(baby, m_Parameters, GetNextSpeciesID()) ); // clone the pop's parameters when creating species + IncrementNextSpeciesID(); + } + } + } + + m_Species = m_TempSpecies; + + // After reassigning, some empty species may be left, so delete them + ClearEmptySpecies(); + }*/ + +#ifdef VDEBUG + SameGenomeIDCheck(); +#endif + +#ifdef VDEBUG + std::cout << "remove worst\n"; +#endif // Remove the worst individual a_deleted_genome = RemoveWorstIndividual(); + +#ifdef VDEBUG + std::cout << "calc avg fitness\n"; +#endif // Recalculate all averages for each species // If the average species fitness of a species is 0, // then there are no evaluated individuals in it. for(unsigned int i=0; i 0); ASSERT(t_baby.NumOutputs() > 0); Genome* t_to_return = NULL; +#ifdef VDEBUG + std::cout << "placing baby in species\n"; +#endif // Add the baby to its proper species bool t_found = false; - std::vector::iterator t_cur_species = m_Species.begin(); + auto t_cur_species = m_Species.begin(); // No species yet? if (t_cur_species == m_Species.end()) { // create the first species and place the baby there - m_Species.push_back( Species(t_baby, GetNextSpeciesID()) ); + m_Species.push_back( Species(t_baby, m_Parameters, GetNextSpeciesID()) ); // clone the pop's parameters when creating species // the last one t_to_return = &(m_Species[ m_Species.size()-1 ].m_Individuals[ m_Species[ m_Species.size()-1 ].m_Individuals.size() - 1]); IncrementNextSpeciesID(); + +#ifdef VDEBUG + std::cout << "made new species\n"; +#endif } else { @@ -1049,81 +1253,163 @@ Genome* Population::Tick(Genome& a_deleted_genome) t_found = false; while((t_cur_species != m_Species.end()) && (!t_found)) { - if (t_baby.IsCompatibleWith( t_to_compare, m_Parameters)) + if (t_baby.IsCompatibleWith( t_to_compare, m_Parameters )) { // found a compatible species t_cur_species->AddIndividual(t_baby); t_to_return = &(t_cur_species->m_Individuals[ t_cur_species->m_Individuals.size() - 1]); t_found = true; // the search is over + + // increase the evals counter for the new species + t_cur_species->IncreaseEvalsNoImprovement(); + +#ifdef VDEBUG + std::cout << "found compatible species\n"; +#endif } else { // keep searching for a matching species - t_cur_species++; + /*t_cur_species++; + while((t_cur_species->NumIndividuals() == 0) && (t_cur_species != m_Species.end())) + t_cur_species++; + if (t_cur_species != m_Species.end()) { - t_to_compare = t_cur_species->GetRepresentative(); - } + t_to_compare = t_cur_species->GetRepresentative(); // was GetRepresentative() + }*/ + + while(1) + { + t_cur_species++; + if (t_cur_species == m_Species.end()) + { + break; + } + if (t_cur_species->NumIndividuals() > 0) + { + t_to_compare = t_cur_species->GetRepresentative(); + break; + } + /*else + { + t_cur_species++; + }*/ + }; } } // if couldn't find a match, make a new species if (!t_found) { - m_Species.push_back( Species(t_baby, GetNextSpeciesID())); + m_Species.push_back( Species(t_baby, m_Parameters, GetNextSpeciesID()) ); // clone the pop's parameters when creating species // the last one t_to_return = &(m_Species[ m_Species.size()-1 ].m_Individuals[ m_Species[ m_Species.size()-1 ].m_Individuals.size() - 1]); IncrementNextSpeciesID(); + +#ifdef VDEBUG + std::cout << "made new species\n"; +#endif } } - + +#ifdef VDEBUG + std::cout << "\n"; +#endif + ASSERT(t_to_return != NULL); return t_to_return; } + +void Population::ClearEmptySpecies() +{ + auto t_cs = m_Species.begin(); + while(t_cs != m_Species.end()) + { + if (t_cs->NumIndividuals() == 0) + { + // remove the dead species + t_cs = m_Species.erase(t_cs ); + if (t_cs != m_Species.begin()) // in case the first species are dead + t_cs--; + } - + t_cs++; + } +} + + Genome Population::RemoveWorstIndividual() { unsigned int t_worst_idx=0; // within the species - //unsigned int t_worst_absolute_idx=0; // within the population unsigned int t_worst_species_idx=0; // within the population double t_worst_fitness = std::numeric_limits::max(); + int numev=0; Genome t_genome; + + bool found=false; // Find and kill the individual with the worst *adjusted* fitness - int t_abs_counter = 0; for(unsigned int i=0; i 0) { - double t_adjusted_fitness = m_Species[i].m_Individuals[j].GetFitness() / static_cast(m_Species[i].m_Individuals.size()); - - // only only evaluated individuals can be removed - if ((t_adjusted_fitness < t_worst_fitness) && (m_Species[i].m_Individuals[j].IsEvaluated())) + double adjinv = 1.0 / static_cast(m_Species[i].m_Individuals.size()); + for (unsigned int j = 0; j < m_Species[i].m_Individuals.size(); j++) { - t_worst_fitness = t_adjusted_fitness; - t_worst_idx = j; - t_worst_species_idx = i; - //t_worst_absolute_idx = t_abs_counter; - t_genome = m_Species[i].m_Individuals[j]; + // only evaluated individuals can be removed + if (m_Species[i].m_Individuals[j].IsEvaluated()) + { + numev++; + double t_adjusted_fitness = m_Species[i].m_Individuals[j].GetFitness() * adjinv; + if (std::isnan(t_adjusted_fitness) || std::isinf(t_adjusted_fitness)) + { + t_adjusted_fitness = 0; + } + + if (t_adjusted_fitness < t_worst_fitness) + { + t_worst_fitness = t_adjusted_fitness; + t_worst_idx = j; + t_worst_species_idx = i; + found = true; + } + } } - - t_abs_counter++; } } + + if (found) + { + t_genome = m_Species[t_worst_species_idx].m_Individuals[t_worst_idx]; + + // make sure this isn't the only evaluated individual + if (numev <= 1) + { + return t_genome; + } - // The individual is now removed - m_Species[t_worst_species_idx].RemoveIndividual(t_worst_idx); - - // If the species becomes empty, remove the species as well - if (m_Species[t_worst_species_idx].m_Individuals.size() == 0) + // The individual is now removed + m_Species[t_worst_species_idx].RemoveIndividual(t_worst_idx); + + // If the species becomes empty, remove the species as well + if (m_Species[t_worst_species_idx].m_Individuals.size() == 0) + { + m_Species.erase(m_Species.begin() + t_worst_species_idx); + } + } + else { - m_Species.erase(m_Species.begin() + t_worst_species_idx); + // set ID of -1 to indicate nothing was removed + t_genome.SetID(-1); +#ifdef VDEBUG + std::cout << "RemoveWorst did not remove anything.\n"; +#endif } - + return t_genome; } @@ -1176,14 +1462,14 @@ double Population::ComputeSparseness(Genome& genome) for(unsigned int j=0; jDistance_To( m_Species[i].m_Individuals[j].m_PhenotypeBehavior ); - t_distances_list.push_back( distance ); + t_distances_list.emplace_back( distance ); } } // then add all distances from the archive for(unsigned int i=0; isize(); i++) { - t_distances_list.push_back( genome.m_PhenotypeBehavior->Distance_To( &((*m_BehaviorArchive)[i]))); + t_distances_list.emplace_back( genome.m_PhenotypeBehavior->Distance_To( &((*m_BehaviorArchive)[i]))); } // sort the list, smaller first @@ -1266,7 +1552,7 @@ bool Population::NoveltySearchTick(Genome& a_SuccessfulGenome) if (!present) { - m_BehaviorArchive->push_back( *(t_new_baby->m_PhenotypeBehavior) ); + m_BehaviorArchive->emplace_back( *(t_new_baby->m_PhenotypeBehavior) ); m_GensSinceLastArchiving = 0; m_QuickAddCounter++; } @@ -1305,14 +1591,7 @@ bool Population::NoveltySearchTick(Genome& a_SuccessfulGenome) a_SuccessfulGenome = *t_new_baby; // OK now last thing, check if this behavior is the one we're looking for. - if (t_new_baby->m_PhenotypeBehavior->Successful()) - { - return true; - } - else - { - return false; - } + return t_new_baby->m_PhenotypeBehavior->Successful(); } diff --git a/src/Population.h b/src/Population.h index 01ede398..aeb77ca0 100644 --- a/src/Population.h +++ b/src/Population.h @@ -107,7 +107,6 @@ class Population // Calculates the current mean population complexity void CalculateMPC(); - // best fitness ever achieved double m_BestFitnessEver; @@ -143,6 +142,8 @@ class Population // The list of species std::vector m_Species; + + int m_ID; //////////////////////////// @@ -157,7 +158,9 @@ class Population // Loads a population from a file. - Population(const char* a_FileName); + Population(const std::string a_FileName); + + Population() {}; //////////////////////////// // Destructor @@ -208,9 +211,6 @@ class Population return m_Species[idx_species].m_Individuals[idx_genome]; } - - - unsigned int GetStagnation() const { return m_GensSinceBestFitnessLastChanged; } unsigned int GetMPCStagnation() const { return m_GensSinceMPCLastChanged; } @@ -218,9 +218,41 @@ class Population unsigned int GetNextSpeciesID() const { return m_NextSpeciesID; } void IncrementNextGenomeID() { m_NextGenomeID++; } void IncrementNextSpeciesID() { m_NextSpeciesID++; } + + + // Make sure no same genome IDs exist in the population + void SameGenomeIDCheck() + { + // count how much each ID found has occured + std::map ids; + for(unsigned int i=0; isecond > 1) + { + char s[256]; + sprintf(s, "Genome ID %d appears %d times in the population\n", it->first, it->second); + throw std::runtime_error(s); + } + } + } - Genome& AccessGenomeByIndex(unsigned int const a_idx); - Genome& AccessGenomeByID(unsigned int const a_id); + Genome& AccessGenomeByIndex(int const a_idx); + Genome& AccessGenomeByID(int const a_id); InnovationDatabase& AccessInnovationDatabase() { return m_InnovationDatabase; } @@ -255,7 +287,9 @@ class Population // Removes worst member of the whole population that has been around for a minimum amount of time // returns the genome that was just deleted (may be useful) Genome RemoveWorstIndividual(); - + + void ClearEmptySpecies(); + // The main reaitime tick. Analog to Epoch(). Replaces the worst evaluated individual with a new one. // Returns a pointer to the new baby. // and copies the genome that was deleted to a_geleted_genome @@ -263,7 +297,7 @@ class Population // Takes an individual and puts it in its apropriate species // Useful in realtime when the compatibility treshold changes - void ReassignSpecies(unsigned int a_genome_idx); + void ReassignSpecies(int a_genome_idx); unsigned int m_NumEvaluations; @@ -294,8 +328,70 @@ class Population // counters for archive stagnation unsigned int m_GensSinceLastArchiving; unsigned int m_QuickAddCounter; + +#ifdef USE_BOOST_PYTHON + // Serialization + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version) + { + ar & m_InnovationDatabase; + ar & m_NextGenomeID; + ar & m_NextSpeciesID; + ar & m_SearchMode; + ar & m_CurrentMPC; + ar & m_OldMPC; + ar & m_BaseMPC; + ar & m_BestFitnessEver; + ar & m_BestGenome; + ar & m_BestGenomeEver; + ar & m_GensSinceBestFitnessLastChanged; + ar & m_EvalsSinceBestFitnessLastChanged; + ar & m_GensSinceMPCLastChanged; + ar & m_Genomes; + ar & m_GenomeArchive; + //ar & m_RNG; + ar & m_Parameters; + ar & m_Generation; + ar & m_Species; + ar & m_NumEvaluations; + ar & m_GensSinceLastArchiving; + ar & m_QuickAddCounter; + ar & m_ID; + + //ar & m_TempSpecies; + //ar & m_BehaviorArchive; + } +#endif + + }; + +#ifdef USE_BOOST_PYTHON + +struct Population_pickle_suite : py::pickle_suite +{ + static py::object getstate(const Population& a) + { + std::ostringstream os; + boost::archive::text_oarchive oa(os); + oa << a; + return py::str (os.str()); + } + + static void setstate(Population& a, py::object entries) + { + py::str s = py::extract (entries)(); + std::string st = py::extract (s)(); + std::istringstream is (st); + + boost::archive::text_iarchive ia (is); + ia >> a; + } }; +#endif + + } // namespace NEAT #endif diff --git a/src/PythonBindings.cpp b/src/PythonBindings.cpp index a39c4aa2..25d96264 100644 --- a/src/PythonBindings.cpp +++ b/src/PythonBindings.cpp @@ -32,13 +32,15 @@ #ifdef USE_BOOST_PYTHON #include - #include + +#ifdef USE_BOOST_NUMPY #if BOOST_VERSION < 106500 #include #else #include #endif +#endif #include #include @@ -55,17 +57,24 @@ namespace py = boost::python; using namespace NEAT; using namespace py; +#ifdef USE_BOOST_NUMPY + #if BOOST_VERSION < 106500 typedef typename numeric::array pyndarray; #else typedef typename numpy::ndarray pyndarray; #endif +#endif + BOOST_PYTHON_MODULE(_MultiNEAT) { Py_Initialize(); + PyErr_Print(); - #if BOOST_VERSION < 106500 +#ifdef USE_BOOST_NUMPY + + #if BOOST_VERSION < 106500 numeric::array::set_module_and_type("numpy", "ndarray"); #else boost::python::numpy::initialize(); @@ -73,6 +82,8 @@ BOOST_PYTHON_MODULE(_MultiNEAT) // On MacOS with 'ImportError: numpy.core.umath failed to import' error is produced, but NEAT still works #endif +#endif + /////////////////////////////////////////////////////////////////// // Enums /////////////////////////////////////////////////////////////////// @@ -108,6 +119,10 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .value("BLENDED", BLENDED) ; + enum_("GenomeSeedType") + .value("PERCEPTRON", PERCEPTRON) + .value("LAYERED", LAYERED) + ; /////////////////////////////////////////////////////////////////// // RNG class @@ -156,7 +171,9 @@ BOOST_PYTHON_MODULE(_MultiNEAT) bool (NeuralNetwork::*NN_Load)(const char*) = &NeuralNetwork::Load; void (Genome::*Genome_Save)(const char*) = &Genome::Save; void (NeuralNetwork::*NN_Input)(const py::list&) = &NeuralNetwork::Input_python_list; +#ifdef USE_BOOST_NUMPY void (NeuralNetwork::*NN_Input_numpy)(const pyndarray&) = &NeuralNetwork::Input_numpy; +#endif void (Parameters::*Parameters_Save)(const char*) = &Parameters::Save; int (Parameters::*Parameters_Load)(const char*) = &Parameters::Load; @@ -204,8 +221,10 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def("Input", NN_Input) +#ifdef USE_BOOST_NUMPY .def("Input", NN_Input_numpy) +#endif .def("Output", &NeuralNetwork::Output) @@ -247,13 +266,22 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def_readwrite("Type", &NeuronGene::m_Type) ; + class_("GenomeInitStruct", init<>()) + .def_readwrite("NumInputs", &GenomeInitStruct::NumInputs) + .def_readwrite("NumHidden", &GenomeInitStruct::NumHidden) + .def_readwrite("NumOutputs", &GenomeInitStruct::NumOutputs) + .def_readwrite("FS_NEAT", &GenomeInitStruct::FS_NEAT) + .def_readwrite("OutputActType", &GenomeInitStruct::OutputActType) + .def_readwrite("HiddenActType", &GenomeInitStruct::HiddenActType) + .def_readwrite("SeedType", &GenomeInitStruct::SeedType) + .def_readwrite("NumLayers", &GenomeInitStruct::NumLayers) + .def_readwrite("FS_NEAT_links", &GenomeInitStruct::FS_NEAT_links) + ; + class_("Genome", init<>()) .def(init()) - .def(init()) - .def(init()) + .def(init()) .def("NumNeurons", &Genome::NumNeurons) .def("NumLinks", &Genome::NumLinks) @@ -272,10 +300,11 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def("DerivePhenotypicChanges", &Genome::DerivePhenotypicChanges) .def("PrintAllTraits", &Genome::PrintAllTraits) + .def("CompatibilityDistance", &Genome::CompatibilityDistance) .def("BuildPhenotype", &Genome::BuildPhenotype) .def("BuildHyperNEATPhenotype", &Genome::BuildHyperNEATPhenotype) - .def("BuildESHyperNEATPhenotype", &Genome::BuildESHyperNEATPhenotype) +// .def("BuildESHyperNEATPhenotype", &Genome::BuildESHyperNEATPhenotype) .def("Randomize_LinkWeights", &Genome::Randomize_LinkWeights) .def("Randomize_Traits", &Genome::Randomize_Traits) @@ -287,6 +316,8 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def("GetNeuronTraits", &Genome::GetNeuronTraits) .def("GetLinkTraits", &Genome::GetLinkTraits) .def("GetGenomeTraits", &Genome::GetGenomeTraits) + + .def("SetGenomeTraits", &Genome::SetGenomeTraits) // experimental .def("FailsConstraints", &Genome::FailsConstraints) @@ -303,8 +334,8 @@ BOOST_PYTHON_MODULE(_MultiNEAT) // Species class /////////////////////////////////////////////////////////////////// - class_("Species", init()) - .def("GetLeader", &Species::GetLeader) + class_("Species", init()) + .def("GetLeader", &Species::GetLeader, return_value_policy()) .def("NumIndividuals", &Species::NumIndividuals) .def("GensNoImprovement", &Species::GensNoImprovement) .def("ID", &Species::ID) @@ -314,6 +345,9 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def_readonly("Red", &Species::m_R) .def_readonly("Green", &Species::m_G) .def_readonly("Blue", &Species::m_B) + .def_readwrite("EvalsNoImprovement", &Species::m_EvalsNoImprovement) + .def_readwrite("BestFitness", &Species::m_BestFitness) + //.def_readwrite("Parameters", &Species::m_Parameters) ; /////////////////////////////////////////////////////////////////// @@ -397,6 +431,9 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def_readwrite("Species", &Population::m_Species) .def_readwrite("Parameters", &Population::m_Parameters) .def_readwrite("RNG", &Population::m_RNG) + .def_readwrite("ID", &Population::m_ID) + + .def_pickle(Population_pickle_suite()) ; /////////////////////////////////////////////////////////////////// @@ -421,6 +458,7 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def("ClearGenomeTraitParameters", &Parameters::ClearGenomeTraitParameters) .def_readwrite("PopulationSize", &Parameters::PopulationSize) + .def_readwrite("Speciation", &Parameters::Speciation) .def_readwrite("DynamicCompatibility", &Parameters::DynamicCompatibility) .def_readwrite("MinSpecies", &Parameters::MinSpecies) .def_readwrite("MaxSpecies", &Parameters::MaxSpecies) @@ -429,9 +467,11 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def_readwrite("ArchiveEnforcement", &Parameters::ArchiveEnforcement) .def_readwrite("NormalizeGenomeSize", &Parameters::NormalizeGenomeSize) .def_readwrite("CustomConstraints", &Parameters::pyCustomConstraints) + .def_readwrite("BehaviorGetter", &Parameters::pyBehaviorGetter) + .def_readwrite("ConstraintTrials", &Parameters::ConstraintTrials) .def_readwrite("YoungAgeTreshold", &Parameters::YoungAgeTreshold) .def_readwrite("YoungAgeFitnessBoost", &Parameters::YoungAgeFitnessBoost) - .def_readwrite("SpeciesDropoffAge", &Parameters::SpeciesMaxStagnation) + .def_readwrite("SpeciesMaxStagnation", &Parameters::SpeciesMaxStagnation) .def_readwrite("StagnationDelta", &Parameters::StagnationDelta) .def_readwrite("OldAgeTreshold", &Parameters::OldAgeTreshold) .def_readwrite("OldAgePenalty", &Parameters::OldAgePenalty) @@ -443,6 +483,7 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def_readwrite("OverallMutationRate", &Parameters::OverallMutationRate) .def_readwrite("InterspeciesCrossoverRate", &Parameters::InterspeciesCrossoverRate) .def_readwrite("MultipointCrossoverRate", &Parameters::MultipointCrossoverRate) + .def_readwrite("PreferFitterParentRate", &Parameters::PreferFitterParentRate) .def_readwrite("RouletteWheelSelection", &Parameters::RouletteWheelSelection) .def_readwrite("PhasedSearching", &Parameters::PhasedSearching) .def_readwrite("DeltaCoding", &Parameters::DeltaCoding) @@ -466,6 +507,8 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def_readwrite("MutateRemLinkProb", &Parameters::MutateRemLinkProb) .def_readwrite("MutateRemSimpleNeuronProb", &Parameters::MutateRemSimpleNeuronProb) .def_readwrite("LinkTries", &Parameters::LinkTries) + .def_readwrite("MaxLinks", &Parameters::MaxLinks) + .def_readwrite("MaxNeurons", &Parameters::MaxNeurons) .def_readwrite("RecurrentProb", &Parameters::RecurrentProb) .def_readwrite("RecurrentLoopProb", &Parameters::RecurrentLoopProb) .def_readwrite("MutateWeightsProb", &Parameters::MutateWeightsProb) @@ -475,6 +518,7 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def_readwrite("WeightReplacementRate", &Parameters::WeightReplacementRate) .def_readwrite("WeightReplacementMaxPower", &Parameters::WeightReplacementMaxPower) .def_readwrite("MaxWeight", &Parameters::MaxWeight) + .def_readwrite("MinWeight", &Parameters::MinWeight) .def_readwrite("MutateActivationAProb", &Parameters::MutateActivationAProb) .def_readwrite("MutateActivationBProb", &Parameters::MutateActivationBProb) .def_readwrite("ActivationAMutationMaxPower", &Parameters::ActivationAMutationMaxPower) @@ -506,6 +550,7 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def_readwrite("ActivationFunction_Linear_Prob", &Parameters::ActivationFunction_Linear_Prob) .def_readwrite("DontUseBiasNeuron", &Parameters::DontUseBiasNeuron) .def_readwrite("AllowLoops", &Parameters::AllowLoops) + .def_readwrite("MutateGenomeTraitsProb", &Parameters::MutateGenomeTraitsProb) .def_readwrite("MutateNeuronTraitsProb", &Parameters::MutateNeuronTraitsProb) .def_readwrite("MutateLinkTraitsProb", &Parameters::MutateLinkTraitsProb) .def_readwrite("DisjointCoeff", &Parameters::DisjointCoeff) @@ -521,6 +566,7 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def_readwrite("CompatTresholdModifier", &Parameters::CompatTresholdModifier) .def_readwrite("CompatTreshChangeInterval_Generations", &Parameters::CompatTreshChangeInterval_Generations) .def_readwrite("CompatTreshChangeInterval_Evaluations", &Parameters::CompatTreshChangeInterval_Evaluations) + .def_readwrite("MinDeltaCompatEqualGenomes", &Parameters::MinDeltaCompatEqualGenomes) .def_readwrite("DivisionThreshold", &Parameters::DivisionThreshold) .def_readwrite("VarianceThreshold", &Parameters::VarianceThreshold) @@ -537,6 +583,7 @@ BOOST_PYTHON_MODULE(_MultiNEAT) .def_readwrite("LeoSeed", &Parameters::LeoSeed) .def_readwrite("GeometrySeed", &Parameters::GeometrySeed) + .def_readwrite("TournamentSelection", &Parameters::TournamentSelection) .def_readwrite("TournamentSize", &Parameters::TournamentSize) .def_readwrite("EliteFraction", &Parameters::EliteFraction) diff --git a/src/PythonBindings.h b/src/PythonBindings.h new file mode 100644 index 00000000..82b09ce9 --- /dev/null +++ b/src/PythonBindings.h @@ -0,0 +1,31 @@ +#ifndef PYTHONBINDINGS_H_ +#define PYTHONBINDINGS_H_ + +/////////////////////////////////////////////////////////////////////////////////////////// +// MultiNEAT - Python/C++ NeuroEvolution of Augmenting Topologies Library +// +// Copyright (C) 2012 Peter Chervenski +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see < http://www.gnu.org/licenses/ >. +// +// Contact info: +// +// Peter Chervenski < spookey@abv.bg > +// Shane Ryan < shane.mcdonald.ryan@gmail.com > +/////////////////////////////////////////////////////////////////////////////////////////// +#if 0 + +#endif + +#endif /* PYTHONBINDINGS_H_ */ \ No newline at end of file diff --git a/src/Random.cpp b/src/Random.cpp index 5a6a9fc8..9b1fdd0a 100644 --- a/src/Random.cpp +++ b/src/Random.cpp @@ -163,6 +163,7 @@ int RNG::Roulette(std::vector& a_probs) boost::random::discrete_distribution<> d_dist(a_probs); return d_dist(gen); #else + double t_marble = 0, t_spin = 0, t_total_score = 0; for(unsigned int i=0; iGetFitness()) > (rs->GetFitness())); - } + }*/ - bool genome_greater(Genome ls, Genome rs) + bool genome_greater(Genome& ls, Genome& rs) { return (ls.GetFitness() > rs.GetFitness()); } + bool idxfitnesspair_greater(std::pair& ls, std::pair& rs) + { + return (ls.second > rs.second); + } + // initializes a species with a representative genome and an ID number - Species::Species(const Genome &a_Genome, int a_ID) + Species::Species(const Genome &a_Genome, const Parameters& a_Parameters, int a_ID) { m_ID = a_ID; - //m_Individuals.reserve(50); wtf is this? + // copy the initializing genome locally. // it is now the representative of the species. - m_Representative = a_Genome; + //m_Representative = a_Genome; m_BestGenome = a_Genome; // add the first and only one individual - m_Individuals.push_back(a_Genome); + m_Individuals.emplace_back(a_Genome); m_AgeGenerations = 0; m_GensNoImprovement = 0; + m_EvalsNoImprovement = 0; m_OffspringRqd = 0; m_BestFitness = a_Genome.GetFitness(); m_BestSpecies = true; m_WorstSpecies = false; m_AverageFitness = 0; + //m_Parameters = a_Parameters; // Choose a random color //RNG rng; @@ -93,18 +100,19 @@ namespace NEAT if (this != &a_S) { m_ID = a_S.m_ID; - m_Representative = a_S.m_Representative; + //m_Representative = a_S.m_Representative; m_BestGenome = a_S.m_BestGenome; m_BestSpecies = a_S.m_BestSpecies; m_WorstSpecies = a_S.m_WorstSpecies; m_BestFitness = a_S.m_BestFitness; m_GensNoImprovement = a_S.m_GensNoImprovement; + m_EvalsNoImprovement = a_S.m_EvalsNoImprovement; + m_AverageFitness = a_S.m_AverageFitness; m_AgeGenerations = a_S.m_AgeGenerations; m_OffspringRqd = a_S.m_OffspringRqd; m_R = a_S.m_R; m_G = a_S.m_G; m_B = a_S.m_B; - m_Individuals = a_S.m_Individuals; } @@ -115,88 +123,118 @@ namespace NEAT // adds a new member to the species and updates variables void Species::AddIndividual(Genome &a_Genome) { - m_Individuals.push_back(a_Genome); + m_Individuals.emplace_back(a_Genome); } - // returns an individual randomly selected from the best N% - Genome Species::GetIndividual(Parameters &a_Parameters, RNG &a_RNG) const + // Individual selection routine + Genome& Species::GetIndividual(Parameters &a_Parameters, RNG &a_RNG) //const { - ASSERT(m_Individuals.size() > 0); + if (m_Individuals.size() == 0) + { + char s[256]; + sprintf(s, "Attempted GetIndividual() but no individuals in species ID %d\n", m_ID); + throw std::runtime_error(s); + } // Make a pool of only evaluated individuals! - std::vector t_Evaluated; + std::vector< std::pair > t_Evaluated; for (unsigned int i = 0; i < m_Individuals.size(); i++) { if (m_Individuals[i].IsEvaluated()) - t_Evaluated.push_back(m_Individuals[i]); + { + t_Evaluated.push_back(std::make_pair(i, m_Individuals[i].GetFitness())); + } } - ASSERT(t_Evaluated.size() > 0); - + // None are evaluated - fall back to random individual + if (t_Evaluated.size() == 0) + { + char s[256]; + sprintf(s, "Attempted GetIndividual() but no evaluated individuals in species ID %d\n", m_ID); + throw std::runtime_error(s); + } if (t_Evaluated.size() == 1) { - return (t_Evaluated[0]); + return (m_Individuals[t_Evaluated[0].first]); } else if (t_Evaluated.size() == 2) { - return (t_Evaluated[Rounded(a_RNG.RandFloat())]); + return (m_Individuals[t_Evaluated[Rounded(a_RNG.RandFloat())].first]); } // Warning!!!! The individuals must be sorted by best fitness for this to work int t_chosen_one = 0; - // then sort them here just to make sure - std::sort(t_Evaluated.begin(), t_Evaluated.end(), genome_greater); - - // Here might be introduced better selection scheme, but this works OK for now - if (!a_Parameters.RouletteWheelSelection) - { //start with the last one just for comparison sake - //int temp_genome; - - //int t_num_parents = static_cast( floor( - // (a_Parameters.SurvivalRate * (static_cast(t_Evaluated.size()))) + 1.0)); - int t_num_parents = (int)(a_Parameters.SurvivalRate * (double)(t_Evaluated.size())); + if (a_Parameters.TournamentSelection) + { + std::vector< std::pair > t_picked; + // choose N individuals at random + for(int i=0; i 0); - ASSERT(t_num_parents < t_Evaluated.size()); - if (t_num_parents >= t_Evaluated.size()) + std::sort(t_picked.begin(), t_picked.end(), idxfitnesspair_greater); + std::vector t_probs; + for (int i = 0; i < t_picked.size(); i++) { - t_num_parents = t_Evaluated.size() - 1; + t_probs.push_back(t_picked.size()-i);//t_picked[i].second); } - t_chosen_one = a_RNG.RandInt(0, t_num_parents); + t_chosen_one = t_picked[a_RNG.Roulette(t_probs)].first; + } + else + { + // sort them here just to make sure + std::sort(t_Evaluated.begin(), t_Evaluated.end(), idxfitnesspair_greater); - /*for (unsigned int i = 0; i < a_Parameters.TournamentSize; i++) + // Here might be introduced better selection scheme, but this works OK for now + if (!a_Parameters.RouletteWheelSelection) { - temp_genome = a_RNG.RandInt(0, t_num_parents); - - if (m_Individuals[temp_genome].GetFitness() > m_Individuals[t_chosen_one].GetFitness()) + int t_num_parents = (int) (a_Parameters.SurvivalRate * (double) (m_Individuals.size())); + + if (t_num_parents >= t_Evaluated.size()) { - t_chosen_one = temp_genome; + t_num_parents = t_Evaluated.size() - 1; } - }*/ - } - else - { - // roulette wheel selection - std::vector t_probs; - for (unsigned int i = 0; i < t_Evaluated.size(); i++) + if (t_num_parents < 1) + { + t_num_parents = 1; + } + + t_chosen_one = t_Evaluated[a_RNG.RandInt(0, t_num_parents)].first; + } + else { - t_probs.push_back(t_Evaluated[i].GetFitness()); + // roulette wheel selection + int t_num_parents = t_Evaluated.size(); + std::vector t_probs; + for (unsigned int i = 0; i < t_num_parents; i++) + { + t_probs.push_back(t_Evaluated[i].second); + } + t_chosen_one = t_Evaluated[a_RNG.Roulette(t_probs)].first; } - t_chosen_one = a_RNG.Roulette(t_probs); } - return (t_Evaluated[t_chosen_one]); + return (m_Individuals[t_chosen_one]); } // returns a completely random individual - Genome Species::GetRandomIndividual(RNG &a_RNG) const + Genome& Species::GetRandomIndividual(RNG &a_RNG) //const { if (m_Individuals.size() == 0) // no members yet, return representative { - return m_Representative; + char s[256]; + sprintf(s, "Attempted GetRandomIndividual() but no individuals in species ID %d\n", m_ID); + throw std::runtime_error(s); + } + else + if (m_Individuals.size() == 1) + { + return m_Individuals[0]; } else { @@ -207,7 +245,7 @@ namespace NEAT } // returns the leader (the member having the best fitness) - Genome Species::GetLeader() const + Genome& Species::GetLeader() //const { // Don't store the leader any more // Perform a search over the members and return the most fit member @@ -215,11 +253,13 @@ namespace NEAT // if empty, return representative if (m_Individuals.size() == 0) { - return m_Representative; + char s[256]; + sprintf(s, "Attempted GetLeader() but no individuals in species ID %d\n", m_ID); + throw std::runtime_error(s); } - double t_max_fitness = -99999999; - int t_leader_idx = -1; + double t_max_fitness = std::numeric_limits::min(); + int t_leader_idx = 0; for (unsigned int i = 0; i < m_Individuals.size(); i++) { double t_f = m_Individuals[i].GetFitness(); @@ -230,14 +270,23 @@ namespace NEAT } } - ASSERT(t_leader_idx != -1); + //ASSERT(t_leader_idx != -1); return (m_Individuals[t_leader_idx]); } - Genome Species::GetRepresentative() const + Genome& Species::GetRepresentative() //const { - return m_Representative; + if (m_Individuals.size() > 0) + { + return m_Individuals[0]; + } + else + { + char s[256]; + sprintf(s, "Attempted GetRepresentative() but no individuals in species ID %d\n", m_ID); + throw std::runtime_error(s); + } } // calculates how many offspring this species should spawn @@ -265,10 +314,14 @@ namespace NEAT // the fitness must be positive //DBG(t_fitness); - ASSERT(t_fitness >= 0); + ASSERT(t_fitness >= 0.0); // this prevents the fitness to be below zero - if (t_fitness <= 0) t_fitness = 0.0001; + if (t_fitness <= 0.0) t_fitness = 0.0000000001; + + // this prevents nan or infinity to be fitness + if (std::isnan(t_fitness)) t_fitness = 0.0000000001; + if (std::isinf(t_fitness)) t_fitness = 0.0000000001; // update the best fitness and stagnation counter if (t_fitness > m_BestFitness) @@ -276,7 +329,7 @@ namespace NEAT m_BestFitness = t_fitness; m_GensNoImprovement = 0; } - + // boost the fitness up to some young age if (m_AgeGenerations < a_Parameters.YoungAgeTreshold) { @@ -301,9 +354,16 @@ namespace NEAT t_fitness *= 0.0000001; } } + + unsigned int ms = m_Individuals.size(); + ASSERT(ms > 0); + if (ms == 0) + { + ms = 1; + } // Compute the adjusted fitness for this member - m_Individuals[i].SetAdjFitness(t_fitness / m_Individuals.size()); + m_Individuals[i].SetAdjFitness(t_fitness / (double)(ms)); } } @@ -314,7 +374,7 @@ namespace NEAT } -// Removes an individual from the species by its index within the species + // Removes an individual from the species by its index within the species void Species::RemoveIndividual(unsigned int a_idx) { ASSERT(a_idx < m_Individuals.size()); @@ -330,14 +390,14 @@ namespace NEAT { Genome t_baby; // temp genome for reproduction - int t_offspring_count = Rounded(GetOffspringRqd()); - int elite_offspring = Rounded(a_Parameters.EliteFraction * m_Individuals.size()); + unsigned int t_offspring_count = Rounded(GetOffspringRqd()); + unsigned int elite_offspring = 1;//Rounded(a_Parameters.EliteFraction * m_Individuals.size()); if (elite_offspring < 1) // can't be 0 { elite_offspring = 1; } // ensure we have a champ - int elite_count = 0; + unsigned int elite_count = 0; // no offspring?! yikes.. dead species! if (t_offspring_count == 0) { @@ -353,15 +413,24 @@ namespace NEAT bool t_baby_exists_in_pop = false; while (t_offspring_count--) { + // clear baby just in case + t_baby = Genome(); + // Select the elite first.. if (elite_count < elite_offspring) { - t_baby = m_Individuals[elite_count]; + //t_baby = m_Individuals[elite_count]; + t_baby = GetLeader();//m_Individuals[elite_count]; elite_count++; } else { + unsigned int t_constraint_trials = a_Parameters.ConstraintTrials; // to prevent infinite loops + + //std::cout << "offspring count:" << t_offspring_count << "\n"; + //std::cout << "making baby\n"; + do // - while the baby already exists somewhere in the new population or turned invalid in some way { // this tells us if the baby is a result of mating @@ -369,6 +438,8 @@ namespace NEAT // There must be individuals there.. ASSERT(NumIndividuals() > 0); + + //std::cout << "trying to mate.."; // for a species of size 1 we can only mutate // NOTE: but does it make sense since we know this is the champ? @@ -380,13 +451,12 @@ namespace NEAT // else we can mate else { - Genome t_mom = GetIndividual(a_Parameters, a_RNG); - // choose whether to mate at all // Do not allow crossover when in simplifying phase if ((a_RNG.RandFloat() < a_Parameters.CrossoverRate) && (a_Pop.GetSearchMode() != SIMPLIFYING)) { // get the father + Genome t_mom; Genome t_dad; bool t_interspecies = false; @@ -394,35 +464,48 @@ namespace NEAT if ((a_RNG.RandFloat() < a_Parameters.InterspeciesCrossoverRate) && (a_Pop.m_Species.size() > 1)) { - // Find different species (random one) // !!!!!!!!!!!!!!!!! - int t_diffspec = a_RNG.RandInt(0, static_cast(a_Pop.m_Species.size() - 1)); - t_dad = a_Pop.m_Species[t_diffspec].GetIndividual(a_Parameters, a_RNG); - t_interspecies = true; + /// Find different species via roulette over average fitness as probability + std::vector probs; + double allp=0; + for(int i=0; i 0) + { + int t_diffspec = a_RNG.Roulette(probs); + t_mom = GetIndividual(a_Parameters, a_RNG); + t_dad = a_Pop.m_Species[t_diffspec].GetIndividual(a_Parameters, a_RNG); + t_interspecies = true; + } + else + { + continue; + } } else { // Mate within species + t_mom = GetIndividual(a_Parameters, a_RNG); t_dad = GetIndividual(a_Parameters, a_RNG); // The other parent should be a different one // number of tries to find different parent - int t_tries = 1024; - if (!a_Parameters.AllowClones) + int t_tries = 32; + while (((t_mom.GetID() == t_dad.GetID())) && (t_tries--)) { - while (((t_mom.GetID() == t_dad.GetID()) || - (t_mom.CompatibilityDistance(t_dad, a_Parameters) < COMPAT_EQUALITY_DELTA)) && - (t_tries--)) - { - t_dad = GetIndividual(a_Parameters, a_RNG); - } - } - else - { - while (((t_mom.GetID() == t_dad.GetID())) && (t_tries--)) - { - t_dad = GetIndividual(a_Parameters, a_RNG); - } + t_mom = GetIndividual(a_Parameters, a_RNG); + t_dad = GetIndividual(a_Parameters, a_RNG); } + t_interspecies = false; } @@ -439,19 +522,26 @@ namespace NEAT t_mated = true; } - // don't mate - reproduce the mother asexually + // don't mate - reproduce one individual asexually else { - t_baby = t_mom; + t_baby = GetIndividual(a_Parameters, a_RNG); t_mated = false; } } + + //std::cout << "mated:" << t_mated << "\n"; + + //std::cout << "trying to mutate.."; // Mutate the baby + bool dummy=false; if ((!t_mated) || (a_RNG.RandFloat() < a_Parameters.OverallMutationRate)) { - MutateGenome(t_baby_exists_in_pop, a_Pop, t_baby, a_Parameters, a_RNG); + MutateGenome(dummy, a_Pop, t_baby, a_Parameters, a_RNG); } + + //std::cout << "mutated." << "\n"; // Check if this baby is already present somewhere in the offspring // we don't want that @@ -465,7 +555,7 @@ namespace NEAT { if ( (t_baby.CompatibilityDistance(a_Pop.m_TempSpecies[i].m_Individuals[j], - a_Parameters) < COMPAT_EQUALITY_DELTA) // identical genome? + a_Parameters) < a_Parameters.MinDeltaCompatEqualGenomes) // identical genome? ) { t_baby_exists_in_pop = true; @@ -482,7 +572,7 @@ namespace NEAT { if ( (t_baby.CompatibilityDistance(a_Pop.m_GenomeArchive[i], - a_Parameters) < COMPAT_EQUALITY_DELTA) // identical genome? + a_Parameters) < a_Parameters.MinDeltaCompatEqualGenomes) // identical genome? ) { t_baby_exists_in_pop = true; @@ -490,8 +580,13 @@ namespace NEAT } } } + + //std::cout << "baby exists in pop:" << t_baby_exists_in_pop << "\n"; } - while (t_baby_exists_in_pop || (t_baby.FailsConstraints(a_Parameters))); // end do + while ((t_baby_exists_in_pop || (t_baby.FailsConstraints(a_Parameters))) && (t_constraint_trials--)); // end do + + //std::cout << "done after " << a_Parameters.ConstraintTrials - t_constraint_trials << "\n"; + //std::cout << "fails constraints:" << t_baby.FailsConstraints(a_Parameters) << "\n\n"; } // We have a new offspring now @@ -508,11 +603,20 @@ namespace NEAT t_baby.SetOffspringAmount(0); t_baby.ResetEvaluated(); - + + // Compute the baby's behavior if possible, before it's added to the species +#ifdef USE_BOOST_PYTHON + // is it not None? + if (a_Parameters.pyBehaviorGetter.ptr() != py::object().ptr()) + { + t_baby.m_behavior = a_Parameters.pyBehaviorGetter(t_baby); + } +#endif + // Archive the baby if needed if (a_Parameters.ArchiveEnforcement) { - a_Pop.m_GenomeArchive.push_back(t_baby); + a_Pop.m_GenomeArchive.emplace_back(t_baby); } ////////////////////////////////// @@ -525,19 +629,19 @@ namespace NEAT // after all reproduction completes, the original species will be replaced back bool t_found = false; - std::vector::iterator t_cur_species = a_Pop.m_TempSpecies.begin(); + auto t_cur_species = a_Pop.m_TempSpecies.begin(); // No species yet? if (t_cur_species == a_Pop.m_TempSpecies.end()) { // create the first species and place the baby there - a_Pop.m_TempSpecies.push_back(Species(t_baby, a_Pop.GetNextSpeciesID())); + a_Pop.m_TempSpecies.emplace_back(Species(t_baby, a_Parameters, a_Pop.GetNextSpeciesID())); a_Pop.IncrementNextSpeciesID(); } else { // try to find a compatible species - Genome t_to_compare = t_cur_species->GetRepresentative(); + Genome t_to_compare = t_cur_species->GetRepresentative(); // was GetRepresentative() t_found = false; while ((t_cur_species != a_Pop.m_TempSpecies.end()) && (!t_found)) @@ -551,10 +655,24 @@ namespace NEAT else { // keep searching for a matching species - t_cur_species++; + /*t_cur_species++; if (t_cur_species != a_Pop.m_TempSpecies.end()) { - t_to_compare = t_cur_species->GetRepresentative(); + t_to_compare = t_cur_species->GetRepresentative(); // was GetRepresentative() + }*/ + + while(1) + { + t_cur_species++; + if (t_cur_species == a_Pop.m_TempSpecies.end()) + { + break; + } + if (t_cur_species->NumIndividuals() > 0) + { + t_to_compare = t_cur_species->GetRepresentative(); + break; + } } } } @@ -562,7 +680,7 @@ namespace NEAT // if couldn't find a match, make a new species if (!t_found) { - a_Pop.m_TempSpecies.push_back(Species(t_baby, a_Pop.GetNextSpeciesID())); + a_Pop.m_TempSpecies.emplace_back(Species(t_baby, a_Parameters, a_Pop.GetNextSpeciesID())); a_Pop.IncrementNextSpeciesID(); } } @@ -580,32 +698,44 @@ namespace NEAT // consider individuals that were evaluated only! for (unsigned int i = 0; i < m_Individuals.size(); i++) { - if (m_Individuals[i].m_Evaluated) + if (m_Individuals[i].IsEvaluated()) { - t_total_fitness += m_Individuals[i].GetFitness(); - t_num_individuals++; + double tf = m_Individuals[i].GetFitness(); + if (std::isinf(tf) || std::isnan(tf)) // nan/inf guard + { + tf = 0.0; + } + t_total_fitness += tf; } + t_num_individuals++; } if (t_num_individuals > 0) + { m_AverageFitness = t_total_fitness / static_cast(t_num_individuals); + } else + { m_AverageFitness = 0; + } } Genome Species::ReproduceOne(Population &a_Pop, Parameters &a_Parameters, RNG &a_RNG) { - Genome t_baby; // for storing the result - ////////////////////////// // Reproduction bool t_baby_exists_in_pop = false; bool t_baby_is_clone = false; + int t_constraint_trials = a_Parameters.ConstraintTrials; // Spawn only one baby + Genome t_baby;// = GetRandomIndividual(a_RNG); // for storing the result + do // - while the baby turned invalid in some way { + t_baby = Genome(); // clear baby + // this tells us if the baby is a result of mating bool t_mated = false; @@ -622,13 +752,12 @@ namespace NEAT // else we can mate else { - Genome t_mom = GetIndividual(a_Parameters, a_RNG); - // choose whether to mate at all // Do not allow crossover when in simplifying phase if ((a_RNG.RandFloat() < a_Parameters.CrossoverRate) && (a_Pop.GetSearchMode() != SIMPLIFYING)) { - // get the father + // get the mother and father + Genome t_mom; Genome t_dad; bool t_interspecies = false; @@ -636,34 +765,47 @@ namespace NEAT if ((a_RNG.RandFloat() < a_Parameters.InterspeciesCrossoverRate) && (a_Pop.m_Species.size() > 1)) { - // Find different species (random one) // !!!!!!!!!!!!!!!!! - int t_diffspec = a_RNG.RandInt(0, static_cast(a_Pop.m_Species.size() - 1)); - t_dad = a_Pop.m_Species[t_diffspec].GetIndividual(a_Parameters, a_RNG); - t_interspecies = true; + // Find different species via roulette over average fitness as probability + std::vector probs; + double allp=0; + for(int i=0; i 0) + { + int t_diffspec = a_RNG.Roulette(probs); + t_mom = GetIndividual(a_Parameters, a_RNG); + t_dad = a_Pop.m_Species[t_diffspec].GetIndividual(a_Parameters, a_RNG); + t_interspecies = true; + } + else + { + continue; + } } else { // Mate within species + t_mom = GetIndividual(a_Parameters, a_RNG); t_dad = GetIndividual(a_Parameters, a_RNG); // The other parent should be a different one // number of tries to find different parent - int t_tries = 1024; - if (!a_Parameters.AllowClones) + // we can mate the same mom and dad and still get different baby + int t_tries=32; + while (((t_mom.GetID() == t_dad.GetID())) && (t_tries--)) { - while (((t_mom.GetID() == t_dad.GetID()) || - (t_mom.CompatibilityDistance(t_dad, a_Parameters) < COMPAT_EQUALITY_DELTA)) && - (t_tries--)) - { - t_dad = GetIndividual(a_Parameters, a_RNG); - } - } - else - { - while (((t_mom.GetID() == t_dad.GetID())) && (t_tries--)) - { - t_dad = GetIndividual(a_Parameters, a_RNG); - } + t_mom = GetIndividual(a_Parameters, a_RNG); + t_dad = GetIndividual(a_Parameters, a_RNG); } t_interspecies = false; } @@ -678,22 +820,29 @@ namespace NEAT { t_baby = t_mom.Mate(t_dad, true, t_interspecies, a_RNG, a_Parameters); } - + +#ifdef VDEBUG + std::cout << "mated baby\n"; +#endif t_mated = true; } - // don't mate - reproduce the mother asexually + // don't mate - reproduce one individual asexually else { - t_baby = t_mom; + t_baby = GetIndividual(a_Parameters, a_RNG); t_mated = false; } } // Mutate the baby t_baby_is_clone = false; + bool dummy=false; if ((!t_mated) || (a_RNG.RandFloat() < a_Parameters.OverallMutationRate)) { - MutateGenome(t_baby_is_clone, a_Pop, t_baby, a_Parameters, a_RNG); + MutateGenome(dummy, a_Pop, t_baby, a_Parameters, a_RNG); +#ifdef VDEBUG + std::cout << "mutated baby\n"; +#endif } // Check if this baby is already present somewhere in the offspring @@ -708,7 +857,7 @@ namespace NEAT { if ( (t_baby.CompatibilityDistance(a_Pop.m_Species[i].m_Individuals[j], - a_Parameters) < COMPAT_EQUALITY_DELTA) // identical genome? + a_Parameters) < a_Parameters.MinDeltaCompatEqualGenomes) // identical genome? ) { t_baby_exists_in_pop = true; @@ -719,13 +868,13 @@ namespace NEAT } // In case we want to enforce always new individuals - if (a_Parameters.ArchiveEnforcement) + if (a_Parameters.ArchiveEnforcement && (!t_baby_exists_in_pop)) { for (unsigned int i = 0; i < a_Pop.m_GenomeArchive.size(); i++) { if ( (t_baby.CompatibilityDistance(a_Pop.m_GenomeArchive[i], - a_Parameters) < COMPAT_EQUALITY_DELTA) // identical genome? + a_Parameters) < a_Parameters.MinDeltaCompatEqualGenomes) // identical genome? ) { t_baby_exists_in_pop = true; @@ -734,7 +883,7 @@ namespace NEAT } } } - while (t_baby_exists_in_pop || t_baby.FailsConstraints(a_Parameters)); // end do + while ((t_baby_exists_in_pop || t_baby.FailsConstraints(a_Parameters)) && (t_constraint_trials--)); // end do // We have a new offspring now @@ -751,13 +900,26 @@ namespace NEAT t_baby.SetOffspringAmount(0); t_baby.ResetEvaluated(); + + // Compute the baby's behavior if possible, before it's added to the species +#ifdef USE_BOOST_PYTHON + // is it not None? + if (a_Parameters.pyBehaviorGetter.ptr() != py::object().ptr()) + { + t_baby.m_behavior = a_Parameters.pyBehaviorGetter(t_baby); + } +#endif // In case of archiving, add the new baby to the archive if (a_Parameters.ArchiveEnforcement) { - a_Pop.m_GenomeArchive.push_back(t_baby); + a_Pop.m_GenomeArchive.emplace_back(t_baby); } +#ifdef VDEBUG + std::cout << "baby success\n"; +#endif + return t_baby; } @@ -767,19 +929,39 @@ namespace NEAT Species::MutateGenome(bool t_baby_is_clone, Population &a_Pop, Genome &t_baby, Parameters &a_Parameters, RNG &a_RNG) { #if 0 - if ((a_RNG.RandFloat() < a_Parameters.MutateAddNeuronProb) && (a_Pop.GetSearchMode() != SIMPLIFYING)) + if ((a_RNG.RandFloat() < a_Parameters.MutateAddNeuronProb) && ((a_Pop.GetSearchMode() == COMPLEXIFYING) || (a_Pop.GetSearchMode() == BLENDED))) { - t_baby.Mutate_AddNeuron(a_Pop.AccessInnovationDatabase(), a_Parameters, a_RNG); + if (a_Parameters.MaxNeurons > 0) + { + if ((t_baby.NumNeurons() - (t_baby.NumInputs() + t_baby.NumOutputs())) < a_Parameters.MaxNeurons) + { + t_baby.Mutate_AddNeuron(a_Pop.AccessInnovationDatabase(), a_Parameters, a_RNG); + } + } + else + { + t_baby.Mutate_AddNeuron(a_Pop.AccessInnovationDatabase(), a_Parameters, a_RNG); + } } - else if ((a_RNG.RandFloat() < a_Parameters.MutateAddLinkProb) && (a_Pop.GetSearchMode() != SIMPLIFYING)) + else if ((a_RNG.RandFloat() < a_Parameters.MutateAddLinkProb) && ((a_Pop.GetSearchMode() == COMPLEXIFYING) || (a_Pop.GetSearchMode() == BLENDED))) { - t_baby.Mutate_AddLink(a_Pop.AccessInnovationDatabase(), a_Parameters, a_RNG); + if (a_Parameters.MaxLinks > 0) + { + if (t_baby.NumLinks() < a_Parameters.MaxLinks) + { + t_baby.Mutate_AddLink(a_Pop.AccessInnovationDatabase(), a_Parameters, a_RNG); + } + } + else + { + t_baby.Mutate_AddLink(a_Pop.AccessInnovationDatabase(), a_Parameters, a_RNG); + } } - else if ((a_RNG.RandFloat() < a_Parameters.MutateRemSimpleNeuronProb) && (a_Pop.GetSearchMode() != COMPLEXIFYING)) + else if ((a_RNG.RandFloat() < a_Parameters.MutateRemSimpleNeuronProb) && ((a_Pop.GetSearchMode() == SIMPLIFYING) || (a_Pop.GetSearchMode() == BLENDED))) { - t_baby.Mutate_RemoveSimpleNeuron(a_Pop.AccessInnovationDatabase(), a_RNG); + t_baby.Mutate_RemoveSimpleNeuron(a_Pop.AccessInnovationDatabase(), a_Parameters, a_RNG); } - else if ((a_RNG.RandFloat() < a_Parameters.MutateRemLinkProb) && (a_Pop.GetSearchMode() != COMPLEXIFYING)) + else if ((a_RNG.RandFloat() < a_Parameters.MutateRemLinkProb) && ((a_Pop.GetSearchMode() == SIMPLIFYING) || (a_Pop.GetSearchMode() == BLENDED))) { // Keep doing this mutation until it is sure that the baby will not // end up having dead ends or no links @@ -814,32 +996,51 @@ namespace NEAT else { if (a_RNG.RandFloat() < a_Parameters.MutateNeuronActivationTypeProb) + { t_baby.Mutate_NeuronActivation_Type(a_Parameters, a_RNG); + } if (a_RNG.RandFloat() < a_Parameters.MutateWeightsProb) + { t_baby.Mutate_LinkWeights(a_Parameters, a_RNG); + } if (a_RNG.RandFloat() < a_Parameters.MutateActivationAProb) + { t_baby.Mutate_NeuronActivations_A(a_Parameters, a_RNG); + } if (a_RNG.RandFloat() < a_Parameters.MutateActivationBProb) + { t_baby.Mutate_NeuronActivations_B(a_Parameters, a_RNG); + } if (a_RNG.RandFloat() < a_Parameters.MutateNeuronTimeConstantsProb) + { t_baby.Mutate_NeuronTimeConstants(a_Parameters, a_RNG); + } if (a_RNG.RandFloat() < a_Parameters.MutateNeuronBiasesProb) + { t_baby.Mutate_NeuronBiases(a_Parameters, a_RNG); + } if (a_RNG.RandFloat() < a_Parameters.MutateNeuronTraitsProb) + { t_baby.Mutate_NeuronTraits(a_Parameters, a_RNG); + } if (a_RNG.RandFloat() < a_Parameters.MutateLinkTraitsProb) + { t_baby.Mutate_LinkTraits(a_Parameters, a_RNG); + } if (a_RNG.RandFloat() < a_Parameters.MutateGenomeTraitsProb) + { t_baby.Mutate_GenomeTraits(a_Parameters, a_RNG); + } } + #else // We will perform roulette wheel selection to choose the type of mutation and will mutate the baby // This method guarantees that the baby will be mutated at least with one mutation @@ -853,43 +1054,43 @@ namespace NEAT std::vector t_mut_probs; // ADD_NODE; - t_mut_probs.push_back(a_Parameters.MutateAddNeuronProb); + t_mut_probs.emplace_back(a_Parameters.MutateAddNeuronProb); // ADD_LINK; - t_mut_probs.push_back(a_Parameters.MutateAddLinkProb); + t_mut_probs.emplace_back(a_Parameters.MutateAddLinkProb); // REMOVE_NODE; - t_mut_probs.push_back(a_Parameters.MutateRemSimpleNeuronProb); + t_mut_probs.emplace_back(a_Parameters.MutateRemSimpleNeuronProb); // REMOVE_LINK; - t_mut_probs.push_back(a_Parameters.MutateRemLinkProb); + t_mut_probs.emplace_back(a_Parameters.MutateRemLinkProb); // CHANGE_ACTIVATION_FUNCTION; - t_mut_probs.push_back(a_Parameters.MutateNeuronActivationTypeProb); + t_mut_probs.emplace_back(a_Parameters.MutateNeuronActivationTypeProb); // MUTATE_WEIGHTS; - t_mut_probs.push_back(a_Parameters.MutateWeightsProb); + t_mut_probs.emplace_back(a_Parameters.MutateWeightsProb); // MUTATE_ACTIVATION_A; - t_mut_probs.push_back(a_Parameters.MutateActivationAProb); + t_mut_probs.emplace_back(a_Parameters.MutateActivationAProb); // MUTATE_ACTIVATION_B; - t_mut_probs.push_back(a_Parameters.MutateActivationBProb); + t_mut_probs.emplace_back(a_Parameters.MutateActivationBProb); // MUTATE_TIMECONSTS; - t_mut_probs.push_back(a_Parameters.MutateNeuronTimeConstantsProb); + t_mut_probs.emplace_back(a_Parameters.MutateNeuronTimeConstantsProb); // MUTATE_BIASES; - t_mut_probs.push_back(a_Parameters.MutateNeuronBiasesProb); + t_mut_probs.emplace_back(a_Parameters.MutateNeuronBiasesProb); // MUTATE_NEURON_TRAITS; - t_mut_probs.push_back( a_Parameters.MutateNeuronTraitsProb ); + t_mut_probs.emplace_back( a_Parameters.MutateNeuronTraitsProb ); // MUTATE_LINK_TRAITS; - t_mut_probs.push_back( a_Parameters.MutateLinkTraitsProb ); + t_mut_probs.emplace_back( a_Parameters.MutateLinkTraitsProb ); // MUTATE_GENOME_TRAITS; - t_mut_probs.push_back( a_Parameters.MutateGenomeTraitsProb ); + t_mut_probs.emplace_back( a_Parameters.MutateGenomeTraitsProb ); // Special consideration for phased searching - do not allow certain mutations depending on the search mode // also don't use additive mutations if we just want to get rid of the clones @@ -923,7 +1124,7 @@ namespace NEAT break; case REMOVE_NODE: - t_mutation_success = t_baby.Mutate_RemoveSimpleNeuron(a_Pop.AccessInnovationDatabase(), a_RNG); + t_mutation_success = t_baby.Mutate_RemoveSimpleNeuron(a_Pop.AccessInnovationDatabase(), a_Parameters, a_RNG); break; case REMOVE_LINK: diff --git a/src/Species.h b/src/Species.h index 5a3dbad5..b9b7962f 100644 --- a/src/Species.h +++ b/src/Species.h @@ -46,6 +46,17 @@ class Population; // The Species class ////////////////////////////////////////////// +enum SelectionMode +{ + TRUNCATION, + ROULETTE, + RANK_LINEAR, + RANK_EXP, + TOURNAMENT, + STOCHASTIC, + BOLTZMANN +}; + class Species { @@ -59,7 +70,7 @@ class Species int m_ID; // Keep a local copy of the representative - Genome m_Representative; + //Genome m_Representative; // This tell us if this is the best species in the population bool m_BestSpecies; @@ -95,17 +106,34 @@ class Species // Safe to access directly. int m_R, m_G, m_B; + double m_AverageFitness; + + //////////////////////////// // Constructors //////////////////////////// + Species() + { + m_ID = 0; + m_BestSpecies = false; + m_WorstSpecies = false; + m_OffspringRqd = 0; + m_AgeGenerations = 0; + m_AgeEvaluations = 0; + m_BestFitness = 0; + m_GensNoImprovement = 0; + m_EvalsNoImprovement = 0; + m_R = m_G = m_B = 0; + }; + // initializes a species with a leader genome and an ID number - Species(const Genome& a_Seed, int a_id); + Species(const Genome& a_Seed, const Parameters& a_Parameters, int a_id); // assignment operator Species& operator=(const Species& a_g); - // comparison operator (nessesary for boost::python) + // comparison operator (for boost::python) // todo: implement a better comparison technique bool operator==(Species const& other) const { return m_ID == other.m_ID; } @@ -119,6 +147,21 @@ class Species // Access double GetBestFitness() const { return m_BestFitness; } + double GetActualBestFitness() const + { + double f = std::numeric_limits::min(); + for(int i=0; i f) + { + f = m_Individuals[i].GetFitness(); + } + } + } + return f; + } void SetBestSpecies(bool t) { m_BestSpecies = t; } void SetWorstSpecies(bool t) { m_WorstSpecies = t; } void IncreaseAgeGens() { m_AgeGenerations++; } @@ -139,21 +182,31 @@ class Species Genome GetIndividualByIdx(int a_idx) const { return (m_Individuals[a_idx]); } bool IsBestSpecies() const { return m_BestSpecies; } bool IsWorstSpecies() const { return m_WorstSpecies; } - void SetRepresentative(Genome& a_G) { m_Representative = a_G; } + //void SetRepresentative(Genome& a_G) { m_Representative = a_G; } + int NumEvaluated() + { + int x=0; + for(int i=0; i + void serialize(Archive & ar, const unsigned int version) + { + ar & m_ID; + //ar & m_Representative; + ar & m_BestSpecies; + ar & m_WorstSpecies; + ar & m_AgeGenerations; + ar & m_AgeEvaluations; + ar & m_OffspringRqd; + ar & m_BestFitness; + ar & m_BestGenome; + ar & m_GensNoImprovement; + ar & m_EvalsNoImprovement; + ar & m_R; + ar & m_G; + ar & m_B; + ar & m_Individuals; + ar & m_AverageFitness; + } +#endif + }; } // namespace NEAT diff --git a/src/Substrate.cpp b/src/Substrate.cpp index 0ee9a145..cb7f36ad 100644 --- a/src/Substrate.cpp +++ b/src/Substrate.cpp @@ -121,17 +121,17 @@ Substrate::Substrate(py::list a_inputs, py::list a_hidden, py::list a_outputs) for(int i=0; i(a_inputs[i][j])); + m_input_coords[i].emplace_back(py::extract(a_inputs[i][j])); } for(int i=0; i(a_hidden[i][j])); + m_hidden_coords[i].emplace_back(py::extract(a_hidden[i][j])); } for(int i=0; i(a_outputs[i][j])); + m_output_coords[i].emplace_back(py::extract(a_outputs[i][j])); } } @@ -154,21 +154,21 @@ void Substrate::SetNeurons(py::list a_inputs, py::list a_hidden, py::list a_outp { for(int j=0; j(a_inputs[i][j])); + m_input_coords[i].emplace_back(py::extract(a_inputs[i][j])); } } for(int i=0; i(a_hidden[i][j])); + m_hidden_coords[i].emplace_back(py::extract(a_hidden[i][j])); } } for(int i=0; i(a_outputs[i][j])); + m_output_coords[i].emplace_back(py::extract(a_outputs[i][j])); } } } @@ -187,12 +187,12 @@ void Substrate::SetCustomConnectivity(py::list a_conns) int dst_idx = py::extract(a_conns[i][3]); std::vector c; - c.push_back(src_type); - c.push_back(src_idx); - c.push_back(dst_type); - c.push_back(dst_idx); + c.emplace_back(src_type); + c.emplace_back(src_idx); + c.emplace_back(dst_type); + c.emplace_back(dst_idx); - m_custom_connectivity.push_back( c ); + m_custom_connectivity.emplace_back( c ); } } @@ -208,12 +208,12 @@ void Substrate::SetCustomConnectivity(std::vector< std::vector >& a_conns) int dst_idx = a_conns[i][3]; std::vector c; - c.push_back(src_type); - c.push_back(src_idx); - c.push_back(dst_type); - c.push_back(dst_idx); + c.emplace_back(src_type); + c.emplace_back(src_idx); + c.emplace_back(dst_type); + c.emplace_back(dst_idx); - m_custom_connectivity.push_back( c ); + m_custom_connectivity.emplace_back( c ); } } @@ -293,5 +293,5 @@ void Substrate::PrintInfo() } // namespace NEAT -} +} diff --git a/src/Traits.h b/src/Traits.h index c2f4ad12..3e2f2513 100644 --- a/src/Traits.h +++ b/src/Traits.h @@ -29,24 +29,47 @@ namespace NEAT class intsetelement { public: + int value; + // Comparison operator bool operator==(const intsetelement& rhs) const { return rhs.value == value; } - - int value; + + // Assignment operator + intsetelement &operator=(const intsetelement &a_g) + { + if (this != &a_g) + { + value = a_g.value; + } + + return *this; + } }; class floatsetelement { public: + + double value; + // Comparison operator bool operator==(const floatsetelement& rhs) const { return rhs.value == value; } + + floatsetelement &operator=(const floatsetelement &a_g) + { + if (this != &a_g) + { + value = a_g.value; + } + + return *this; + } - double value; }; typedef bs::variant set; // the set of possible strings std::vector probs; // their respective probabilities for appearance + StringTraitParameters &operator=(const StringTraitParameters &a_g) + { + if (this != &a_g) + { + set = a_g.set; + probs = a_g.probs; + } + + return *this; + } }; class IntSetTraitParameters { public: std::vector set; // the set of possible ints std::vector probs; // their respective probabilities for appearance + + IntSetTraitParameters &operator=(const IntSetTraitParameters &a_g) + { + if (this != &a_g) + { + set = a_g.set; + probs = a_g.probs; + } + + return *this; + } }; class FloatSetTraitParameters { public: std::vector set; // the set of possible floats std::vector probs; // their respective probabilities for appearance + + FloatSetTraitParameters &operator=(const FloatSetTraitParameters &a_g) + { + if (this != &a_g) + { + set = a_g.set; + probs = a_g.probs; + } + + return *this; + } }; - class TraitParameters { public: @@ -132,7 +212,22 @@ namespace NEAT type = "int"; m_Details = IntTraitParameters(); dep_key = ""; - dep_values.push_back( std::string("") ); + dep_values.emplace_back( std::string("") ); + } + + TraitParameters &operator=(const TraitParameters &a_g) + { + if (this != &a_g) + { + m_ImportanceCoeff = a_g.m_ImportanceCoeff; + m_MutationProb = a_g.m_MutationProb; + type = a_g.type; + m_Details = a_g.m_Details; + dep_key = a_g.dep_key; + dep_values = a_g.dep_values; + } + + return *this; } }; @@ -144,12 +239,24 @@ namespace NEAT Trait() { value = 0; - dep_values.push_back(0); + dep_values.emplace_back(0); dep_key = ""; } std::string dep_key; // counts only if this other trait exists.. std::vector dep_values; // and has this value + + Trait &operator=(const Trait &a_g) + { + if (this != &a_g) + { + value = a_g.value; + dep_values = a_g.dep_values; + dep_key = a_g.dep_key; + } + + return *this; + } }; } diff --git a/src/Utils.h b/src/Utils.h index 28c9a077..6e4c4610 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -99,7 +99,7 @@ inline void Clamp(double &a_Arg, const double a_Min, const double a_Max) } //clamps the first argument between the second two -inline void Clamp(float &a_Arg, const double a_Min, const double a_Max) +inline void Clamp(float &a_Arg, const float a_Min, const float a_Max) { ASSERT(a_Min <= a_Max); diff --git a/travis/build_docker.sh b/travis/build_docker.sh old mode 100755 new mode 100644 diff --git a/travis/install.sh b/travis/install.sh old mode 100755 new mode 100644 diff --git a/travis/main.sh b/travis/main.sh old mode 100755 new mode 100644 diff --git a/travis/run.sh b/travis/run.sh old mode 100755 new mode 100644 diff --git a/travis/run_in_docker.sh b/travis/run_in_docker.sh old mode 100755 new mode 100644