int zerosSum; // how many inactive genes are in chromozome? #endregion Fields #region Constructors /// <summary> /// Creates new random population and sets parameters of evolution /// </summary> /// <param name="populationSize">Population size</param> /// <param name="probCrossOver">Probability of crossover</param> /// <param name="probMutability">Probability of mutation</param> /// <param name="elitism">How many best ones will survive?</param> /// <param name="shareSigma">Distance, two chromozome with distance below that parameter are similiar</param> /// <param name="shareAlfa">Sharing constant</param> /// <param name="scaleSigma">Scaling constant, best fitnuss would be scaleSigma times greater than average population fitness</param> /// <param name="newBorn">True if extincted ones should be replace by random ones</param> /// <param name="zeros">Which genes arent active in this evolution? (ex. building fort is banned in a scenario)</param> public Genetic(int populationSize, double probCrossOver, double probMutability, int elitism, double shareSigma, double shareAlfa, double scaleSigma, bool newBorn, bool [] zeros) { rnd = new Random(); this.shareSigma = shareSigma; this.shareAlfa = shareAlfa; this.scaleSigma = scaleSigma; this.elitism = elitism; this.probCrossOver = probCrossOver; this.probMutability = probMutability; this.populationSize = populationSize; this.extinction = 0.0; this.newBorn = newBorn; this.zeros = zeros; generationNumber = 0; zerosSum = 0; for (int loop1 = 0; loop1 < zeros.Length; loop1++) if (zeros[loop1]) zerosSum++; population = new Chromozone[populationSize]; // generate random start population for (int loop1 = 0; loop1 < populationSize; loop1++) population[loop1] = new Chromozone(rnd, zeros); theBestOne = population[0]; fitnessBestOne = 0.0; activeChromozomeID = 0; lastFitness = 0.0; // start time of evolving stopwatch = new Stopwatch(); stopwatch.Start(); }
private void NewPopulation() { // create empty list of new population List<Chromozone> newPopulation = new List<Chromozone>(); // sort chromozomes according their fitness Array.Sort(population); Log(); if (generationNumber % 3 == 0) // in each third generation, print all chromozomes in text file PrintAllChromozones(); // replace best one in all populations if (population[0].GetFitness() > fitnessBestOne) { fitnessBestOne = population[0].GetFitness(); theBestOne = population[0]; } // At least the worst one wont produce itself // Adds something to exctinction for (int loop1 = population.Length - 1; loop1 >= population.Length / 3; loop1--) { if (population[loop1].GetFitness() > extinction && population[loop1].GetFitness() != population[population.Length / 3 - 1].GetFitness()) { extinction = population[loop1].GetFitness(); break; } } // apply elitism for (int loop1 = 0; loop1 < elitism; loop1++) { newPopulation.Add(new Chromozone(population[loop1].GetGenes(), zeros)); } // kill all chromozome with fitness less than extinction value KillTheWorsts(extinction); // replace extincted ones by new random ones if (newBorn || population.Length < 2) AddFreshOnes(newPopulation); // linear scaling of fitness ScaleFactor(); // change fitnesses according share value ShareFactor(); // prepare roulete wheel for selectioin double sumFitness = 0.0; double sumProb = 0.0; foreach (Chromozone ch in population) { sumFitness += ch.GetFitness(); } foreach (Chromozone ch in population) { double prob = sumProb + ch.GetFitness() / sumFitness; ch.SetProbability(prob); sumProb += ch.GetFitness() / sumFitness; } // end of preparing roulete wheel int[][][] sons; while (newPopulation.Count < populationSize) { // clone selected mum and dad int[][] dad = Chromozone.CloneArray2D(Selection()); int[][] mum = Chromozone.CloneArray2D(Selection()); sons = CrossOver(dad, mum); for (int loop1 = 0; loop1 < sons.Length; loop1++) { sons[loop1] = Mutation(sons[loop1]); newPopulation.Add(new Chromozone(sons[loop1], zeros)); } } population = newPopulation.ToArray(); // when there are exactly same chromozome in new population, mutate the copyiest until thera arent two same chromozomes DifferPopulation(); }
/// <summary> /// For the last step of evolution new generation. /// If there are 2 exactly same chromozomes, mutate one of them. /// </summary> private void DifferPopulation() { double tempMutability = probMutability; probMutability = 0.1; for (int loop1 = 0; loop1 < population.Length; loop1++) { for (int loop2 = 0; loop2 < population.Length; loop2++) { if (loop1 != loop2 && population[loop1].DistanceTo(population[loop2]) == 0) { population[loop1] = new Chromozone(Mutation(population[loop1].GetGenes()), zeros); loop2 = 0; } } } probMutability = tempMutability; }
private void KillTheWorsts(double trashhold) { int alive = 0; // how many will survive? for (alive = 0; alive < population.Length; alive++) { if (population[alive].GetFitness() < trashhold) { break; } } // copy survived chromozome to new array and replace with it the old one if (alive != population.Length) { Chromozone[] oldPopulation = new Chromozone[alive]; for (int loop1 = 0; loop1 < oldPopulation.Length; loop1++) { oldPopulation[loop1] = population[loop1]; } population = oldPopulation; } }
/// <summary> /// Returns weighted manhatton distance between two chromozomes /// </summary> /// <param name="b">Second chromozome</param> /// <returns>Distance</returns> internal double DistanceTo(Chromozone b) { double chromDistance = 0.0; for (int loop1 = 0; loop1 < genes.Length; loop1++) { for (int loop2 = 0; loop2 < genes[loop1].Length; loop2++) { int genDistance = Math.Abs(genes[loop1][loop2] - b.genes[loop1][loop2]); if (loop2 == 0) { chromDistance += genDistance; } else { chromDistance += 5 * genDistance; } } } return chromDistance; }