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)); }
/// <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); } } }
/// <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();
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]; } }
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); } }