aboutsummaryrefslogtreecommitdiff
path: root/include/HyperNeat
diff options
context:
space:
mode:
authorPaul Oliver <contact@pauloliver.dev>2024-02-29 19:04:34 +0100
committerPaul Oliver <contact@pauloliver.dev>2024-02-29 19:16:14 +0100
commite6ab4a8ed100d5d5b7611c74cf3ccd556f1f1d71 (patch)
tree129cf13c2f9b3eae54402300db4570815789a02a /include/HyperNeat
Initial commitHEADmaster
Diffstat (limited to 'include/HyperNeat')
-rw-r--r--include/HyperNeat/Behavior.hpp40
-rw-r--r--include/HyperNeat/Cppn.hpp58
-rw-r--r--include/HyperNeat/Genome.hpp42
-rw-r--r--include/HyperNeat/Innovation.hpp25
-rw-r--r--include/HyperNeat/NeuralNet.hpp78
-rw-r--r--include/HyperNeat/NeuralNetPrms.hpp25
-rw-r--r--include/HyperNeat/NodeSearchPrms.hpp33
-rw-r--r--include/HyperNeat/NoveltyMetric.hpp37
-rw-r--r--include/HyperNeat/NoveltyMetricPrms.hpp20
-rw-r--r--include/HyperNeat/Organism.hpp71
-rw-r--r--include/HyperNeat/Population.hpp148
-rw-r--r--include/HyperNeat/PopulationPrms.hpp63
-rw-r--r--include/HyperNeat/QuadTree.hpp30
-rw-r--r--include/HyperNeat/Utils/Atomic.hpp12
-rw-r--r--include/HyperNeat/Utils/Function.hpp12
-rw-r--r--include/HyperNeat/Utils/LoadFile.hpp40
-rw-r--r--include/HyperNeat/Utils/Map.hpp12
-rw-r--r--include/HyperNeat/Utils/NodeTypes.hpp22
-rw-r--r--include/HyperNeat/Utils/Pi.hpp9
-rw-r--r--include/HyperNeat/Utils/Point.hpp21
-rw-r--r--include/HyperNeat/Utils/Pointer.hpp12
-rw-r--r--include/HyperNeat/Utils/Random.hpp14
-rw-r--r--include/HyperNeat/Utils/SaveFile.hpp45
-rw-r--r--include/HyperNeat/Utils/Set.hpp12
-rw-r--r--include/HyperNeat/Utils/Size.hpp12
-rw-r--r--include/HyperNeat/Utils/String.hpp11
-rw-r--r--include/HyperNeat/Utils/Thread.hpp11
-rw-r--r--include/HyperNeat/Utils/ValueMap.hpp12
-rw-r--r--include/HyperNeat/Utils/ValuePoint.hpp19
-rw-r--r--include/HyperNeat/Utils/Vector.hpp12
-rw-r--r--include/HyperNeat/Utils/Vector2D.hpp12
31 files changed, 970 insertions, 0 deletions
diff --git a/include/HyperNeat/Behavior.hpp b/include/HyperNeat/Behavior.hpp
new file mode 100644
index 0000000..2f474a6
--- /dev/null
+++ b/include/HyperNeat/Behavior.hpp
@@ -0,0 +1,40 @@
+#ifndef __HYPERNEAT_BEHAVIOR_HPP__
+#define __HYPERNEAT_BEHAVIOR_HPP__
+
+#include <HyperNeat/Utils/Size.hpp>
+#include <HyperNeat/Utils/Vector.hpp>
+
+namespace hyperneat
+{
+ class Organism;
+ class NoveltyMetric;
+
+ class Behavior
+ {
+ public:
+ void clear();
+ void reset(bool archive = true);
+
+ double& at(size_t i);
+ double getNoveltyScore() const;
+ bool isToBeArchived() const;
+ Organism& getOrganism();
+ const NoveltyMetric& getNoveltyMetric() const;
+ const Vector<double>& getCharacterization() const;
+
+ bool _criteriaReached = true;
+
+ private:
+ double _noveltyScore = 0.0;
+ bool _isReady = false;
+ bool _toBeArchived = false;
+ Organism* _organism = nullptr;
+ NoveltyMetric* _noveltyMetric = nullptr;
+ Vector<double> _characterization;
+
+ friend class LoadFile;
+ friend class NoveltyMetric;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/Cppn.hpp b/include/HyperNeat/Cppn.hpp
new file mode 100644
index 0000000..a4511c8
--- /dev/null
+++ b/include/HyperNeat/Cppn.hpp
@@ -0,0 +1,58 @@
+#ifndef __HYPERNEAT_CPPN_HPP__
+#define __HYPERNEAT_CPPN_HPP__
+
+#include <HyperNeat/Utils/Size.hpp>
+#include <HyperNeat/Utils/ValueMap.hpp>
+#include <HyperNeat/Utils/Vector2D.hpp>
+#include <HyperNeat/Utils/NodeTypes.hpp>
+
+namespace hyperneat
+{
+ class Genome;
+ class NodeSearchPrms;
+
+ class Cppn
+ {
+ public:
+ Cppn() = default;
+
+ void create(const Genome& genome);
+ void clear();
+
+ size_t getInputsCount() const;
+ size_t getOutputsCount() const;
+ size_t getNodesCount() const;
+
+ double& inputAt(size_t i);
+ double outputAt(size_t i) const;
+
+ void cycle();
+ void findNodesIn2DSection(ValueMap& valueMap, const NodeSearchPrms& qpPrms, const Point& source = Point());
+
+ private:
+ class Node
+ {
+ public:
+ void appendInput();
+ void flushOutput();
+
+ class Link
+ {
+ public:
+ double* _input = nullptr;
+ double _weight = 0.0;
+ };
+
+ Vector<Link> _links;
+ NodeType _nodeType = NodeType::NULL_TYPE;
+ double _storedInput = 0.0;
+ double _output = 0.0;
+ };
+
+ Vector<double> _inputs;
+ Vector<double*> _outputs;
+ Vector2D<Node> _nodeLayers;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/Genome.hpp b/include/HyperNeat/Genome.hpp
new file mode 100644
index 0000000..d8f678f
--- /dev/null
+++ b/include/HyperNeat/Genome.hpp
@@ -0,0 +1,42 @@
+#ifndef __HYPERNEAT_GENOME_HPP__
+#define __HYPERNEAT_GENOME_HPP__
+
+#include <HyperNeat/Utils/Map.hpp>
+#include <HyperNeat/Utils/Size.hpp>
+#include <HyperNeat/Utils/NodeTypes.hpp>
+
+namespace hyperneat
+{
+ class Genome
+ {
+ public:
+ Genome() = default;
+ explicit Genome(size_t inputs);
+
+ class NodeGene
+ {
+ public:
+ NodeGene() = default;
+ NodeGene(double depth, NodeType nodeType);
+
+ class LinkGene
+ {
+ public:
+ LinkGene() = default;
+ LinkGene(double weight, bool isEnabled = true);
+
+ double _weight = 0.0;
+ bool _isEnabled = true;
+ };
+
+ double _depth = 0.0;
+ NodeType _nodeType = NodeType::NULL_TYPE;
+ Map<size_t, LinkGene> _linkGenes;
+ };
+
+ size_t _inputs = 0;
+ Map<size_t, NodeGene> _nodeGenes;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/Innovation.hpp b/include/HyperNeat/Innovation.hpp
new file mode 100644
index 0000000..ac618e5
--- /dev/null
+++ b/include/HyperNeat/Innovation.hpp
@@ -0,0 +1,25 @@
+#ifndef __HYPERNEAT_INNOVATION_HPP__
+#define __HYPERNEAT_INNOVATION_HPP__
+
+#include <Hyperneat/Utils/Size.hpp>
+#include <Hyperneat/Utils/NodeTypes.hpp>
+
+namespace hyperneat
+{
+ class Innovation
+ {
+ public:
+ Innovation() = default;
+ Innovation(size_t number, size_t source, size_t target, double depth, NodeType nodeType);
+
+ bool operator== (const Innovation& other) const;
+
+ size_t _number = 0;
+ size_t _source = 0;
+ size_t _target = 0;
+ double _depth = 0.0;
+ NodeType _nodeType = NodeType::NULL_TYPE;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/NeuralNet.hpp b/include/HyperNeat/NeuralNet.hpp
new file mode 100644
index 0000000..7f4a81f
--- /dev/null
+++ b/include/HyperNeat/NeuralNet.hpp
@@ -0,0 +1,78 @@
+#ifndef __HYPERNEAT_NEURALNET_HPP__
+#define __HYPERNEAT_NEURALNET_HPP__
+
+#include <HyperNeat/Utils/Size.hpp>
+#include <HyperNeat/Utils/ValueMap.hpp>
+
+namespace hyperneat
+{
+ class Cppn;
+ class NeuralNetPrms;
+
+ class NeuralNet
+ {
+ public:
+ class Neuron;
+
+ NeuralNet() = default;
+
+ void create(Cppn& cppn, const NeuralNetPrms& nnPrms);
+ void clear();
+
+ size_t getInputsCount() const;
+ size_t getOutputsCount() const;
+ size_t getNeuronsCount() const;
+
+ const Vector<double*>& getInputs() const;
+ const Vector<double*>& getOutputs() const;
+ const Vector<Neuron>& getNeurons() const;
+
+ double getAverageActivation() const;
+
+ double& inputAt(size_t i);
+ double outputAt(size_t i) const;
+
+ void cycle();
+
+ class Neuron
+ {
+ public:
+ enum class Type {
+ INPUT, HIDDEN, OUTPUT
+ };
+
+ Neuron() = default;
+ Neuron(const Point& position, Type type, double bias);
+
+ void appendInput();
+ void flushOutput();
+
+ class Synapse
+ {
+ public:
+ Synapse() = default;
+ Synapse(Neuron* inputNeuron, double weight);
+
+ double* _input = nullptr;
+ Neuron* _neuron = nullptr;
+ double _weight = 0.0;
+ };
+
+ Vector<Synapse> _synapses;
+ Point _position;
+ Type _type = Type::HIDDEN;
+ double _bias = 0.0;
+ double _storedInput = 0.0;
+ double _output = 0.0;
+ };
+
+ private:
+ Vector<double*> _inputs;
+ Vector<double*> _outputs;
+ Vector<Neuron> _neurons;
+
+ friend class Organism;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/NeuralNetPrms.hpp b/include/HyperNeat/NeuralNetPrms.hpp
new file mode 100644
index 0000000..fb5c349
--- /dev/null
+++ b/include/HyperNeat/NeuralNetPrms.hpp
@@ -0,0 +1,25 @@
+#ifndef __HYPERNEAT_NEURALNETPRMS_HPP__
+#define __HYPERNEAT_NEURALNETPRMS_HPP__
+
+#include <HyperNeat/Utils/Size.hpp>
+#include <HyperNeat/Utils/Point.hpp>
+#include <HyperNeat/Utils/Vector.hpp>
+
+namespace hyperneat
+{
+ class NeuralNetPrms
+ {
+ public:
+ Vector<Point> _inputMap;
+ Vector<Point> _outputMap;
+ size_t _testGridLevel = 3;
+ size_t _maxQuadTreeLevel = SIZE_MAX;
+ size_t _minQuadTreeLevel = 0;
+ double _bandPruningThreshold = 0.3;
+ double _varianceThreshold = 0.03;
+ double _divisionThreshold = 0.03;
+ size_t _iterations = SIZE_MAX;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/NodeSearchPrms.hpp b/include/HyperNeat/NodeSearchPrms.hpp
new file mode 100644
index 0000000..52d9083
--- /dev/null
+++ b/include/HyperNeat/NodeSearchPrms.hpp
@@ -0,0 +1,33 @@
+#ifndef __HYPERNEAT_QUERYPLANEPRMS_HPP__
+#define __HYPERNEAT_QUERYPLANEPRMS_HPP__
+
+#include <HyperNeat/Utils/Size.hpp>
+
+namespace hyperneat
+{
+ class NeuralNetPrms;
+
+ class NodeSearchPrms
+ {
+ public:
+ NodeSearchPrms() = default;
+ NodeSearchPrms(size_t o, size_t x, size_t y);
+ NodeSearchPrms(size_t o, size_t x, size_t y, size_t d);
+
+ void importFrom(const NeuralNetPrms& nnPrms);
+
+ size_t _o = 0;
+ size_t _x = 0;
+ size_t _y = 1;
+ bool _useDistance = true;
+ size_t _d = 4;
+ size_t _testGridLevel = 3;
+ size_t _maxQuadTreeLevel = -1;
+ size_t _minQuadTreeLevel = 0;
+ double _bandPruningThreshold = 0.3;
+ double _varianceThreshold = 0.03;
+ double _divisionThreshold = 0.03;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/NoveltyMetric.hpp b/include/HyperNeat/NoveltyMetric.hpp
new file mode 100644
index 0000000..01a6f75
--- /dev/null
+++ b/include/HyperNeat/NoveltyMetric.hpp
@@ -0,0 +1,37 @@
+#ifndef __HYPERNEAT_NOVELTY_METRIC_HPP__
+#define __HYPERNEAT_NOVELTY_METRIC_HPP__
+
+#include <Hyperneat/Behavior.hpp>
+#include <Hyperneat/Utils/Vector2D.hpp>
+#include <Hyperneat/NoveltyMetricPrms.hpp>
+
+namespace hyperneat
+{
+ class Population;
+
+ class NoveltyMetric
+ {
+ public:
+ const NoveltyMetricPrms& getPrms() const;
+ const Vector<Behavior>& getBehaviors() const;
+ const Vector2D<double>& getArchive() const;
+
+ Behavior& getBehaviorOf(size_t i);
+
+ private:
+ void initialize(const NoveltyMetricPrms& prms, Population* population = nullptr);
+ void setScores();
+
+ double getDistance(const Vector<double>& v1, const Vector<double>& v2) const;
+
+ NoveltyMetricPrms _prms;
+ Vector<Behavior> _behaviors;
+ Vector2D<double> _archive;
+
+ friend class Behavior;
+ friend class LoadFile;
+ friend class Population;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/NoveltyMetricPrms.hpp b/include/HyperNeat/NoveltyMetricPrms.hpp
new file mode 100644
index 0000000..305d075
--- /dev/null
+++ b/include/HyperNeat/NoveltyMetricPrms.hpp
@@ -0,0 +1,20 @@
+#ifndef __HYPERNEAT_NOVELTY_METRIC_PRMS_HPP__
+#define __HYPERNEAT_NOVELTY_METRIC_PRMS_HPP__
+
+#include <Hyperneat/Utils/Size.hpp>
+
+namespace hyperneat
+{
+ class Population;
+
+ class NoveltyMetricPrms
+ {
+ public:
+ double _noveltyThreshold = 10.0;
+ size_t _referenceOrganisms = 15;
+ size_t _characterizationSize = 3;
+ bool _criteriaReachedByDefault = true;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/Organism.hpp b/include/HyperNeat/Organism.hpp
new file mode 100644
index 0000000..d35210c
--- /dev/null
+++ b/include/HyperNeat/Organism.hpp
@@ -0,0 +1,71 @@
+#ifndef __HYPERNEAT_ORGANISM_HPP__
+#define __HYPERNEAT_ORGANISM_HPP__
+
+#include <HyperNeat/Genome.hpp>
+#include <HyperNeat/NeuralNet.hpp>
+#include <HyperNeat/Utils/Atomic.hpp>
+#include <HyperNeat/Utils/Pointer.hpp>
+
+namespace hyperneat
+{
+ class Behavior;
+ class NeuralNet;
+ class Population;
+ class NeuralNetPrms;
+
+ class Organism
+ {
+ public:
+ Organism(const Organism& other);
+ Organism& operator=(const Organism& other);
+
+ size_t getIndex() const;
+
+ void lock();
+ void unlock();
+ bool isLocked() const;
+
+ void freeze();
+ void unfreeze();
+ bool isFrozen() const;
+
+ bool isBeingGenerated() const;
+ size_t getSpecie() const;
+ bool isOld() const;
+ size_t getLifetime() const;
+
+ Behavior& getBehavior();
+ const Genome& getGenome() const;
+
+ bool isChampion() const;
+ Population& getPopulation() const;
+
+ void createNeuralNet();
+
+ Pointer<NeuralNet> _neuralNet;
+ double _fitness = 0.0;
+
+ private:
+ Organism(Population* population);
+ Organism(size_t inputs, Population* population);
+
+ void reset(bool archive = false);
+
+ size_t _index = 0;
+ bool _isLocked = false;
+ bool _isFrozen = false;
+ Atomic<bool> _isBeingGenerated = {false};
+ size_t _specie = 0;
+ size_t _lifetime = 0;
+ Behavior* _behavior = nullptr;
+ Genome _genome;
+
+ Population* _population = nullptr;
+
+ friend class LoadFile;
+ friend class Population;
+ friend class NoveltyMetric;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/Population.hpp b/include/HyperNeat/Population.hpp
new file mode 100644
index 0000000..6d79d14
--- /dev/null
+++ b/include/HyperNeat/Population.hpp
@@ -0,0 +1,148 @@
+#ifndef __HYPERNEAT_POPULATION_HPP__
+#define __HYPERNEAT_POPULATION_HPP__
+
+#include <HyperNeat/Organism.hpp>
+#include <HyperNeat/Innovation.hpp>
+#include <HyperNeat/Utils/Random.hpp>
+#include <HyperNeat/Utils/Vector.hpp>
+#include <HyperNeat/Utils/Pointer.hpp>
+#include <HyperNeat/NeuralNetPrms.hpp>
+#include <HyperNeat/NoveltyMetric.hpp>
+#include <HyperNeat/Utils/Vector2D.hpp>
+#include <HyperNeat/Utils/Function.hpp>
+#include <HyperNeat/PopulationPrms.hpp>
+
+namespace hyperneat
+{
+ class NeuralNet;
+ class NoveltyMetricPrms;
+
+ class Population
+ {
+ public:
+ void create(const PopulationPrms& popPrms);
+ void create(const PopulationPrms& popPrms, const NeuralNetPrms& nnPrms);
+ void create(const PopulationPrms& popPrms, const NeuralNetPrms& nnPrms, const NoveltyMetricPrms& nmPrms);
+ void shutdown(bool resetOrganisms = false, bool archiveOrganisms = false);
+ ~Population();
+
+ void setMinimumLifetime(size_t lifetime);
+
+ const PopulationPrms& getPopulationPrms() const;
+ const NeuralNetPrms& getNeuralNetPrms() const;
+ bool hasNeuralNets() const;
+ const Vector<Organism>& getAllOrganisms() const;
+ const Vector2D<Organism*>& getSpecies() const;
+
+ Organism& getOrganism(size_t i);
+ Organism& getChampion();
+ const Vector<Organism*>& getSpecie(size_t i) const;
+
+ void lock();
+ void unlock();
+ bool isLocked() const;
+
+ void lockOrganism(size_t i);
+ void unlockOrganism(size_t i);
+ bool isOrganismLocked(size_t i) const;
+ bool isAnyOrganismLocked() const;
+ size_t getLockedOrganisms() const;
+
+ void freezeOrganism(size_t i);
+ void unfreezeOrganism(size_t i);
+ bool isOrganismFrozen(size_t i) const;
+ bool isAnyOrganismFrozen() const;
+ size_t getFrozenOrganisms() const;
+
+ bool isOrganismBeingGenerated(size_t i) const;
+ bool isAnyOrganismBeingGenerated() const;
+ size_t getOrganismsBeingGenerated() const;
+
+ size_t getReadyOrganisms() const;
+
+ const Vector<Innovation>& getInnovations() const;
+ size_t getInnovationsCount() const;
+ size_t getBasicInnovationsCount() const;
+ Organism* getLastReplacement();
+ Organism* getLastMother();
+ Organism* getLastFather();
+ size_t getReplacements() const;
+ bool recentReplacement() const;
+ double getDistanceThreshold() const;
+ size_t getOldOrganisms() const;
+ size_t getMinimumOldOrganisms() const;
+ double getAverageFitness() const;
+ double getAverageOldFitness() const;
+
+ void setNoveltyMetric(const NoveltyMetricPrms& prms);
+ void clearNoveltyMetric();
+ bool isNoveltyMetricSet() const;
+ const NoveltyMetric& getNoveltyMetric() const;
+
+ size_t getUpdates() const;
+
+ double& fitnessOf(size_t i);
+ bool update(Function<void(void)> beforeReplacement = []() {}, Function<void(void)> afterReplacement = []() {});
+
+ private:
+ void generateAllNeuralNets();
+
+ void replaceOrganism();
+ Organism* killPoorOrganism();
+ Vector<Organism*>* chooseParentSpecie();
+
+ void breedAsexually(Genome& child, const Genome& mother);
+ void breedSexually(Genome& child, const Genome& mother, const Genome& father);
+ bool mutateNodesAndLinks(Genome& child);
+
+ void assignToSpecie(Organism& org);
+ void organizeSpecies();
+ double computeDistance(const Genome& g1, const Genome& g2) const;
+
+ size_t getRandSeed() const;
+ size_t getRandSize(size_t low, size_t hi);
+ double getRandReal(double low, double hi);
+ double getRandWeight();
+ double getWeightDeviation();
+ NodeType getRandNodeType();
+ bool getChance(double ratio);
+
+ PopulationPrms _prms;
+ Pointer<NeuralNetPrms> _nnPrms;
+ Vector2D<Organism*> _species;
+ Vector<Organism> _allOrganisms;
+
+ bool _populationLock = false;
+ size_t _lockedOrganisms = 0;
+ size_t _frozenOrganisms = 0;
+ Atomic<size_t> _organismsBeingGenerated = {0};
+
+ Vector<Innovation> _innovations;
+ size_t _basicInnovs = 0;
+
+ Organism* _lastReplacement = nullptr;
+ Organism* _lastMother = nullptr;
+ Organism* _lastFather = nullptr;
+ size_t _replacements = 0;
+ bool _recentReplacement = false;
+ double _distanceThreshold = 0.0;
+ size_t _oldOrganisms = 0;
+ size_t _minOldOrganisms = 0;
+
+ Pointer<NoveltyMetric> _noveltyMetric;
+
+ size_t _updates = 0;
+
+ RandGen _randGen;
+ IntDist _nodeTypeSelector = IntDist(0, NODE_TYPES_COUNT - 1);
+ RealDist _weightSelector = RealDist(0.0, 1.0);
+ BellDist _weightDeviator;
+ RealDist _chanceSelector;
+
+ friend class LoadFile;
+ friend class Organism;
+ friend class NoveltyMetric;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/PopulationPrms.hpp b/include/HyperNeat/PopulationPrms.hpp
new file mode 100644
index 0000000..21a6bc3
--- /dev/null
+++ b/include/HyperNeat/PopulationPrms.hpp
@@ -0,0 +1,63 @@
+#ifndef __HYPERNEAT_POPULATIONPRMS_HPP__
+#define __HYPERNEAT_POPULATIONPRMS_HPP__
+
+// #include <cereal/cereal.hpp>
+#include <HyperNeat/Utils/Size.hpp>
+
+namespace hyperneat
+{
+ class PopulationPrms
+ {
+ public:
+ size_t _popSize = 200;
+ size_t _cppnInputs = 6;
+ size_t _cppnOutputs = 2;
+ size_t _seed = 0;
+ double _weightRange = 1.0;
+ double _c1Disjoint = 1.0;
+ double _c3WeightDifference = 0.4;
+ double _initialDistanceThreshold = 4.0;
+ double _distanceThresholdShift = 0.3;
+ double _sexualReproductionRate = 0.5;
+ double _weightMutationRate = 0.94;
+ double _weightDeviation = 0.25;
+ double _interspeciesMatingRate = 0.001;
+ double _geneDisablingRatio = 0.75;
+ double _linkMutationRate = 0.03;
+ double _nodeMutationRate = 0.01;
+ size_t _targetSpeciesCount = 8;
+ double _eligibilityRatio = 0.5;
+ size_t _minimumLifetime = 120;
+ size_t _replBeforeReorganization = 5;
+
+ // private:
+ // friend class cereal::access;
+
+ // template <class Archive>
+ // void serialize(Archive &ar)
+ // {
+ // ar(CEREAL_NVP(_popSize));
+ // ar(CEREAL_NVP(_cppnInputs));
+ // ar(CEREAL_NVP(_cppnOutputs));
+ // ar(CEREAL_NVP(_seed));
+ // ar(CEREAL_NVP(_weightRange));
+ // ar(CEREAL_NVP(_c1Disjoint));
+ // ar(CEREAL_NVP(_c3WeightDifference));
+ // ar(CEREAL_NVP(_initialDistanceThreshold));
+ // ar(CEREAL_NVP(_distanceThresholdShift));
+ // ar(CEREAL_NVP(_sexualReproductionRate));
+ // ar(CEREAL_NVP(_weightMutationRate));
+ // ar(CEREAL_NVP(_weightDeviation));
+ // ar(CEREAL_NVP(_interspeciesMatingRate));
+ // ar(CEREAL_NVP(_geneDisablingRatio));
+ // ar(CEREAL_NVP(_linkMutationRate));
+ // ar(CEREAL_NVP(_nodeMutationRate));
+ // ar(CEREAL_NVP(_targetSpeciesCount));
+ // ar(CEREAL_NVP(_eligibilityRatio));
+ // ar(CEREAL_NVP(_minimumLifetime));
+ // ar(CEREAL_NVP(_replBeforeReorganization));
+ // }
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/QuadTree.hpp b/include/HyperNeat/QuadTree.hpp
new file mode 100644
index 0000000..8090254
--- /dev/null
+++ b/include/HyperNeat/QuadTree.hpp
@@ -0,0 +1,30 @@
+#ifndef __HYPERNEAT_QUADTREE_HPP__
+#define __HYPERNEAT_QUADTREE_HPP__
+
+#include <HyperNeat/Utils/Vector.hpp>
+#include <HyperNeat/Utils/Function.hpp>
+
+namespace hyperneat
+{
+ class QuadTree
+ {
+ public:
+ QuadTree() = default;
+ QuadTree(double segment, double x, double y);
+
+ double getSegment() const;
+ double getX() const;
+ double getY() const;
+
+ void subdivide(Function<bool(QuadTree*)> subdivider);
+ void traverse(Function<void(const QuadTree*)> traverser) const;
+
+ private:
+ Vector<QuadTree> _children;
+ double _segment = 0.0;
+ double _x = 0.0;
+ double _y = 0.0;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/Atomic.hpp b/include/HyperNeat/Utils/Atomic.hpp
new file mode 100644
index 0000000..850a06e
--- /dev/null
+++ b/include/HyperNeat/Utils/Atomic.hpp
@@ -0,0 +1,12 @@
+#ifndef __HYPERNEAT_ATOM_HPP__
+#define __HYPERNEAT_ATOM_HPP__
+
+#include <atomic>
+
+namespace hyperneat
+{
+ template <class T>
+ using Atomic = std::atomic<T>;
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/Function.hpp b/include/HyperNeat/Utils/Function.hpp
new file mode 100644
index 0000000..ebcb27b
--- /dev/null
+++ b/include/HyperNeat/Utils/Function.hpp
@@ -0,0 +1,12 @@
+#ifndef __HYPERNEAT_FUNCTION_HPP__
+#define __HYPERNEAT_FUNCTION_HPP__
+
+#include <functional>
+
+namespace hyperneat
+{
+ template <class F>
+ using Function = std::function<F>;
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/LoadFile.hpp b/include/HyperNeat/Utils/LoadFile.hpp
new file mode 100644
index 0000000..1960e90
--- /dev/null
+++ b/include/HyperNeat/Utils/LoadFile.hpp
@@ -0,0 +1,40 @@
+#ifndef __HYPERNEAT_LOADFILE_HPP__
+#define __HYPERNEAT_LOADFILE_HPP__
+
+#include <iostream>
+#include <HyperNeat/Utils/String.hpp>
+#include <HyperNeat/Utils/Vector.hpp>
+
+namespace hyperneat
+{
+ using Istream = std::istream;
+
+ class Genome;
+ class Organism;
+ class Population;
+ class NoveltyMetric;
+ class PopulationPrms;
+ class NoveltyMetricPrms;
+
+ class LoadFile
+ {
+ public:
+ LoadFile(Istream& stream);
+
+ void loadPopulation(Population& population);
+ void loadPopulationPrms(PopulationPrms& prms);
+ void loadNeuralNetPrms(NeuralNetPrms& prms);
+ void loadNoveltyMetric(NoveltyMetric& noveltyMetric);
+ void loadNoveltyMetricPrms(NoveltyMetricPrms& prms);
+ void loadOrganism(Organism& organism);
+ void loadGenome(Genome& genome);
+
+ private:
+ Istream& nextPrm(bool arrayVal = false);
+ Istream& nextArrayValue();
+
+ Istream& _stream;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/Map.hpp b/include/HyperNeat/Utils/Map.hpp
new file mode 100644
index 0000000..c735ab3
--- /dev/null
+++ b/include/HyperNeat/Utils/Map.hpp
@@ -0,0 +1,12 @@
+#ifndef __HYPERNEAT_MAP_HPP__
+#define __HYPERNEAT_MAP_HPP__
+
+#include <map>
+
+namespace hyperneat
+{
+ template <class K, class V>
+ using Map = std::map<K, V>;
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/NodeTypes.hpp b/include/HyperNeat/Utils/NodeTypes.hpp
new file mode 100644
index 0000000..815214e
--- /dev/null
+++ b/include/HyperNeat/Utils/NodeTypes.hpp
@@ -0,0 +1,22 @@
+#ifndef __HYPERNEAT_NODETYPES_HPP__
+#define __HYPERNEAT_NODETYPES_HPP__
+
+#include <HyperNeat/Utils/String.hpp>
+
+namespace hyperneat
+{
+ enum class NodeType {
+ NULL_TYPE = -1,
+ SIGMOID = 0,
+ GAUSSIAN = 1,
+ SINE = 2,
+ ABSOLUTE = 3,
+ };
+
+ String nodeToString(NodeType type);
+ NodeType stringToNode(const String& str);
+
+ const size_t NODE_TYPES_COUNT = 4;
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/Pi.hpp b/include/HyperNeat/Utils/Pi.hpp
new file mode 100644
index 0000000..00a3df2
--- /dev/null
+++ b/include/HyperNeat/Utils/Pi.hpp
@@ -0,0 +1,9 @@
+#ifndef __HYPERNEAT_PI_HPP__
+#define __HYPERNEAT_PI_HPP__
+
+namespace hyperneat
+{
+ const double PI = 3.14159265359;
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/Point.hpp b/include/HyperNeat/Utils/Point.hpp
new file mode 100644
index 0000000..ba51bac
--- /dev/null
+++ b/include/HyperNeat/Utils/Point.hpp
@@ -0,0 +1,21 @@
+#ifndef __HYPERNEAT_POINT_HPP__
+#define __HYPERNEAT_POINT_HPP__
+
+namespace hyperneat
+{
+ class Point
+ {
+ public:
+ Point() = default;
+ Point(double x, double y);
+
+ double distance(const Point& other) const;
+ bool operator== (const Point& other) const;
+ bool operator< (const Point& other) const;
+
+ double _x = 0.0;
+ double _y = 0.0;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/Pointer.hpp b/include/HyperNeat/Utils/Pointer.hpp
new file mode 100644
index 0000000..f02e853
--- /dev/null
+++ b/include/HyperNeat/Utils/Pointer.hpp
@@ -0,0 +1,12 @@
+#ifndef __HYPERNEAT_POINTER_HPP__
+#define __HYPERNEAT_POINTER_HPP__
+
+#include <memory>
+
+namespace hyperneat
+{
+ template <class T>
+ using Pointer = std::unique_ptr<T>;
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/Random.hpp b/include/HyperNeat/Utils/Random.hpp
new file mode 100644
index 0000000..4a4d979
--- /dev/null
+++ b/include/HyperNeat/Utils/Random.hpp
@@ -0,0 +1,14 @@
+#ifndef __HYPERNEAT_RANDOM_HPP__
+#define __HYPERNEAT_RANDOM_HPP__
+
+#include <random>
+
+namespace hyperneat
+{
+ using RandGen = std::mt19937_64;
+ using IntDist = std::uniform_int_distribution<size_t>;
+ using RealDist = std::uniform_real_distribution<double>;
+ using BellDist = std::normal_distribution<double>;
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/SaveFile.hpp b/include/HyperNeat/Utils/SaveFile.hpp
new file mode 100644
index 0000000..18cad38
--- /dev/null
+++ b/include/HyperNeat/Utils/SaveFile.hpp
@@ -0,0 +1,45 @@
+#ifndef __HYPERNEAT_SAVEFILE_HPP__
+#define __HYPERNEAT_SAVEFILE_HPP__
+
+#include <iostream>
+#include <HyperNeat/Utils/String.hpp>
+#include <HyperNeat/Utils/Vector.hpp>
+
+namespace hyperneat
+{
+ using Ostream = std::ostream;
+
+ class Genome;
+ class Organism;
+ class Population;
+ class NoveltyMetric;
+ class NeuralNetPrms;
+ class PopulationPrms;
+ class NoveltyMetricPrms;
+
+ class SaveFile
+ {
+ public:
+ SaveFile(Ostream& stream);
+
+ void savePopulation(Population& population, bool shuttedDown = false, size_t tabs = 0,
+ const String& prefix = "");
+ void savePopulationPrms(const PopulationPrms& prms, size_t tabs = 0, const String& prefix = "");
+ void saveNeuralNetPrms(const NeuralNetPrms& prms, size_t tabs = 0, const String& prefix = "");
+ void saveOrganism(const Organism& organism, bool shuttedDown = false, size_t tabs = 0,
+ const String& prefix = "");
+ void saveGenome(const Genome& genome, size_t tabs = 0, const String& prefix = "");
+ void saveNoveltyMetric(const NoveltyMetric& noveltyMetric, bool shuttedDown = false, size_t tabs = 0,
+ const String& prefix = "");
+ void saveNoveltyMetricPrms(const NoveltyMetricPrms& noveltyMetricPrms, size_t tabs = 0,
+ const String& prefix = "");
+
+ private:
+ Ostream& print(size_t tabs = 0);
+ String newl(size_t lines = 1);
+
+ Ostream& _stream;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/Set.hpp b/include/HyperNeat/Utils/Set.hpp
new file mode 100644
index 0000000..d403e6b
--- /dev/null
+++ b/include/HyperNeat/Utils/Set.hpp
@@ -0,0 +1,12 @@
+#ifndef __HYPERNEAT_SET_HPP__
+#define __HYPERNEAT_SET_HPP__
+
+#include <set>
+
+namespace hyperneat
+{
+ template <class V>
+ using Set = std::set<V>;
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/Size.hpp b/include/HyperNeat/Utils/Size.hpp
new file mode 100644
index 0000000..0ef5616
--- /dev/null
+++ b/include/HyperNeat/Utils/Size.hpp
@@ -0,0 +1,12 @@
+#ifndef __HYPERNEAT_SIZE_HPP__
+#define __HYPERNEAT_SIZE_HPP__
+
+#include <cstddef>
+#include <climits>
+
+namespace hyperneat
+{
+ using std::size_t;
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/String.hpp b/include/HyperNeat/Utils/String.hpp
new file mode 100644
index 0000000..ab74d45
--- /dev/null
+++ b/include/HyperNeat/Utils/String.hpp
@@ -0,0 +1,11 @@
+#ifndef HYPERNEAT_STRING_HPP
+#define HYPERNEAT_STRING_HPP
+
+#include <string>
+
+namespace hyperneat
+{
+ using String = std::string;
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/Thread.hpp b/include/HyperNeat/Utils/Thread.hpp
new file mode 100644
index 0000000..4b861e3
--- /dev/null
+++ b/include/HyperNeat/Utils/Thread.hpp
@@ -0,0 +1,11 @@
+#ifndef __HYPERNEAT_THREAD_HPP__
+#define __HYPERNEAT_THREAD_HPP__
+
+#include <thread>
+
+namespace hyperneat
+{
+ using Thread = std::thread;
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/ValueMap.hpp b/include/HyperNeat/Utils/ValueMap.hpp
new file mode 100644
index 0000000..c2910b5
--- /dev/null
+++ b/include/HyperNeat/Utils/ValueMap.hpp
@@ -0,0 +1,12 @@
+#ifndef __HYPERNEAT_VALUEMAP_HPP__
+#define __HYPERNEAT_VALUEMAP_HPP__
+
+#include <HyperNeat/Utils/Vector.hpp>
+#include <HyperNeat/Utils/ValuePoint.hpp>
+
+namespace hyperneat
+{
+ using ValueMap = Vector<ValuePoint>;
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/ValuePoint.hpp b/include/HyperNeat/Utils/ValuePoint.hpp
new file mode 100644
index 0000000..b9e15ab
--- /dev/null
+++ b/include/HyperNeat/Utils/ValuePoint.hpp
@@ -0,0 +1,19 @@
+#ifndef __HYPERNEAT_VALUEPOINT_HPP__
+#define __HYPERNEAT_VALUEPOINT_HPP__
+
+#include <HyperNeat/Utils/Point.hpp>
+
+namespace hyperneat
+{
+ class ValuePoint : public Point
+ {
+ public:
+ ValuePoint() = default;
+ ValuePoint(double x, double y, double value, double segment);
+
+ double _value = 0.0;
+ double _segment = 0.0;
+ };
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/Vector.hpp b/include/HyperNeat/Utils/Vector.hpp
new file mode 100644
index 0000000..f7352e4
--- /dev/null
+++ b/include/HyperNeat/Utils/Vector.hpp
@@ -0,0 +1,12 @@
+#ifndef __HYPERNEAT_VECTOR_HPP__
+#define __HYPERNEAT_VECTOR_HPP__
+
+#include <vector>
+
+namespace hyperneat
+{
+ template <class V>
+ using Vector = std::vector<V>;
+}
+
+#endif
diff --git a/include/HyperNeat/Utils/Vector2D.hpp b/include/HyperNeat/Utils/Vector2D.hpp
new file mode 100644
index 0000000..257dbe6
--- /dev/null
+++ b/include/HyperNeat/Utils/Vector2D.hpp
@@ -0,0 +1,12 @@
+#ifndef __HYPERNEAT_VECTOR2D_HPP__
+#define __HYPERNEAT_VECTOR2D_HPP__
+
+#include <Hyperneat/Utils/Vector.hpp>
+
+namespace hyperneat
+{
+ template <class V>
+ using Vector2D = Vector<Vector<V>>;
+}
+
+#endif