示例#1
0
        /// <inheritdoc/>
        public override void PerformOperation(EncogRandom rnd, IGenome[] parents,
                                              int parentIndex, IGenome[] offspring,
                                              int offspringIndex)
        {
            var target = ObtainGenome(parents, parentIndex, offspring,
                                      offspringIndex);

            if (target.LinksChromosome.Count < MinLink)
            {
                // don't remove from small genomes
                return;
            }

            // determine the target and remove
            var index = RangeRandomizer.RandomInt(0, target
                                                  .LinksChromosome.Count - 1);
            NEATLinkGene targetGene = target.LinksChromosome[index];

            target.LinksChromosome.Remove(targetGene);

            // if this orphaned any nodes, then kill them too!
            if (!IsNeuronNeeded(target, targetGene.FromNeuronId))
            {
                RemoveNeuron(target, targetGene.FromNeuronId);
            }

            if (!IsNeuronNeeded(target, targetGene.ToNeuronId))
            {
                RemoveNeuron(target, targetGene.ToNeuronId);
            }
        }
示例#2
0
        /// <summary>
        /// Choose a random neuron.
        /// </summary>
        /// <param name="includeInput">Should the input neurons be included.</param>
        /// <returns>The random neuron.</returns>
        private NEATNeuronGene ChooseRandomNeuron(bool includeInput)
        {
            int start;

            if (includeInput)
            {
                start = 0;
            }
            else
            {
                start = inputCount + 1;
            }

            int neuronPos = RangeRandomizer.RandomInt(start, Neurons
                                                      .Genes.Count - 1);
            NEATNeuronGene neuronGene = (NEATNeuronGene)neuronsChromosome.Genes[neuronPos];

            return(neuronGene);
        }
示例#3
0
        /// <summary>
        ///     Get the next row from the underlying CSV file.
        /// </summary>
        /// <param name="csv">The underlying CSV file.</param>
        /// <returns>The loaded row.</returns>
        private LoadedRow GetNextRow(ReadCSV csv)
        {
            if (_remaining == 0)
            {
                LoadBuffer(csv);
            }

            while (_remaining > 0)
            {
                int index = RangeRandomizer.RandomInt(0, _bufferSize - 1);
                if (_buffer[index] != null)
                {
                    LoadedRow result = _buffer[index];
                    _buffer[index] = null;
                    _remaining--;
                    return(result);
                }
            }
            return(null);
        }
示例#4
0
        /// <summary>
        /// Choose a random neuron.
        /// </summary>
        /// <param name="target">The target genome. Should the input and bias neurons be
        /// included.</param>
        /// <param name="choosingFrom">True if we are chosing from all neurons, false if we exclude
        /// the input and bias.</param>
        /// <returns>The random neuron.</returns>
        public NEATNeuronGene ChooseRandomNeuron(NEATGenome target,
                                                 bool choosingFrom)
        {
            int start;

            if (choosingFrom)
            {
                start = 0;
            }
            else
            {
                start = target.InputCount + 1;
            }

            // if this network will not "cycle" then output neurons cannot be source
            // neurons
            if (!choosingFrom)
            {
                int ac = ((NEATPopulation)target.Population)
                         .ActivationCycles;
                if (ac == 1)
                {
                    start += target.OutputCount;
                }
            }

            int end = target.NeuronsChromosome.Count - 1;

            // no neurons to pick!
            if (start > end)
            {
                return(null);
            }

            int            neuronPos  = RangeRandomizer.RandomInt(start, end);
            NEATNeuronGene neuronGene = target.NeuronsChromosome[neuronPos];

            return(neuronGene);
        }
示例#5
0
        /// <summary>
        /// Mutate the genome by adding a neuron.
        /// </summary>
        /// <param name="mutationRate">The mutation rate.</param>
        /// <param name="numTrysToFindOldLink">The number of tries to find a link to split.</param>
        public void AddNeuron(double mutationRate, int numTrysToFindOldLink)
        {
            // should we add a neuron?
            if (ThreadSafeRandom.NextDouble() > mutationRate)
            {
                return;
            }

            // the link to split
            NEATLinkGene splitLink = null;

            int sizeThreshold = inputCount + outputCount + 10;

            // if there are not at least
            int upperLimit;

            if (linksChromosome.Genes.Count < sizeThreshold)
            {
                upperLimit = NumGenes - 1 - (int)Math.Sqrt(NumGenes);
            }
            else
            {
                upperLimit = NumGenes - 1;
            }

            while ((numTrysToFindOldLink--) > 0)
            {
                // choose a link, use the square root to prefer the older links
                int          i    = RangeRandomizer.RandomInt(0, upperLimit);
                NEATLinkGene link = (NEATLinkGene)linksChromosome.Genes[i];

                // get the from neuron
                long fromNeuron = link.FromNeuronID;

                if ((link.Enabled) &&
                    (!link.IsRecurrent) &&
                    (((NEATNeuronGene)Neurons.Genes[
                          GetElementPos(fromNeuron)]).NeuronType != NEATNeuronType.Bias))
                {
                    splitLink = link;
                    break;
                }
            }

            if (splitLink == null)
            {
                return;
            }

            splitLink.Enabled = false;

            double originalWeight = splitLink.Weight;

            long from = splitLink.FromNeuronID;
            long to   = splitLink.ToNeuronID;

            NEATNeuronGene fromGene = (NEATNeuronGene)Neurons.Genes[
                GetElementPos(from)];
            NEATNeuronGene toGene = (NEATNeuronGene)Neurons.Genes[
                GetElementPos(to)];

            double newDepth = (fromGene.SplitY + toGene.SplitY) / 2;
            double newWidth = (fromGene.SplitX + toGene.SplitX) / 2;

            // has this innovation already been tried?
            NEATInnovation innovation = ((NEATTraining)GA).Innovations.CheckInnovation(
                from, to, NEATInnovationType.NewNeuron);

            // prevent chaining
            if (innovation != null)
            {
                long neuronID = innovation.NeuronID;

                if (AlreadyHaveThisNeuronID(neuronID))
                {
                    innovation = null;
                }
            }

            if (innovation == null)
            {
                // this innovation has not been tried, create it
                long newNeuronID = ((NEATTraining)GA).Innovations
                                   .CreateNewInnovation(from, to,
                                                        NEATInnovationType.NewNeuron,
                                                        NEATNeuronType.Hidden, newWidth, newDepth);

                neuronsChromosome.Genes.Add(new NEATNeuronGene(NEATNeuronType.Hidden,
                                                               newNeuronID, newDepth, newWidth));

                // add the first link
                long link1ID = ((NEATTraining)GA).Population.AssignInnovationID();

                ((NEATTraining)GA).Innovations.CreateNewInnovation(from, newNeuronID,
                                                                   NEATInnovationType.NewLink);

                NEATLinkGene link1 = new NEATLinkGene(from, newNeuronID,
                                                      true, link1ID, 1.0, false);

                linksChromosome.Genes.Add(link1);

                // add the second link
                long link2ID = ((NEATTraining)GA).Population.AssignInnovationID();

                ((NEATTraining)GA).Innovations.CreateNewInnovation(newNeuronID, to,
                                                                   NEATInnovationType.NewLink);

                NEATLinkGene link2 = new NEATLinkGene(newNeuronID, to, true,
                                                      link2ID, originalWeight, false);

                linksChromosome.Genes.Add(link2);
            }

            else
            {
                // existing innovation
                long newNeuronID = innovation.NeuronID;

                NEATInnovation innovationLink1 = ((NEATTraining)GA).Innovations
                                                 .CheckInnovation(from, newNeuronID,
                                                                  NEATInnovationType.NewLink);
                NEATInnovation innovationLink2 = ((NEATTraining)GA).Innovations
                                                 .CheckInnovation(newNeuronID, to,
                                                                  NEATInnovationType.NewLink);

                if ((innovationLink1 == null) || (innovationLink2 == null))
                {
                    throw new NeuralNetworkError("NEAT Error");
                }

                NEATLinkGene link1 = new NEATLinkGene(from, newNeuronID,
                                                      true, innovationLink1.InnovationID, 1.0, false);
                NEATLinkGene link2 = new NEATLinkGene(newNeuronID, to, true,
                                                      innovationLink2.InnovationID, originalWeight, false);

                linksChromosome.Genes.Add(link1);
                linksChromosome.Genes.Add(link2);

                NEATNeuronGene newNeuron = new NEATNeuronGene(
                    NEATNeuronType.Hidden, newNeuronID, newDepth, newWidth);

                neuronsChromosome.Genes.Add(newNeuron);
            }

            return;
        }
        /// <inheritdoc/>
        public override void PerformOperation(EncogRandom rnd, IGenome[] parents,
                                              int parentIndex, IGenome[] offspring,
                                              int offspringIndex)
        {
            var target = ObtainGenome(parents, parentIndex, offspring,
                                      offspringIndex);
            var countTrysToFindOldLink = Owner.MaxTries;

            var pop = ((NEATPopulation)target.Population);

            // the link to split
            NEATLinkGene splitLink = null;

            int sizeBias = ((NEATGenome)parents[0]).InputCount
                           + ((NEATGenome)parents[0]).OutputCount + 10;

            // if there are not at least
            int upperLimit;

            if (target.LinksChromosome.Count < sizeBias)
            {
                upperLimit = target.NumGenes - 1
                             - (int)Math.Sqrt(target.NumGenes);
            }
            else
            {
                upperLimit = target.NumGenes - 1;
            }

            while ((countTrysToFindOldLink--) > 0)
            {
                // choose a link, use the square root to prefer the older links
                int          i    = RangeRandomizer.RandomInt(0, upperLimit);
                NEATLinkGene link = target.LinksChromosome[i];

                // get the from neuron
                long fromNeuron = link.FromNeuronId;

                if ((link.Enabled) &&
                    (target.NeuronsChromosome
                     [GetElementPos(target, fromNeuron)]
                     .NeuronType != NEATNeuronType.Bias))
                {
                    splitLink = link;
                    break;
                }
            }

            if (splitLink == null)
            {
                return;
            }

            splitLink.Enabled = false;

            long from = splitLink.FromNeuronId;
            long to   = splitLink.ToNeuronId;

            NEATInnovation innovation = ((NEATPopulation)Owner.Population).Innovations
                                        .FindInnovationSplit(from, to);

            // add the splitting neuron
            IActivationFunction af = ((NEATPopulation)Owner.Population).ActivationFunctions.Pick(new Random());

            target.NeuronsChromosome.Add(
                new NEATNeuronGene(NEATNeuronType.Hidden, af, innovation
                                   .NeuronId, innovation.InnovationId));

            // add the other two sides of the link
            CreateLink(target, from, innovation.NeuronId,
                       splitLink.Weight);
            CreateLink(target, innovation.NeuronId, to, pop.WeightRange);

            target.SortGenes();
        }