コード例 #1
0
        /// <summary>
        /// Runs a single iteration of ES on a given individual.
        /// </summary>
        public static Individual EvolutionStrategy(GameInstance game, Individual previous, List <Individual> generation,
                                                   bool evolveTeam1)
        {
            float totalFitness = generation.Sum(i => i.CombinedFitness());

            var first = generation[0];

            Vector <float> t1 = first.Team1.Data * (first.CombinedFitness() / totalFitness);
            Vector <float> t2 = first.Team2.Data * (first.CombinedFitness() / totalFitness);

            for (int i = 1; i < generation.Count; i++)
            {
                var ratio = generation[i].CombinedFitness() / totalFitness;
                t1 += generation[i].Team1.Data * ratio;
                t2 += generation[i].Team2.Data * ratio;
            }

            var d1 = first.Team1.Clone();

            d1.Data = t1;
            var d2 = first.Team2.Clone();

            d2.Data = t2;

            if (!evolveTeam1)
            {
                d1.Data = previous.Team1.Data;
            }

            var newFitness = EvolutionBenchmark.CalculateFitness(game, d1, d2);

            return(new Individual(d1, d2, newFitness));
        }
コード例 #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();
            }
        }