/** * Calculates the maximum available fitness by multiplying the amount of block pairs with the amount of reward points. */ int GetMaxFitness(ConnectedBlocksGraph connectedBlocks, GeneticOptions geneticOptions) { int maxFitness = 0; foreach (var a in connectedBlocks.Blocks) { foreach (var i in a) { maxFitness++; } } return(maxFitness * geneticOptions.PositiveFitnessPoints); }
/** * Creates a new population by recombining the parents to create children. Selects the parents to stay in the new population with roulette wheel selection. * @see ParentRecombination() */ Population RefreshPopulation(Population population, ConnectedBlocksGraph connectedBlocks, GeneticOptions geneticOptions, Random random) { RouletteWheelSelection rouletteWheelSelection = new RouletteWheelSelection(); int childrenAmount = (int)(geneticOptions.PopulationSize * geneticOptions.PopulationRefreshing); Individual[] children = new Individual[geneticOptions.PopulationSize]; for (int i = 0; i < childrenAmount; i++) { int[,] parents = ParentSelection(population, random); children[i] = ParentRecombination(new Individual(Util.GetRow(parents, 0)), new Individual(Util.GetRow(parents, 1)), random); children[i].CalculateFitness(connectedBlocks, geneticOptions); } for (int i = 0; i < geneticOptions.PopulationSize - childrenAmount; i++) { children[i + childrenAmount] = population.Individuals[rouletteWheelSelection.Selection(population.GetFitness(), random)]; } return(new Population(children)); }
///A method that calculates the fitness of the individual based on the reward and punishment values. public void CalculateFitness(ConnectedBlocksGraph connectedBlocks, GeneticOptions geneticOptions) { Fitness = 0; for (int j = 0; j < connectedBlocks.Blocks.Count; j++) { for (int k = 0; k < connectedBlocks.Blocks[j].Length; k++) { if (Sequence[j] == (connectedBlocks.Blocks[j][k] - 1)) { Fitness += geneticOptions.NegativeFitnessPoints; } else { Fitness += geneticOptions.PositiveFitnessPoints; } } } }
/** * The method that combines the methods below to actually compute the result of the genetic algorithm. * It initializes the population at first. Then, it calculates the fitness, and checks if the maximum fitness has been reached. * Continues until the max fitness has been reached, by creating a new population with recombination and mutation. */ public void StartGeneticAlgorithmProcess(GeneticOptions geneticOptions, string graphPath, Random random) { int iterations = 0; ConnectedBlocksGraph connectedBlocks = new ConnectedBlocksGraph(graphPath); Population population = InitializePopulation(geneticOptions, connectedBlocks.Blocks.Count, random); foreach (var i in population.Individuals) { i.CalculateFitness(connectedBlocks, geneticOptions); } while (!CanEnd(connectedBlocks, population, geneticOptions)) { Population newPopulation = RefreshPopulation(population, connectedBlocks, geneticOptions, random); newPopulation = ApplyMutation(newPopulation, random, geneticOptions, connectedBlocks); population = newPopulation; iterations++; } int maxFitness = GetMaxFitness(connectedBlocks, geneticOptions); ResultPrinting(iterations, population, maxFitness); }
/** * Applies mutation to the whole population based on the mutation chance. * @return Returns a population object with the mutated individuals. */ Population ApplyMutation(Population population, Random random, GeneticOptions geneticOptions, ConnectedBlocksGraph connectedBlocks) { for (int i = 0; i < population.Individuals.Length; i++) { if (random.NextDouble() < geneticOptions.MutationChance) { population.Individuals[i].Mutate(random, geneticOptions); population.Individuals[i].CalculateFitness(connectedBlocks, geneticOptions); } } return(population); }
/** * Checks if the maximum fitness value has been reached, by checking if the population has an individual with the maximum amount of fitness. */ bool CanEnd(ConnectedBlocksGraph connectedBlocks, Population population, GeneticOptions geneticOptions) { return(GetMaxFitness(connectedBlocks, geneticOptions) == population.GetFitness().Max()); }