/// <summary> /// Runs learning epoch. /// </summary> /// /// <param name="input">Array of input vectors.</param> /// <param name="output">Array of output vectors.</param> /// /// <returns>Returns summary squared learning error for the entire epoch.</returns> /// /// <remarks><para><note>While running the neural network's learning process, it is required to /// pass the same <paramref name="input"/> and <paramref name="output"/> values for each /// epoch. On the very first run of the method it will initialize evolutionary fitness /// function with the given input/output. So, changing input/output in middle of the learning /// process, will break it.</note></para></remarks> /// public double RunEpoch( double[][] input, double[][] output ) { Debug.Assert( input.Length > 0 ); Debug.Assert( output.Length > 0 ); Debug.Assert( input.Length == output.Length ); Debug.Assert( network.InputsCount == input.Length ); // check if it is a first run and create population if so if ( population == null ) { // sample chromosome DoubleArrayChromosome chromosomeExample = new DoubleArrayChromosome( chromosomeGenerator, mutationMultiplierGenerator, mutationAdditionGenerator, numberOfNetworksWeights ); // create population ... population = new Population( populationSize, chromosomeExample, new EvolutionaryFitness( network, input, output ), selectionMethod ); // ... and configure it population.CrossoverRate = crossOverRate; population.MutationRate = mutationRate; population.RandomSelectionPortion = randomSelectionRate; } // run genetic epoch population.RunEpoch( ); // get best chromosome of the population DoubleArrayChromosome chromosome = (DoubleArrayChromosome) population.BestChromosome; double[] chromosomeGenes = chromosome.Value; // put best chromosome's value into neural network's weights int v = 0; for ( int i = 0; i < network.Layers.Length; i++ ) { Layer layer = network.Layers[i]; for ( int j = 0; j < layer.Neurons.Length; j++ ) { ActivationNeuron neuron = layer.Neurons[j] as ActivationNeuron; for ( int k = 0; k < neuron.Weights.Length; k++ ) { neuron.Weights[k] = chromosomeGenes[v++]; } neuron.Threshold = chromosomeGenes[v++]; } } Debug.Assert( v == numberOfNetworksWeights ); return 1.0 / chromosome.Fitness; }
/// <summary> /// Perform migration between two populations. /// </summary> /// /// <param name="anotherPopulation">Population to do migration with.</param> /// <param name="numberOfMigrants">Number of chromosomes from each population to migrate.</param> /// <param name="migrantsSelector">Selection algorithm used to select chromosomes to migrate.</param> /// /// <remarks><para>The method performs migration between two populations - current and the /// <paramref name="anotherPopulation">specified one</paramref>. During migration /// <paramref name="numberOfMigrants">specified number</paramref> of chromosomes is choosen from /// each population using <paramref name="migrantsSelector">specified selection algorithms</paramref> /// and put into another population replacing worst members there.</para></remarks> /// public void Migrate( Population anotherPopulation, int numberOfMigrants, ISelectionMethod migrantsSelector ) { int currentSize = this.size; int anotherSize = anotherPopulation.Size; // create copy of current population List<IChromosome> currentCopy = new List<IChromosome>( ); for ( int i = 0; i < currentSize; i++ ) { currentCopy.Add( population[i].Clone( ) ); } // create copy of another population List<IChromosome> anotherCopy = new List<IChromosome>( ); for ( int i = 0; i < anotherSize; i++ ) { anotherCopy.Add( anotherPopulation.population[i].Clone( ) ); } // apply selection to both populations' copies - select members to migrate migrantsSelector.ApplySelection( currentCopy, numberOfMigrants ); migrantsSelector.ApplySelection( anotherCopy, numberOfMigrants ); // sort original populations, so the best chromosomes are in the beginning population.Sort( ); anotherPopulation.population.Sort( ); // remove worst chromosomes from both populations to free space for new members population.RemoveRange( currentSize - numberOfMigrants, numberOfMigrants ); anotherPopulation.population.RemoveRange( anotherSize - numberOfMigrants, numberOfMigrants ); // put migrants to corresponding populations population.AddRange( anotherCopy ); anotherPopulation.population.AddRange( currentCopy ); // find best chromosomes in each population FindBestChromosome( ); anotherPopulation.FindBestChromosome( ); }