private static void Mutate(List <string> genes, IReadOnlyList <string> numbers, IReadOnlyList <string> operations, int minNumbers, int maxNumbers, FnFitnessDelegate fnGetFitness) { var count = Rand.Random.Next(1, 10); var initialFitness = fnGetFitness(genes); while (count > 0) { count--; if (fnGetFitness(genes) > initialFitness) { return; } var numberCount = (1 + genes.Count) / 2; var adding = numberCount < maxNumbers && Rand.PercentChance(1); if (adding) { genes.Add(Rand.SelectItem(operations)); genes.Add(Rand.SelectItem(numbers)); continue; } var removing = numberCount > minNumbers && Rand.PercentChance(5); if (removing) { var index = Rand.Random.Next(0, genes.Count - 1); genes.RemoveAt(index); genes.RemoveAt(index); continue; } var index2 = Rand.Random.Next(0, genes.Count); genes[index2] = (index2 & 1) == 1 ? Rand.SelectItem(operations) : Rand.SelectItem(numbers); } }
private static int GetFitness(IReadOnlyList <string> genes, int expectedTotal, FnFitnessDelegate fnEvaluate) { try { var result = fnEvaluate(genes); var fitness = result != expectedTotal ? expectedTotal - Math.Abs(result - expectedTotal) : 1000 - genes.Count; return(fitness); } catch (OverflowException) { return(1000); } }