public float CombinedFitness() { float fitA = 1 - Result.HpPercentage; float fitB = (float)PlayoutResult.LengthSample(Result.TotalTurns); float fitC = Team1.DistanceFitness(Team2); float fitness = (fitA + fitB + fitC) / 3; if (!Result.AllPlayed) { fitness = 0.0001f; } return(fitness); }
public void RunEvolutionStrategies(DNA initialDna, bool evolveTeam1 = true, int?forcedIndex = null, bool stopWhenGood = false) { if (!_keepCounter) { GoodCount = 0; } var t1 = initialDna; var t2 = t1.Clone(); if (evolveTeam1) { t1.Randomize(); } t2.Randomize(); var map = Map.Load("data/map.json"); Console.WriteLine($"Initial ({t1.Data.Count}): {t1.ToDnaString()}\n\n"); var game = GameSetup.GenerateFromDna(t1, t2, map); int restartCount = 0; var current = new Individual(t1.Clone(), t2.Clone(), EvolutionBenchmark.CalculateFitness(game, t1, t2)); List <double> plotT = new List <double>(); List <double> plotFit = new List <double>(); List <double> plotHpPercentage = new List <double>(); List <double> plotLength = new List <double>(); List <double> plotDistance = new List <double>(); var gameCopies = Enumerable.Range(0, Constants.TeamsPerGeneration) #if PARALLEL .AsParallel() #endif .Select(_ => game.DeepCopy()) .ToList(); int i; for (i = 0; i < Constants.NumGenerations; i++) { var genWatch = new Stopwatch(); genWatch.Start(); var teamWatch = new Stopwatch(); teamWatch.Start(); if (Constants.RestartFailures && current.CombinedFitness() < Constants.FitnessThreshold) { if (evolveTeam1) { current.Team1.Randomize(); } current.Team2.Randomize(); restartCount++; } var generation = Enumerable.Range(0, Constants.TeamsPerGeneration) #if PARALLEL .AsParallel() #endif .Select(j => { var newTeam1 = evolveTeam1 ? EvolutionBenchmark.Mutate(current.Team1) : current.Team1; var newTeam2 = EvolutionBenchmark.Mutate(current.Team2); var newFitness = EvolutionBenchmark.CalculateFitness( gameCopies[j], newTeam1, newTeam2); return(new Individual(newTeam1, newTeam2, newFitness)); }) .ToList(); var previous = current; current = EvolutionStrategy(game, previous, generation, evolveTeam1); plotT.Add(i); plotFit.Add(current.CombinedFitness()); plotHpPercentage.Add(1 - current.Result.HpPercentage); plotLength.Add(PlayoutResult.LengthSample(current.Result.TotalTurns)); plotDistance.Add(current.Team1.DistanceFitness(current.Team2)); if (i % Constants.EvolutionPrintModulo == 0) { Console.WriteLine($"T: {i}\t\t" + $"F: {previous.CombinedFitness().ToString("0.0000")}" + $" -> {current.CombinedFitness().ToString("0.0000")}"); } if (Constants.SaveGoodOnes && current.CombinedFitness() > 0.95) { int index = forcedIndex ?? GoodCount + GoodIndexOffset; EvolutionBenchmark.SaveDna(index, current.Team1, current.Team2); GoodCount++; Console.WriteLine($"Found extra good {current.CombinedFitness()}, restarting"); if (evolveTeam1) { current.Team1.Randomize(); } current.Team2.Randomize(); if (stopWhenGood || GoodCount >= _maxGoodCount) { Console.WriteLine($"Stopping evolution early, reached target {_maxGoodCount} good matches."); break; } } } Console.WriteLine($"Restarts: {restartCount}"); if (Constants.GnuPlot) { GnuPlot.HoldOn(); GnuPlot.Set($"xrange [0:{i}] reverse", $"title '{Constants.NumGenerations} generations", "key tmargin center horizontal"); GnuPlot.Plot(plotT.ToArray(), plotFit.ToArray(), $"title 'Fitness {Constants.NumGenerations}gen'"); GnuPlot.Plot(plotT.ToArray(), plotHpPercentage.ToArray(), $"title 'HP percentage'"); GnuPlot.Plot(plotT.ToArray(), plotLength.ToArray(), "title 'Game length'"); GnuPlot.Plot(plotT.ToArray(), plotDistance.ToArray(), "title 'Team difference'"); Console.ReadKey(); } }
public Individual(DNA team1, DNA team2, PlayoutResult result) { Team1 = team1; Team2 = team2; Result = result; }