public NeatNeuralNetwork(NeuralActivationFunction[] _neuralActivationFunctions, int _inputSize, int _outputSize, double _learnRate = -1, double _momentum = -1)
 {
     genome = new NeuralGenome();
     neuralActivationFunctions = _neuralActivationFunctions;
     genome.learnRate          = _learnRate == -1 ? .1 : _learnRate;
     genome.momentum           = _momentum == -1 ? .4 : _momentum;
     genome.InputLayer         = new List <NeuralGeneNode>();
     genome.HiddenLayers       = new List <NeuralGeneNode>();
     genome.OutputLayer        = new List <NeuralGeneNode>();
     genome.nodes       = new List <NeuralGeneNode>();
     genome.connections = new List <NeuralGeneConnection>();
     genome.InitNewGenome(_inputSize, _outputSize, 0, _neuralActivationFunctions);
 }
 public NeatNeuralNetwork(NeuralActivationFunction[] _neuralActivationFunctions, int _inputSize, int _outputSize, int _globalInnovation, bool _firstGenome,
                          Func <int, float> fitnessFunction, float[] _mutationRates, Func <int, int> _increaseGlobalInnovation, double _learnRate = -1, double _momentum = -1)
 {
     genome = new NeuralGenome();
     neuralActivationFunctions = _neuralActivationFunctions;
     genome.learnRate          = _learnRate == -1 ? .1 : _learnRate;
     genome.momentum           = _momentum == -1 ? .4 : _momentum;
     genome.random             = Random;
     genome.InputLayer         = new List <NeuralGeneNode>();
     genome.HiddenLayers       = new List <NeuralGeneNode>();
     genome.OutputLayer        = new List <NeuralGeneNode>();
     genome.nodes           = new List <NeuralGeneNode>();
     genome.connections     = new List <NeuralGeneConnection>();
     genome.mutationRates   = _mutationRates;
     genome.fitnessFunction = fitnessFunction;
     genome.InitNewGenome(_inputSize, _outputSize, _globalInnovation, _neuralActivationFunctions, _increaseGlobalInnovation, _firstGenome);
 }
    public NeatNeuralNetwork Crossover(NeatNeuralNetwork otherParent)
    {
        NeuralGenome childGenome = new NeuralGenome();

        childGenome.learnRate       = genome.learnRate;
        childGenome.momentum        = genome.momentum;
        childGenome.random          = Random;
        childGenome.InputLayer      = new List <NeuralGeneNode>();
        childGenome.HiddenLayers    = new List <NeuralGeneNode>();
        childGenome.OutputLayer     = new List <NeuralGeneNode>();
        childGenome.nodes           = new List <NeuralGeneNode>();
        childGenome.connections     = new List <NeuralGeneConnection>();
        childGenome.mutationRates   = genome.mutationRates;
        childGenome.fitnessFunction = genome.fitnessFunction;
        childGenome.InitNewGenome(genome.currInnovation, neuralActivationFunctions, genome.IncreaseGlobalInnovation, false);
        // no best parent
        int    bestGenome     = 0;
        bool   takeNotOptimum = false;
        double randRate       = Random.NextDouble();

        if (randRate < 0.01f)
        {
            takeNotOptimum = true;
        }
        // find parent with best fitness
        if (otherParent.genome.fitness > genome.fitness)
        {
            // best parent is other parent
            bestGenome = 1;
        }
        else if (otherParent.genome.fitness < genome.fitness)
        {
            // best parent is thisparent
            bestGenome = 2;
        }
        int index = 0;

        if (this.genome.connections.Count > otherParent.genome.connections.Count)
        {
            foreach (var thisParentConnection in this.genome.connections)
            {
                //foreach (var otherParentConnection in otherParent.genome.connections)
                //{
                if (index > otherParent.genome.connections.Count - 1)
                {
                    HandleExtraNodes(thisParentConnection, null, childGenome, bestGenome, takeNotOptimum);
                }
                else
                {
                    CrossOverParents(thisParentConnection, otherParent.genome.connections[index], childGenome, bestGenome);
                }
                //}
                index++;
            }
        }
        else
        {
            foreach (var otherParentConnection in otherParent.genome.connections)
            {
                //foreach (var thisParentConnection in this.genome.connections)
                //{
                if (index > this.genome.connections.Count - 1)
                {
                    HandleExtraNodes(null, otherParentConnection, childGenome, bestGenome, takeNotOptimum);
                }
                else
                {
                    CrossOverParents(this.genome.connections[index], otherParentConnection, childGenome, bestGenome);
                }
                //}
                index++;
            }
        }

        NeatNeuralNetwork child = new NeatNeuralNetwork(childGenome);

        return(child);
    }