private void applyGenomesInBrains()
 {
     for (int i = 0; i < genomes.Length; i++)
     {
         brains[i] = new NeuroNetwork(neuro_input_nodes, neurons_per_layer, neuro_output_nodes, genomes[i]);
     }
 }
        public void createGeneration()
        {
            if (current_generation == 0)
            {
                // Generate random genomes on first generation
                brains  = new NeuroNetwork[genomes_count];
                genomes = new sbyte[genomes_count][];
                fitness = new double[genomes_count];

                for (int i = 0; i < brains.Length; i++)
                {
                    genomes[i] = new sbyte[NeuroNetwork.calculateGenomeLength(neuro_input_nodes, neurons_per_layer, neuro_output_nodes)];
                    for (int g = 0; g < genomes[i].Length; g++)
                    {
                        genomes[i][g] = (sbyte)random.Next(-128, 127);
                    }
                }
            }
            else
            {
                // Generate new solutions trying to improve them
                improveGeneration();
            }

            applyGenomesInBrains();
            current_generation++;
        }
        private NeuroNetwork[] crossover(NeuroNetwork genome1, NeuroNetwork genome2)
        {
            NeuroNetwork newGenome1 = new NeuroNetwork(neuro_input_nodes, neurons_per_layer, neuro_output_nodes, random),
                         newGenome2 = new NeuroNetwork(neuro_input_nodes, neurons_per_layer, neuro_output_nodes, random);

            object[] genome1_perceptrons = genome1.crossOverSplit(), genome2_perceptrons = genome2.crossOverSplit();

            newGenome1.setPerceptrons((Perceptron[])genome1_perceptrons[0], (Perceptron[])genome2_perceptrons[1]);
            newGenome2.setPerceptrons((Perceptron[])genome2_perceptrons[0], (Perceptron[])genome1_perceptrons[1]);

            return(new NeuroNetwork[] { newGenome1, newGenome2 });
        }
        private void improveGeneration()
        {
            // Selecting better solutions
            Dictionary <NeuroNetwork, double> genomes_dictionary = new Dictionary <NeuroNetwork, double>();

            for (int i = 0; i < genomes_count; i++)
            {
                genomes_dictionary.Add(genomes[i], fitness[i]);
            }
            genomes_dictionary = genomes_dictionary.OrderByDescending(key => key.Value).Take(solution_selection_for_crossover).ToDictionary(pair => pair.Key, pair => pair.Value);

            // Create new genomes array
            NeuroNetwork[] newGenomes = new NeuroNetwork[genomes_count];

            // Keep original 2 better solutions
            newGenomes[0] = genomes_dictionary.Keys.First();
            newGenomes[1] = genomes_dictionary.Keys.Last();

            // Cross-over solutions
            NeuroNetwork[] hybrids = crossover(newGenomes[0], newGenomes[1]);
            for (int i = 0; i < hybrids.Length; i++)
            {
                newGenomes[i + 2] = hybrids[i]; // Add crossed over solutions to new generation
            }

            // Mutated solutions
            for (int i = hybrids.Length + 2; i < newGenomes.Length; i++)
            {
                int          selection = random.Next(0, 4);
                Perceptron[] old_ps    = newGenomes[selection].getPerceptrons();
                Perceptron[] new_ps    = new Perceptron[old_ps.Length];
                for (int o = 0; o < new_ps.Length; o++)
                {
                    new_ps[o] = new Perceptron(old_ps[o].getWeights(), old_ps[o].getBias());
                }

                newGenomes[i] = new NeuroNetwork(neuro_input_nodes, neurons_per_layer, neuro_output_nodes, random, new_ps);
                newGenomes[i].applyMutations(random);
            }

            // Replace old generation with new one
            genomes = newGenomes;
        }
        public void createGeneration()
        {
            if (current_generation == 0)
            {
                // Generate random genomes on first generation
                genomes = new NeuroNetwork[genomes_count];
                fitness = new double[genomes_count];

                for (int i = 0; i < genomes.Length; i++)
                {
                    genomes[i] = new NeuroNetwork(neuro_input_nodes, neurons_per_layer, neuro_output_nodes, random);
                }
            }
            else
            {
                // Generate new solutions trying to improve them
                improveGeneration();
            }

            current_generation++;
        }