Exemplo n.º 1
0
    private NeatGenome <T> CreateGenomeInner(
        NeatGenome <T> parent1,
        NeatGenome <T> parent2,
        IRandomSource rng)
    {
        // Resolve a flag that determines if *all* disjoint genes from the secondary parent will be included in the child genome, or not.
        // This approach is from SharpNEAT v2.x and is preserved to act as baseline in v4.x, but better strategies may exist.
        bool includeSecondaryParentGene = DiscreteDistribution.SampleBernoulli(rng, _secondaryParentGeneProbability);

        // 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,
                includeSecondaryParentGene, rng);

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

        // Convert the genes to the structure required by NeatGenome.
        ConnectionGenes <T> connGenes = _connGeneListBuilder.ToConnectionGenes();

        // Create and return a new genome.
        return(_genomeBuilder.Create(
                   _genomeIdSeq.Next(),
                   _generationSeq.Peek,
                   connGenes));
    }
Exemplo n.º 2
0
        private ConnectionGene <T>?CreateConnectionGene(
            ConnectionGenes <T> connGenes1,
            ConnectionGenes <T> connGenes2,
            int idx1, int idx2,
            IRandomSource rng)
        {
            // Select gene at random if it is present on both parents.
            if (-1 != idx1 && -1 != idx2)
            {
                if (rng.NextBool())
                {
                    return(CreateConnectionGene(connGenes1, idx1));
                }
                else
                {
                    return(CreateConnectionGene(connGenes2, idx2));
                }
            }

            // Use the primary parent's gene if it has one.
            if (-1 != idx1)
            {
                return(CreateConnectionGene(connGenes1, idx1));
            }

            // Otherwise use the secondary parent's gene stochastically.
            if (DiscreteDistribution.SampleBernoulli(rng, _secondaryParentGeneProbability))
            {
                return(CreateConnectionGene(connGenes2, idx2));
            }

            return(null);
        }