예제 #1
0
        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);
        }
예제 #2
0
        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();
            }
        }
예제 #3
0
 public Individual(DNA team1, DNA team2, PlayoutResult result)
 {
     Team1  = team1;
     Team2  = team2;
     Result = result;
 }