Example #1
0
        public NeatBrainGenotype(NeatBrainGenotype other)
        {
            // Node name map does not need copying as it should remain the same between different genomes
            this.NodeNameMap = other.NodeNameMap;


            // The genome lists do need to be copied as we can end up doing mutable operations to them
            this.ConnectionGenes = other.ConnectionGenes.ConvertAll(connectionGene => (ConnectionGene)connectionGene.Clone());
            this.NodeGenes       = other.NodeGenes.ConvertAll(nodeGene => (NodeGene)nodeGene.Clone());
        }
Example #2
0
        /// <summary>
        /// Compare the connection genes of this genotype to those of another.
        ///
        /// </summary>
        /// <param name="other"></param>
        /// <returns>(Disjoint, excess, average weight difference)</returns>
        public (int, int, double) CompareConnectionGenes(NeatBrainGenotype other)
        {
            // Calculate number of similar genes

            int thisGenesCount  = this.ConnectionGenes.Count;
            int otherGenesCount = other.ConnectionGenes.Count;

            int thisIndex  = 0;
            int otherIndex = 0;

            int totalDisjointGenes = 0;

            double totalWeightDiff        = 0;
            int    totalSharedConnections = 0;

            while (thisIndex < thisGenesCount && otherIndex < otherGenesCount)
            {
                ConnectionGene thisGene  = this.ConnectionGenes[thisIndex];
                ConnectionGene otherGene = other.ConnectionGenes[otherIndex];

                if (thisGene.InnovationId == otherGene.InnovationId)
                {
                    // genes match, progress both pointers
                    thisIndex              += 1;
                    otherIndex             += 1;
                    totalWeightDiff        += Math.Abs(thisGene.Weight - otherGene.Weight);
                    totalSharedConnections += 1;
                    continue;
                }
                else if (thisGene.InnovationId > otherGene.InnovationId)
                {
                    // If the thisGene (top genome) has a larger innovation number
                    // Progress otherIndex counter
                    otherIndex         += 1;
                    totalDisjointGenes += 1;
                    continue;
                }
                // This will always happen, because otherGene.InnovationId must be larger if it is not equal or smaller to thisGene.InnovationId
                else
                {
                    // thisGene.innov_id < otherGene.innov_id
                    // If the otherGene (bottom genome) has a larger innovation number
                    // progress thisGene counter
                    thisIndex          += 1;
                    totalDisjointGenes += 1;
                    continue;
                }
            }

            // Once we've got here we know some of the genes don't match so lets count them
            int totalExcessGenes = (thisGenesCount - (thisIndex + 1)) + (otherGenesCount - (otherIndex + 1));

            // Max(1,...) to avoid divide by 0
            return(totalDisjointGenes, totalExcessGenes, totalWeightDiff / Math.Max(1, totalSharedConnections));
        }