示例#1
0
        public float CombinedFitness(DNA initialDna)
        {
            float fitA = 1 - result.HpPercentage;
            float fitB = (float)PlayoutResult.LengthSample(result.TotalTurns);

            float fitness = (fitA + fitB) / 2;

            if (!result.AllPlayed)
            {
                fitness = 0.0001f;
            }

            var low  = DenseVector.Build.Dense(dna.Data.Count, 0);
            var high = DenseVector.Build.Dense(dna.Data.Count, 1);

            double maxDistance = Distance.Euclidean(low, high);


            double distance         = Distance.Euclidean(dna.Data, initialDna.Data);
            double relativeDistance = distance / maxDistance;
            double distanceFitness  = 1 / (1 + Math.Exp(-20 * relativeDistance + 4));

            return((fitness + (float)distanceFitness) / 2);
        }
        public void RunSimulatedAnnealing()
        {
            var copy = _initialDna.Clone();

            copy.Randomize();

            var current = new GenerationMember {
                dna    = copy,
                result = CalculateFitness(_game, _initialDna, copy)
            };

            float T = Constants.InitialT;

            List <double> plotT            = new List <double>();
            List <double> plotFit          = new List <double>();
            List <double> plotHpPercentage = new List <double>();
            List <double> plotLength       = new List <double>();

            int  goodCount  = 0;
            bool goodEnough = false;

            var gameCopies = Enumerable.Range(0, Constants.TeamsPerGeneration)
                             .AsParallel()
                             .Select(_ => _game.DeepCopy())
                             .ToList();

            var initialDnaCopies = Enumerable.Range(0, Constants.TeamsPerGeneration)
                                   .Select(_ => _initialDna.Clone())
                                   .ToList();

            for (int i = 0; i < Constants.NumGenerations; i++)
            {
                var tpercentage = Math.Max(0, 1.0f - (float)i / Constants.NumGenerations);

                T = Constants.InitialT * tpercentage;

                var genWatch = new Stopwatch();
                genWatch.Start();

                var teamWatch = new Stopwatch();
                teamWatch.Start();

                if (Constants.RestartFailures && current.result.SimpleFitness() < Constants.FitnessThreshold)
                {
                    current.dna.Randomize();
                    _restartCount++;
                }

                //_initialDna = Mutate(_initialDna, T);

                var tmp        = T;
                var current1   = current;
                var generation = Enumerable.Range(0, Constants.TeamsPerGeneration)
                                 .AsParallel()
                                 .Select(j => {
                    var newDna     = Mutate(current1.dna);
                    var newFitness =
                        CalculateFitness(gameCopies[j], initialDnaCopies[j], newDna);

                    return(new GenerationMember(newDna, newFitness));
                })
                                 .ToList();


                var newMax = PickBestMember(_game, _initialDna, generation);

                HandleGoodEnough(ref goodEnough, newMax.result, current, ref goodCount);

                float e  = current.result.SimpleFitness();
                float ep = newMax.result.SimpleFitness();

                double probability = 1;

                float delta = ep - e;

                if (delta > 0)
                {
                    probability = 1;
                    current     = newMax;
                }
                else
                {
                    probability = Math.Exp(-Math.Abs(delta) / T);
                    if (Constants.HillClimbing ^ Probability.Uniform(probability))
                    {
                        newMax.failCount = current.failCount;
                        current          = newMax;
                    }
                    current.failCount++;
                }

                plotT.Add(T);
                plotFit.Add(current.result.SimpleFitness());
                plotHpPercentage.Add(1 - current.result.HpPercentage);
                //plotLength.Add(current.result.TotalTurns);
                plotLength.Add(PlayoutResult.LengthSample(current.result.TotalTurns));

                PrintEvaluationResult(i, e, ep, probability, T, current);
            }

            Console.WriteLine($"Restarts: {_restartCount}");

            if (Constants.GnuPlot)
            {
                var gnuplotConfigString = $"title '{Constants.NumGenerations} generations," +
                                          $"T_s = {Constants.InitialT}'";

                GnuPlot.HoldOn();
                GnuPlot.Set($"xrange [{Constants.InitialT}:{T}] reverse",
                            $"title '{Constants.NumGenerations} generations, T_s = {Constants.InitialT}",
                            "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'");
                Console.ReadKey();
            }
        }