예제 #1
0
        private NeatGenome <T> CreateGenomeInner(NeatGenome <T> parent1, NeatGenome <T> parent2)
        {
            // Randomly select one parent as being the primary parent.
            if (_rng.NextBool())
            {
                VariableUtils.Swap(ref parent1, ref parent2);
            }

            // Enumerate over the connection genes in both parents.
            foreach (var geneIndexPair in EnumerateParentGenes(parent1.ConnectionGenes, parent2.ConnectionGenes))
            {
                // Create a connection gene based on the current position in both parents.
                ConnectionGene <T>?connGene = CreateConnectionGene(
                    parent1.ConnectionGenes, parent2.ConnectionGenes,
                    geneIndexPair.Item1, geneIndexPair.Item2,
                    out bool isSecondaryGene);

                if (connGene.HasValue)
                {
                    // Attempt to add the gene to the child genome we are building.
                    _builder.TryAddGene(connGene.Value, isSecondaryGene);
                }
            }

            // Convert the genes to the structure required by NeatGenome.
            var connGenes = _builder.ToConnectionGenes();

            // Create and return a new genome.
            return(_genomeBuilder.Create(
                       _genomeIdSeq.Next(),
                       _generationSeq.Peek,
                       connGenes));
        }
예제 #2
0
        /// <summary>
        /// Initialise an array with 'naturally' random integers.
        /// The array will contain sub-spans of sorted integers, in both ascending and descending order.
        /// </summary>
        /// <param name="arr">The array to initialise.</param>
        /// <param name="rng">Random number generator.</param>
        public static void InitNatural(int[] arr, IRandomSource rng)
        {
            // Init with an incrementing sequence.
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = i;
            }

            // Reverse multiple random sub-ranges.
            int reverseCount = (int)(Math.Sqrt(arr.Length) * 2.0);
            int len          = arr.Length;

            for (int i = 0; i < reverseCount; i++)
            {
                int idx  = rng.Next(arr.Length);
                int idx2 = rng.Next(arr.Length);

                if (idx > idx2)
                {
                    VariableUtils.Swap(ref idx, ref idx2);
                }

                if (i % 2 == 0)
                {
                    Array.Reverse(arr, 0, idx + 1);
                    Array.Reverse(arr, idx2, len - idx2);
                }
                else
                {
                    Array.Reverse(arr, idx, idx2 - idx);
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Initialise a span with 'naturally' ordered random integers.
        /// The initialised span will contain sub-spans of sorted integers, in both ascending and descending order.
        /// </summary>
        /// <param name="keys">The span to initialise.</param>
        /// <param name="rng">Random number generator.</param>
        public static void InitNatural(Span <int> keys, IRandomSource rng)
        {
            // Init with an incrementing sequence.
            for (int i = 0; i < keys.Length; i++)
            {
                keys[i] = i;
            }

            // Reverse multiple random sub-ranges.
            int reverseCount = (int)(Math.Sqrt(keys.Length) * 2.0);
            int len          = keys.Length;

            for (int i = 0; i < reverseCount; i++)
            {
                int idx  = rng.Next(keys.Length);
                int idx2 = rng.Next(keys.Length);

                if (idx > idx2)
                {
                    VariableUtils.Swap(ref idx, ref idx2);
                }

                if (rng.NextBool())
                {
                    keys[0..idx].Reverse();
예제 #4
0
        public void IterationSetup_NaturallyOrderedKeys()
        {
            // Init with an incrementing sequence.
            for (int i = 0; i < _keys.Length; i++)
            {
                _keys[i] = i;
            }

            // Reverse multiple random sub-ranges.
            int reverseCount = (int)(Math.Sqrt(_keys.Length) * 2.0);
            int len          = _keys.Length;

            for (int i = 0; i < reverseCount; i++)
            {
                int idx  = _rng.Next(len);
                int idx2 = _rng.Next(len);

                if (idx > idx2)
                {
                    VariableUtils.Swap(ref idx, ref idx2);
                }

                if (_rng.NextBool())
                {
                    Array.Reverse(_keys, 0, idx + 1);
                    Array.Reverse(_keys, idx2, len - idx2);
                }
                else
                {
                    Array.Reverse(_keys, idx, idx2 - idx);
                }
            }

            // Init value arrays (just copy key value into these).
            for (int i = 0; i < _keys.Length; i++)
            {
                _values[i]  = _keys[i];
                _values2[i] = _keys[i];
            }
        }
예제 #5
0
        private void CreateSpeciesOffspringSexual(
            Species <T>[] speciesArr,
            Species <T> species,
            DiscreteDistribution speciesDistUpdated,
            DiscreteDistribution[] genomeDistArr,
            DiscreteDistribution genomeDist,
            int offspringCount,
            List <NeatGenome <T> > offspringList,
            double interspeciesMatingProportion,
            IRandomSource rng)
        {
            // Calc the number of offspring to create via inter-species sexual reproduction.
            int offspringCountSexualInter;

            if (interspeciesMatingProportion == 0.0)
            {
                offspringCountSexualInter = 0;
            }
            else
            {
                offspringCountSexualInter = (int)NumericsUtils.ProbabilisticRound(interspeciesMatingProportion * offspringCount, rng);
            }

            // Calc the number of offspring to create via intra-species sexual reproduction.
            int offspringCountSexualIntra = offspringCount - offspringCountSexualInter;

            // Get genome list for the current species.
            var genomeList = species.GenomeList;

            // Produce the required number of offspring from inter-species sexual reproduction.
            for (int i = 0; i < offspringCountSexualInter; i++)
            {
                // Select/sample parent A from the current species.
                int genomeIdx     = DiscreteDistribution.Sample(rng, genomeDist);
                var parentGenomeA = genomeList[genomeIdx];

                // Select another species to select parent B from.
                int         speciesIdx = DiscreteDistribution.Sample(rng, speciesDistUpdated);
                Species <T> speciesB   = speciesArr[speciesIdx];

                // Select parent B from species B.
                DiscreteDistribution genomeDistB = genomeDistArr[speciesIdx];
                genomeIdx = DiscreteDistribution.Sample(rng, genomeDistB);
                var parentGenomeB = speciesB.GenomeList[genomeIdx];

                // Ensure parentA is the fittest of the two parents.
                if (_fitnessComparer.Compare(parentGenomeA.FitnessInfo, parentGenomeB.FitnessInfo) < 0)
                {
                    VariableUtils.Swap(ref parentGenomeA, ref parentGenomeB);
                }

                // Create a child genome and add it to offspringList.
                var childGenome = _reproductionSexual.CreateGenome(parentGenomeA, parentGenomeB, rng);
                offspringList.Add(childGenome);
            }

            // Produce the required number of offspring from intra-species sexual reproduction.
            for (int i = 0; i < offspringCountSexualIntra; i++)
            {
                // Select/sample parent A from the species.
                int genomeIdx     = DiscreteDistribution.Sample(rng, genomeDist);
                var parentGenomeA = genomeList[genomeIdx];

                // Create a new distribution with parent A removed from the set of possibilities.
                DiscreteDistribution genomeDistUpdated = genomeDist.RemoveOutcome(genomeIdx);

                // Select/sample parent B from the species.
                genomeIdx = DiscreteDistribution.Sample(rng, genomeDistUpdated);
                var parentGenomeB = genomeList[genomeIdx];

                // Create a child genome and add it to offspringList.
                var childGenome = _reproductionSexual.CreateGenome(parentGenomeA, parentGenomeB, rng);
                offspringList.Add(childGenome);
            }
        }