public CPPNNEATGenome(ICPPNNEATGA parentGA, CPPNNEATGenome <PType> parent, CPPNNEATGenome <PType> partner) : this(parentGA) { var differences = new DifferenceAnalysis(parent.GeneCollection, partner.GeneCollection); var disjointAndExcessSource = differences.FirstCollection; if (partner.Score > parent.Score) { disjointAndExcessSource = differences.SecondCollection; } else if (partner.Score == parent.Score) { disjointAndExcessSource = (MathExtensions.RandomNumber() <= 0.5) ? differences.FirstCollection : differences.SecondCollection; } Func <CPPNNEATLinkGene, CPPNNEATLinkGene, Complex> weightSelector = null; if (MathExtensions.RandomNumber() <= parentGA.MateByAveragingRate) { weightSelector = (first, second) => (first.Weight + second.Weight) / 2; } else { weightSelector = (first, second) => (MathExtensions.RandomNumber() <= 0.5) ? first.Weight : second.Weight; } foreach (var match in differences.Matches) { var geneToCopy = match.FirstCollection; var newGene = geneToCopy.Copy(); newGene.Enabled = true; newGene.Weight = weightSelector(match.FirstCollection, match.SecondCollection); GeneCollection.TryAddLinkGene(newGene); if ((!match.FirstCollection.Enabled || !match.SecondCollection.Enabled) && MathExtensions.RandomNumber() <= parentGA.DisableGeneRate) { GeneCollection.DisableLinkGene(newGene.InnovationNumber); } } foreach (var linkGene in disjointAndExcessSource .Disjoint.Union(disjointAndExcessSource.Excess)) { GeneCollection.TryAddLinkGene(linkGene.Copy()); } }
private static double GetAverageFunctionDifference(CPPNNEATGenome <PType> genome1, CPPNNEATGenome <PType> genome2) { var functionDifferenceMap = genome1.GeneCollection.ActivationFunctions.GroupBy(func => func.Label) .ToDictionary(group => group.Key, group => group.Count()); foreach (var activationFunctionGroup in genome2.GeneCollection.ActivationFunctions.GroupBy(func => func.Label)) { if (!functionDifferenceMap.ContainsKey(activationFunctionGroup.Key)) { functionDifferenceMap[activationFunctionGroup.Key] = 0; } functionDifferenceMap[activationFunctionGroup.Key] = Math.Abs(functionDifferenceMap[activationFunctionGroup.Key] - activationFunctionGroup.Count()); } return(functionDifferenceMap.Average(pair => pair.Value)); }