private Genome ApplyMutation(Genome genome) { for (int gene = 0; gene < _numCoins; gene++) { if (rand.NextDouble() < _mutationRate) { int numIndicesToSkip = rand.Next(4) + 1; // Avoids using the same index int startIndex = rand.Next(6); // Make sure neither of the indices we are swapping are spaces for population not being used. while (!_coinsUsed[startIndex]) { startIndex = rand.Next(6); } // complicated check ensures that we are checking inside the array while (!_coinsUsed[(startIndex + numIndicesToSkip) % 6]) { numIndicesToSkip = rand.Next(4) +1; } int amountToSwap = rand.Next(genome[startIndex]); genome[startIndex] -= amountToSwap; genome[(numIndicesToSkip + startIndex) % 6] += amountToSwap; } } return genome; }
public Genome Clone() { Genome aGenome = new Genome(); for (int i = 0; i < 6; i++) aGenome.Set(i, Get(i)); return aGenome; }
private Genome[] RunGA(Genome[] population) { population = OrganizeGeneration(population); Genome[] nextGen = CreateNextGeneration(population); nextGen.CopyTo(population, 0); _genCount++; population = OrganizeGeneration(population); DisplayGeneration(population, _genCount); _solutionFound = SolutionFound(population); return population; }
private bool SolutionFound(Genome[] population) { foreach (Genome genome in population) { if (genome.Fitness(_target) == 0) return true; } return false; }
private Genome[] OrganizeGeneration(Genome[] population) { // Order genes in population by fitness IEnumerable<Genome> orderedPopulation = population.OrderBy(genome => genome.Fitness(_target)); return orderedPopulation.ToArray<Genome>(); }
private Genome PickAFitParent(Genome[] population) { int parentIndex1 = rand.Next(_popSize); int parentIndex2 = rand.Next(_popSize); Genome parent; if (population[parentIndex1].Fitness(_target) < population[parentIndex2].Fitness(_target)) parent = population[parentIndex1]; else parent = population[parentIndex2]; return parent.Clone(); }
private void DisplayGeneration(Genome[] population, int genCount) { textOutput.Clear(); StringBuilder sb = new StringBuilder(100 * _popSize); foreach (Genome genome in population) { int[] current = genome.ToArray(); sb.Append(genome.Fitness(_target).ToString() + "\t0.01: " + GetPaddedValue(current[(int)CoinNames.pennies], 2) + " 0.05: " + GetPaddedValue(current[(int)CoinNames.nickels], 2) + " 0.10: " + GetPaddedValue(current[(int)CoinNames.dimes], 2) + " 0.25: " + GetPaddedValue(current[(int)CoinNames.quarters], 2) + " 0.50: " + GetPaddedValue(current[(int)CoinNames.halfDollars], 2) + " 1.00: " + GetPaddedValue(current[(int)CoinNames.dollars], 2) + " Total: " + GetDollarValue(genome).ToString() + "\r\n"); } textOutput.Text = sb.ToString(); this.Text = "Generation #" + genCount; this.Update(); Thread.Sleep(25); }
private double GetDollarValue(Genome genome) { double dollarValue = 0; dollarValue += + genome.Get((int)CoinNames.pennies) * ((double)CoinValues.pennies / 100) + genome.Get((int)CoinNames.nickels) * ((double)CoinValues.nickels / 100) + genome.Get((int)CoinNames.dimes) * ((double)CoinValues.dimes / 100) + genome.Get((int)CoinNames.quarters) * ((double)CoinValues.quarters / 100) + genome.Get((int)CoinNames.halfDollars) * ((double)CoinValues.halfDollars / 100) + genome.Get((int)CoinNames.dollars) * ((double)CoinValues.dollars / 100); return dollarValue; }
private Genome[] CreateNextGeneration(Genome[] population) { Genome[] nextGen = new Genome[_popSize]; int numGenesToKeep = (int)(_popSize * _elitism); //for (int i = 0; i < numGenesToKeep; i++) //{ // nextGen[i] = population[i].ToArray(); //} //nextGen = population.ToArray(); population.ToArray().CopyTo(nextGen, 0); for (int i = numGenesToKeep; i < _popSize; i++) { Genome copyOfParent = PickAFitParent(population); Genome child = ApplyMutation(copyOfParent); nextGen[i] = child; } return OrganizeGeneration(nextGen); }
private Genome[] CreateRandomPopulation(int _popSize, bool[] _coinsUsed) { Genome[] population = new Genome[_popSize]; for (int i = 0; i < _popSize; i++) population[i] = new Genome(); int numCoinsRemaining = _numCoins; // Get random values which add up to _numCoins for (int genome = 0; genome < _popSize; genome++) { for (int coin = 0; coin < 5; coin++) { if (_coinsUsed[coin]) { population[genome].Set(coin, rand.Next(numCoinsRemaining)); numCoinsRemaining -= population[genome].Get(coin); } } population[genome].Set(5, numCoinsRemaining); numCoinsRemaining = _numCoins; } // Further randomize by changing order of values randomly foreach (Genome genome in population) { genome.Randomize(); for (int i = 0; i < 6; i++) { if (!_coinsUsed[i]) { if (genome.Get(i) != 0) { int indexToSwapWith = genome.Find(0); genome.Swap(i, indexToSwapWith); } } } } return population; }
public static void BoundaryMutation(ref Genome gene, int index, Random rand) { gene.Genes[index] = rand.Next(0, 2) > 0 ? Functions.MaxValue : Functions.MinValue; }
public static void SimpleMutation(ref Genome gene, int index, Random rand) { gene.Genes[index] = Functions.NewParamValue(rand); }
public static void WholeArithmeticRecombination(Genome firstParent, Genome secondParent, ref Genome firstChild, Random rand) { firstChild.Fitness = Single.MaxValue; for (int i = 0; i < firstParent.Genes.Length; i++) { firstChild.Genes[i] = Average(firstParent.Genes[i], secondParent.Genes[i]); } }
public static void SingleArithmeticRecombination(Genome firstParent, Genome secondParent, ref Genome firstChild, Random rand) { int location = rand.Next(0, firstChild.Genes.Length); firstChild.Copy(firstParent); firstChild.Fitness = Single.MaxValue; firstChild.Genes[location] = Average(firstParent.Genes[location], secondParent.Genes[location]); }
public static void DiscreteRecombination(Genome firstParent, Genome secondParent, ref Genome firstChild, Random rand) { firstChild.Fitness = Single.MaxValue; for (int i = 0; i < firstChild.Genes.Length; i++) { firstChild.Genes[i] = rand.NextDouble() > 0.5 ? firstParent.Genes[i] : secondParent.Genes[i]; } }