public override IIndividual Mutate(float probability, float sigma, Random r) { var newInd = new AdaptiveCartesianIndividual(this); //Mutate mutation (add a number between (-0.1,0.1) ) //F****d up side effect of not setting the probability to the child but the parent instead. // The children had worse values as sigmas skyroketted, keeping the parents alive even longer // The parents were making they're children worse off so they could keep surviving :/ newInd.MutationProbability = (MutationProbability + (r.NextDouble() - 0.5) / 5).Clamp(0, 1); newInd.AverageCrossOverProbabilty = (AverageCrossOverProbabilty + (r.NextDouble() - 0.5) / 5).Clamp(0, 1); //Mutate sigmas based on Tau for (int i = 0; i < Sigmas.Length; ++i) { if (r.ProbabilityPass((float)newInd.MutationProbability)) { double modFactor = r.GausianNoise(Tau) + 1; newInd.Sigmas[i] = newInd.Sigmas[i] * modFactor; } } //Mutate actual values based on Sigmas for (int i = 0; i < Values.Length; ++i) { if (r.ProbabilityPass((float)newInd.MutationProbability)) { //Here we were using the parent's sigmas... newInd.Values[i] += r.GausianNoise(newInd.Sigmas[i]); } } return(newInd); }
public AdaptiveCartesianIndividual(AdaptiveCartesianIndividual other) : base(other) { Sigmas = other.Sigmas.ToArray(); MutationProbability = 0.6; AverageCrossOverProbabilty = 0.66; }
public static IIndividual CrossOver(List <IIndividual> parents, Random r) { var typedParents = parents.OfType <AdaptiveCartesianIndividual>().ToList(); int newLength = typedParents .PickRandom(r) .Values .Length; float aveCrossOverProb = (float)typedParents.Select(i => i.AverageCrossOverProbabilty).Average(); var newInd = new AdaptiveCartesianIndividual(newLength, r: r, empty: true); bool takeAverage = false; //Go through the values and the sigma for (var ii = 0; ii < newLength; ++ii) { takeAverage = r.ProbabilityPass(aveCrossOverProb); if (takeAverage) { //Take average of parents respective alleles double valueTot = 0.0; double sigmaTot = 0.0; for (var kk = 0; kk < parents.Count; ++kk) { AdaptiveCartesianIndividual par = typedParents[kk]; //TODO: is the absence of value zero? if (ii < par.Values.Length) { valueTot += par.Values[ii]; sigmaTot += par.Sigmas[ii]; } } //TODO: is the absence of value zero? newInd.Values[ii] = valueTot / parents.Count; newInd.Sigmas[ii] = sigmaTot / parents.Count; } else //Take single parent gene randomly { AdaptiveCartesianIndividual par = typedParents[r.Next(0, typedParents.Count)]; //TODO: Is the absence of value zero? newInd.Values[ii] = ii < par.Values.Length ? par.Values[ii] : 0; newInd.Sigmas[ii] = ii < par.Sigmas.Length ? par.Sigmas[ii] : DefaultSigma; } } if (r.ProbabilityPass(aveCrossOverProb)) { newInd.MutationProbability = typedParents.Select(i => i.MutationProbability).Average(); } else { newInd.MutationProbability = typedParents.PickRandom(r).MutationProbability; } if (r.ProbabilityPass(aveCrossOverProb)) { newInd.AverageCrossOverProbabilty = typedParents.Select(i => i.AverageCrossOverProbabilty).Average(); } else { newInd.AverageCrossOverProbabilty = typedParents.PickRandom(r).AverageCrossOverProbabilty; } return(newInd); }