//Subscribed to PlotStart, which is queued in UIReflect after UI updates (which is queued StartEvolve) private void EvolvePopulation(object sender, EventArgs e) { TimeLogger.LogStart(); float averageFitness = 0.0f; List <Bed> evolvedBeds = new List <Bed>(); //Actual Evolve process for (int g = 0; g < givenIterations; g++) { //New beds get inited from rand conditions for the first gen //Should ideally ahve already been done from Start -> ResetPopulation, just a safety measure if (!initialised) { newBeds = CreateBeds(); } //The previous List gets emptied. This data is now stored in newBeds after the last generation if (initialised) { } /*for (int i = 0; i < beds.Count; i++) * { * beds[i].ComputeFitness(); * }*/ if (evolvedBeds == null) { //Debug.Log("Evolved null"); } if (newBeds == null) { //Debug.Log("new beds null"); } //Use the GA to evolve our data evolvedBeds = GeneticEvolution.Evolve(newBeds, newBeds.Count, testbench.GetUsedMatingPoolSelector(), testbench.GetUsedBreedingPairSelector(), testbench.GetUsedCrossoverOperator(), testbench.GetUsedMutator()); for (int i = 0; i < evolvedBeds.Count; i++) { evolvedBeds[i].LoadGardenAndPatches(this, patches); } generationNumber++; //Debug.Log("Unsorted List " + beds[0].Fitness); Bed[] bedArray = evolvedBeds.ToArray(); TimSort <Bed> .sort(bedArray, new GeneticEntityComparable()); /* for (int i = 0; i < bedArray.Length; i++) * { * Debug.Log("Sorted post-gen i: " + i + " Fitness: " + bedArray[i].Fitness); * }*/ //Debug.Log("Top of Array: " + bedArray[0].Fitness); evolvedBeds = new List <Bed>(bedArray); //Trimming the solutions //Debug.Log("Evolved Beds pre-trim - size: " + evolvedBeds.Count); //Certain Pair Selectors create larger numbers of solutions than the intial set of parents. //In this case, we require as many solutions (beds) as we put in and therefore remove the excess //after they've been fitness sorted if (evolvedBeds.Count > numberOfBeds) { evolvedBeds.RemoveRange(numberOfBeds - 1, (evolvedBeds.Count - numberOfBeds)); } //Debug.Log("Evolved Beds post-trim - size: " + evolvedBeds.Count); averageFitness = 0.0f; for (int i = 0; i < evolvedBeds.Count; i++) { averageFitness += evolvedBeds[i].Fitness; // Debug.Log("Beds [" + i + "]:" + beds[i].Fitness); } averageFitness /= evolvedBeds.Count; //Clear out the starting beds newBeds.Clear(); //Save the evolved beds into a new starting List to be used for the next generation for (int i = 0; i < evolvedBeds.Count; i++) { newBeds.Add(evolvedBeds[i]); } //Clear out the evolved one evolvedBeds.Clear(); //Debug.Log("End of gen loop - eb size: " + evolvedBeds.Count + " | nb: " + newBeds.Count); } TimeLogger.LogEnd(); EventQueue.QueueEvent(EventQueue.EventType.Plot_End, this, new TimeArgs(Time.realtimeSinceStartup)); //We use newBeds not evolvedBeds here since at the end of the gen, new holds the next (or last) generation's data //and evolved is already cleared for the next gen EventQueue.QueueEvent(EventQueue.EventType.BroadcastGeneration, this, new GenerationArgs <Bed>(newBeds, newBeds[0].Fitness, averageFitness, generationNumber, testingBase)); }