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