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