private IEntity SelectOne(IEntityList entities, int tournamentSize) { var index = Random.GetInt(0, entities.Count); var best = entities[index]; for (int i = 1; i < tournamentSize; i++) { index = Random.GetInt(0, entities.Count); var next = entities[index]; var comparisonResult = FitnessComparer.Compare(best.Fitness, next.Fitness); if (comparisonResult > 0) { next.Fitness.TournamentWinner++; best.Fitness.TournamentLoser++; best = next; } else { best.Fitness.TournamentWinner++; next.Fitness.TournamentLoser++; } } return(best); }
public override IEntityList Replace(IPopulation targetPopulation, IEntityList offspring, IEntityList parents, IPopulation sourcePopulation) { var inserted = new EntityList(1); var populationSize = Parameters.GetValue(Algorithm.ParameterNames.PopulationSize); //TODO: FitnessComparer.SelectWorst, SelectBest if (offspring.Count == 0) { return(inserted); } var entityToRemove = FitnessComparer.Dominates(parents[0].Fitness, parents[1].Fitness) ? parents[0] : parents[1]; var entityToAdd = (offspring.Count > 1 && FitnessComparer.Dominates(offspring[0].Fitness, offspring[1].Fitness)) ? offspring[1] : offspring[0]; if (FitnessComparer.Dominates(entityToRemove.Fitness, entityToAdd.Fitness)) { targetPopulation.Add(entityToAdd); inserted.Add(entityToAdd); if (sourcePopulation.Count > populationSize) { sourcePopulation.Remove(entityToRemove); } } return(inserted); }
public void MergeToBests(IEntityList entities) { IEntityList travelers = new EntityList(entities.Count); bool anyMerged = false; for (int e = 0; e < entities.Count; e++) { if (entities[e].Fitness.IsLethal()) { continue; } bool merged = FitnessComparer.MergeToBests(Algorithm.Population.Bests, entities[e]); if (merged) { travelers.Add(entities[e]); var timeString = DateTime.Now.ToString("HH:mm:ss.ffff"); Debug.WriteLine(timeString + " " + entities[e].ToString()); var stat = Algorithm.Population.FitnessStatistics.StatisticVariables[0]; Debug.WriteLine($"{timeString} Mean: {stat.Mean}, Deviation: {stat.Deviation}"); anyMerged = true; } } if (anyMerged && NewEntityMergedToBest != null) { NewEntityMergedToBest(Algorithm.Population.Bests); } if (LaunchTravelers != null && travelers.Count > 0) { LaunchTravelers(travelers, TravelerTypes.Best); } }
/// <summary> /// Sorts the population according to /// </summary> /// <param name="solver"></param> /// <param name="op"></param> public void Sort( Solver <GenomeType, ProblemType, WeightType> solver, IFitnessCalculator <GenomeType, ProblemType, WeightType> op) { // create comparer. FitnessComparer comparer = new FitnessComparer(solver, op); // sort using comparer. _individuals.Sort(comparer); }
private int SelectOne(IEntityList entities, int size) { var index = Random.GetInt(0, entities.Count); var worst = index; for (int i = 1; i < size; i++) { index = Random.GetInt(0, entities.Count); var comparisonResult = FitnessComparer.Compare(entities[worst].Fitness, entities[index].Fitness); if (comparisonResult < 0) { worst = index; } } return(worst); }
private void Start() { // actors ignore each other Physics2D.IgnoreLayerCollision(10, 10, true); ImportPremadeBrain(); // reset scores generation = 0; globalBestScore = 0; globalFastest = 0; globalMostLaps = 0; globalBestBrain = null; population = null; if (play) { Instantiate(player); } else { if (testBrain) { NeuralNetwork testb = JsonUtility.FromJson <NeuralNetwork>(ReadBrain(readFile)); StartCoroutine(AssignBrain(Instantiate(player).GetComponent <PlayerController>(), testb)); } else { fc = new FitnessComparer(); population = new PlayerController[populationCount]; for (int j = 0; j < populationCount; j++) { GameObject p = Instantiate(player); population[j] = p.GetComponent <PlayerController>(); } populationAlive = populationCount; } } }
public override IOperation Apply() { double maxSelPress = MaximumSelectionPressureParameter.ActualValue.Value; double successRatio = SuccessRatioParameter.ActualValue.Value; IScope scope = ExecutionContext.Scope; IScope parents = scope.SubScopes[0]; IScope offspring = scope.SubScopes[1]; int populationSize = parents.SubScopes.Count; // retrieve actual selection pressure and success ratio DoubleValue selectionPressure = SelectionPressureParameter.ActualValue; if (selectionPressure == null) { selectionPressure = new DoubleValue(0); SelectionPressureParameter.ActualValue = selectionPressure; } DoubleValue currentSuccessRatio = CurrentSuccessRatioParameter.ActualValue; if (currentSuccessRatio == null) { currentSuccessRatio = new DoubleValue(0); CurrentSuccessRatioParameter.ActualValue = currentSuccessRatio; } // retrieve next population ItemList <IScope> population = OffspringPopulationParameter.ActualValue; ItemList <IScope> virtual_population = OffspringVirtualPopulationParameter.ActualValue; IntValue successfulOffspring; if (population == null) { population = new ItemList <IScope>(); OffspringPopulationParameter.ActualValue = population; selectionPressure.Value = 0; // initialize selection pressure for this round currentSuccessRatio.Value = 0; // initialize current success ratio for this round successfulOffspring = new IntValue(0); OffspringPopulationWinnersParameter.ActualValue = successfulOffspring; virtual_population = new ItemList <IScope>(); OffspringVirtualPopulationParameter.ActualValue = virtual_population; } else { successfulOffspring = OffspringPopulationWinnersParameter.ActualValue; } int successfulOffspringAdded = 0; // implement the ActualValue fetch here - otherwise the parent scope would also be included, given that there may be 1000 or more parents, this is quite unnecessary string tname = SuccessfulOffspringParameter.TranslatedName; double tmpSelPress = selectionPressure.Value; double tmpSelPressInc = 1.0 / populationSize; for (int i = 0; i < offspring.SubScopes.Count; i++) { // fetch value IVariable tmpVar; if (!offspring.SubScopes[i].Variables.TryGetValue(tname, out tmpVar)) { throw new InvalidOperationException(Name + ": Could not determine if an offspring was successful or not."); } BoolValue tmp = (tmpVar.Value as BoolValue); if (tmp == null) { throw new InvalidOperationException(Name + ": The variable that indicates whether an offspring is successful or not must contain a BoolValue."); } // add to population if (tmp.Value) { IScope currentOffspring = offspring.SubScopes[i]; offspring.SubScopes.RemoveAt(i); i--; // next loop should continue with the subscope at index i which replaced currentOffspring population.Add(currentOffspring); successfulOffspringAdded++; } else { IScope currentOffspring = offspring.SubScopes[i]; offspring.SubScopes.RemoveAt(i); i--; virtual_population.Add(currentOffspring); // add to losers pool } tmpSelPress += tmpSelPressInc; double tmpSuccessRatio = (successfulOffspring.Value + successfulOffspringAdded) / ((double)populationSize); if (tmpSuccessRatio >= successRatio && (population.Count + virtual_population.Count) >= populationSize) { break; } } successfulOffspring.Value += successfulOffspringAdded; // calculate actual selection pressure and success ratio selectionPressure.Value = tmpSelPress; currentSuccessRatio.Value = successfulOffspring.Value / ((double)populationSize); // check if enough children have been generated (or limit of selection pressure or evaluted solutions is reached) if (((EvaluatedSolutionsParameter.ActualValue.Value < MaximumEvaluatedSolutionsParameter.ActualValue.Value) && (selectionPressure.Value < maxSelPress) && (currentSuccessRatio.Value < successRatio)) || ((population.Count + virtual_population.Count) < populationSize)) { // more children required -> reduce left and start children generation again scope.SubScopes.Remove(parents); scope.SubScopes.Remove(offspring); while (parents.SubScopes.Count > 0) { IScope parent = parents.SubScopes[0]; parents.SubScopes.RemoveAt(0); // TODO: repeated call of RemoveAt(0) is inefficient? scope.SubScopes.Add(parent); // order of subscopes is reversed } IOperator offspringCreator = OffspringCreatorParameter.ActualValue as IOperator; if (offspringCreator == null) { throw new InvalidOperationException(Name + ": More offspring are required, but no operator specified for creating them."); } return(ExecutionContext.CreateOperation(offspringCreator)); // this assumes that this operator will be called again indirectly or directly } else { // enough children generated var fitnessComparer = new FitnessComparer(QualityParameter.TranslatedName, MaximizationParameter.ActualValue.Value); population.Sort(fitnessComparer); // sort individuals by descending fitness // keeps only the best successRatio * populationSize solutions in the population (the remaining ones are added to the virtual population) int removed = 0; for (int i = 0; i < population.Count; i++) { double tmpSuccessRatio = i / (double)populationSize; if (tmpSuccessRatio > successRatio) { virtual_population.Add(population[i]); removed++; } } population.RemoveRange(population.Count - removed, removed); //fill up population with best remaining children (successful or unsuccessful) virtual_population.Sort(fitnessComparer); int offspringNeeded = populationSize - population.Count; for (int i = 0; i < offspringNeeded && i < virtual_population.Count; i++) { population.Add(virtual_population[i]); // children are sorted by descending fitness } offspring.SubScopes.Clear(); offspring.SubScopes.AddRange(population); scope.Variables.Remove(OffspringPopulationParameter.TranslatedName); scope.Variables.Remove(OffspringVirtualPopulationParameter.TranslatedName); scope.Variables.Remove(OffspringPopulationWinnersParameter.TranslatedName); return(base.Apply()); } }
static void Main(string[] args) { Maze maze = new Maze(); Random rand = new Random(System.DateTime.Now.Millisecond); List <Robot> robots = new List <Robot>(); int generation = 1; //Create comma delimted output file and open stream to it System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(@"c:\Users\Pehr\Documents\robotDataFile.csv"); streamWriter.WriteLine("Initial Fitness:"); // Create initial population of robots for (int i = 0; i < startingPopulationSize; i++) { robots.Add(new Robot(rand)); robots[i].ProcessRobot(maze); System.Console.Write(robots[i].Fitness); System.Console.Write(" "); //Write intial data to output file streamWriter.WriteLine(robots[i].Fitness); } // Sort our robots by fitness FitnessComparer fitnessComparer = new FitnessComparer(); robots.Sort(fitnessComparer); // While fitness[highest sorted] < 0.9 or maybe 1.0 while (robots[0].Fitness < fitnessThreshold) { // Save our fittest (first) 10 robots for the next generation and kill off the least fit 10 (last) robots List <Robot> fittestRobots = new List <Robot>(); for (int i = 0; i < saveKillCount; i++) { robots.RemoveAt(robots.Count - 1); fittestRobots.Add(new Robot(robots[i].GenoType, robots[i].Fitness)); } // Randomly sort our robot list to create random pairs for crossover robots.Sort(delegate(Robot x, Robot y) { return((x.Fitness == y.Fitness) ? 0 : rand.Next(0, 1)); }); // Iterate through our list pairing robots and performing crossover or mutation for (int i = 0; i < robots.Count; i++) { int crossoverMutationChoser = rand.Next(0, 9); // 70% chance of crossover (and must be at least 2 robots left) if (i < robots.Count - 1 && crossoverMutationChoser < crossoverChance) { Robot parentOne = robots[i]; Robot parentTwo = robots[i + 1]; Robot.Crossover(ref parentOne, ref parentTwo, rand); // ProcessRobot will get a new fitness value robots[i].ProcessRobot(maze); robots[i + 1].ProcessRobot(maze); } else // 30% chance of mutation { robots[i].Mutate(rand); // ProcessRobot will get a new fitness value robots[i].ProcessRobot(maze); } } // Re-add our fittest robots for (int i = 0; i < saveKillCount; i++) { robots.Add(fittestRobots[i]); } generation++; System.Console.Write("New generation: "); // Put our robots in fitness sort order robots.Sort(fitnessComparer); streamWriter.WriteLine(String.Format("Fitness Generation[{0}]:", generation)); String phenoType = new String(robots[0].PhenoType); streamWriter.WriteLine(String.Format("Fittest Phenotype: {0}", phenoType)); // Print out our current fitness data for (int i = 0; i < robots.Count; i++) { System.Console.Write(robots[i].Fitness); System.Console.Write(" "); //Write current fitness data to output file streamWriter.WriteLine(robots[i].Fitness); } } System.Console.Write("Final fitness values: "); streamWriter.WriteLine(String.Format("Final Fitness Generation[{0}]:", generation)); String pheno = new String(robots[0].PhenoType); streamWriter.WriteLine(String.Format("Fittest Phenotype: {0}", pheno)); StreamWriter fitPhenoWriter = new StreamWriter(@"c:\Users\Pehr\Documents\robotSolution.txt"); fitPhenoWriter.Write(pheno); fitPhenoWriter.Close(); for (int i = 0; i < robots.Count; i++) { System.Console.Write(robots[i].Fitness); System.Console.Write(" "); //Write current fitness data to output file streamWriter.WriteLine(robots[i].Fitness); } streamWriter.Close(); // Wait for input so data can be viewed on console System.Console.ReadKey(); }