예제 #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EvolvableMap"/> class.
 /// </summary>
 /// <param name="mapSearchOptions"> The map search options.</param>
 /// <param name="mutationChance"> The mutation chance. </param>
 /// <param name="r"> The random object. </param>
 /// <param name="mapFitnessOptions"> The map fitness options. </param>
 public EvolvableMap(MapSearchOptions mapSearchOptions, double mutationChance, Random r, MapFitnessOptions mapFitnessOptions) : base(mutationChance, r)
 {
     this.MapFitnessOptions  = mapFitnessOptions;
     this.MapSearchOptions   = mapSearchOptions;
     this.convertedPhenotype = null;
     this.hasBeenConverted   = false;
     this.MapPoints          = new List <MapPoint>();
 }
예제 #2
0
        /// <summary>
        /// Mutates the point into a new point of the same type, but with different distance and angle.
        /// </summary>
        /// <param name="r">
        /// The random generator to use for mutation.
        /// </param>
        /// <param name="mnso">The search options.</param>
        /// <returns>
        /// The <see cref="MapPoint"/> created by the mutation.
        /// </returns>
        public MapPoint Mutate(Random r, MapSearchOptions mnso)
        {
            var positiveChange = r.Next(2);
            var newDistance    = positiveChange == 1
                                ? this.Distance + (r.NextDouble() * mnso.MaximumDistanceModifier)
                                : this.Distance - (r.NextDouble() * mnso.MaximumDistanceModifier);

            positiveChange = r.Next(2);
            var newDegree = positiveChange == 1
                                ? this.Degree + (r.NextDouble() * mnso.MaximumDegreeModifier)
                                : this.Degree - (r.NextDouble() * mnso.MaximumDegreeModifier);

            newDegree = (newDegree + 360) % 360;

            return(new MapPoint(newDistance, newDegree, this.Type, Enums.WasPlaced.NotAttempted));
        }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MultiObjectiveEvolver"/> class.
        /// The multi objective evolver.
        /// </summary>
        /// <param name="numberOfGenerations"> The number Of Generations. </param>
        /// <param name="populationSize"> The population Size. </param>
        /// <param name="mutationChance"> The mutation Chance. </param>
        /// <param name="r"> The random. </param>
        /// <param name="mso"> The map search options. </param>
        /// <param name="mfo"> The map fitness options. </param>
        public MultiObjectiveEvolver(
            int numberOfGenerations,
            int populationSize,
            double mutationChance,
            Random r,
            MapSearchOptions mso,
            MapFitnessOptions mfo)
        {
            this.MapSearchOptions  = mso;
            this.MapFitnessOptions = mfo;
            this.Random            = r;
            this.Population        = new List <EvolvableMap>();

            this.NumberOfGenerations = numberOfGenerations;
            this.PopulationSize      = populationSize;
            this.MutationChance      = mutationChance;
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MapSearchOptions"/> class.
        /// </summary>
        /// <param name="mp">
        /// The map phenotype.
        /// </param>
        /// <param name="mso">
        /// The map search options to copy..
        /// </param>
        public MapSearchOptions(MapPhenotype mp, MapSearchOptions mso)
        {
            this.ChanceToAddBase                = mso.ChanceToAddBase;
            this.ChanceToAddGoldBase            = mso.ChanceToAddGoldBase;
            this.ChanceToAddDestructibleRocks   = mso.ChanceToAddDestructibleRocks;
            this.ChanceToAddXelNagaTower        = mso.ChanceToAddXelNagaTower;
            this.ChanceToRemoveElement          = mso.ChanceToRemoveElement;
            this.ChanceToAddNewElement          = mso.ChanceToAddNewElement;
            this.MaximumStartBaseDistance       = mso.MaximumStartBaseDistance;
            this.MinimumStartBaseDistance       = mso.MinimumStartBaseDistance;
            this.TooManyElementsPenalty         = mso.TooManyElementsPenalty;
            this.TooFewElementsPenalty          = mso.TooFewElementsPenalty;
            this.DisplacementAmountPerStep      = mso.DisplacementAmountPerStep;
            this.MaximumDisplacement            = mso.MaximumDisplacement;
            this.NoPathBetweenStartBasesPenalty = mso.NoPathBetweenStartBasesPenalty;
            this.MapCompletion = mso.MapCompletion;
            this.MaximumNumberOfXelNagaTowers     = mso.MaximumNumberOfXelNagaTowers;
            this.MinimumNumberOfXelNagaTowers     = mso.MinimumNumberOfXelNagaTowers;
            this.MaximumNumberOfDestructibleRocks = mso.MaximumNumberOfDestructibleRocks;
            this.MinimumNumberOfDestructibleRocks = mso.MinimumNumberOfDestructibleRocks;
            this.MaximumNumberOfRamps             = mso.MaximumNumberOfRamps;
            this.MinimumNumberOfRamps             = mso.MinimumNumberOfRamps;
            this.MaximumNumberOfBases             = mso.MaximumNumberOfBases;
            this.MinimumNumberOfBases             = mso.MinimumNumberOfBases;
            this.MinimumDegreeModifier            = mso.MinimumDegreeModifier;
            this.MaximumDegreeModifier            = mso.MaximumDegreeModifier;
            this.MinimumDistanceModifier          = mso.MinimumDistanceModifier;
            this.MaximumDistanceModifier          = mso.MaximumDistanceModifier;
            this.MinimumDistance          = mso.MinimumDistance;
            this.MaximumDistance          = mso.MaximumDistance;
            this.MinimumDegree            = mso.MinimumDegree;
            this.MaximumDegree            = mso.MaximumDegree;
            this.NotPlacedPenalty         = mso.NotPlacedPenalty;
            this.NotPlacedPenaltyModifier = mso.NotPlacedPenaltyModifier;

            this.Map = mp;
        }
예제 #5
0
파일: Program.cs 프로젝트: esfdk/OPMGFS
        /// <summary>
        /// Runs standard evolution and/or MOEA seeded with maps found by the constrained novelty search.
        /// </summary>
        /// <param name="maps"> The maps to run evolution on. </param>
        /// <param name="r"> The random number generator. </param>
        /// <param name="mapSearchOptions"> The map search options. </param>
        /// <param name="noveltySearchOptions"> The novelty search options. </param>
        /// <param name="mapFitnessOptions"> The map fitness options. </param>
        /// <param name="numberOfNoveltyGenerations"> The number of generations to run for the novelty search. </param>
        /// <param name="numberOfEvolutionGenerations"> The number of generations to run for the standard evolution. </param>
        /// <param name="numberOfMOEAGenerations"> The number of generations to run for the MOEA. </param>
        /// <param name="evolutionPopulationSize"> The population size of the standard evolution. </param>
        /// <param name="numberOfParents"> The number of parents for the standard evolution. </param>
        /// <param name="numberOfChildren"> The number of children spawned per generation in the standard evolution. </param>
        /// <param name="evolutionMutationChance"> The chance of mutation happening during evolution. </param>
        /// <param name="moeaPopulationSize"> The population size of the MOEA. </param>
        /// <param name="moeaMutationChance"> The chance of mutation happening in the MOEA. </param>
        /// <param name="selectionStrategy"> The selection strategy used in the standard evolution. </param>
        /// <param name="parentSelectionStrategy"> The parent selection strategy used in the standard evolution. </param>
        /// <param name="populationStrategy"> The population strategy used in the standard evolution. </param>
        /// <param name="folderName"> The folder to save results to in "Images/Finished Maps". </param>
        /// <param name="fileToWriteTo"> The file to write timings and fitness per generation to. </param>
        /// <param name="selectHighestFitness"> Determines if the maps for seeding are chosen by highest fitness or highest novelty. </param>
        /// <param name="lowestFitnessLevelForPrint"> The fitness required before a map is printed. </param>
        /// <param name="runEvo"> Determines if the standard evolution should be run. </param>
        /// <param name="runMOEA"> Determines if the MOEA should be run. </param>
        public static void RunEvolutionWithNoveltyAsBase(
            List <MapPhenotype> maps,
            Random r,
            MapSearchOptions mapSearchOptions         = null,
            NoveltySearchOptions noveltySearchOptions = null,
            MapFitnessOptions mapFitnessOptions       = null,
            int numberOfNoveltyGenerations            = 10,
            int numberOfEvolutionGenerations          = 10,
            int numberOfMOEAGenerations                     = 10,
            int evolutionPopulationSize                     = 20,
            int numberOfParents                             = 6,
            int numberOfChildren                            = 16,
            double evolutionMutationChance                  = 0.3,
            int moeaPopulationSize                          = 25,
            double moeaMutationChance                       = 0.3,
            Enums.SelectionStrategy selectionStrategy       = Enums.SelectionStrategy.ChanceBased,
            Enums.SelectionStrategy parentSelectionStrategy = Enums.SelectionStrategy.ChanceBased,
            Enums.PopulationStrategy populationStrategy     = Enums.PopulationStrategy.Mutation,
            string folderName                 = "MapNoveltyEvolution",
            string fileToWriteTo              = "NoveltyEvolutionHighestFitnessSearchGenerationTimes.txt",
            bool selectHighestFitness         = true,
            double lowestFitnessLevelForPrint = double.MinValue,
            bool runEvo  = true,
            bool runMOEA = true)
        {
            var stringToWrite  = new StringBuilder();
            var mso            = mapSearchOptions ?? new MapSearchOptions(null);
            var mfo            = mapFitnessOptions ?? new MapFitnessOptions();
            var nso            = noveltySearchOptions ?? new NoveltySearchOptions();
            var listOfArchives = new List <List <Solution> >();

            // Novelty search
            var sw = new Stopwatch();

            sw.Start();
            var baseMapCounter = 0;

            foreach (var map in maps)
            {
                sw.Restart();
                stringToWrite.AppendLine(string.Format("Performing novelty search on base map number {0}.", baseMapCounter));
                var heightLevels = map.HeightLevels.Clone() as Enums.HeightLevel[, ];
                var items        = map.MapItems.Clone() as Enums.Item[, ];
                var baseMap      = new MapPhenotype(heightLevels, items);
                baseMap.CreateCompleteMap(Enums.Half.Top, Enums.MapFunction.Turn).SaveMapToPngFile(string.Format("Base Map {0}", baseMapCounter), folderName, false);

                mso = new MapSearchOptions(map, mso);
                var searcher = new MapSearcher(r, mso, nso);

                searcher.RunGenerations(numberOfNoveltyGenerations, stringToWrite);

                listOfArchives.Add(searcher.Archive.Archive);

                stringToWrite.AppendLine(string.Format("It took {0} ms to perform novelty search on base map number {1}.", sw.ElapsedMilliseconds, baseMapCounter));
                stringToWrite.AppendLine();

                baseMapCounter++;
            }

            baseMapCounter = 0;

            sw.Restart();
            var solutions = new List <List <EvolvableMap> >();

            if (selectHighestFitness)
            {
                stringToWrite.AppendLine(string.Format("Sorting initial population based by highest fitness."));
                foreach (var map in maps)
                {
                    var evolvableMaps = new List <EvolvableMap>();
                    var archive       = listOfArchives[baseMapCounter];

                    foreach (var solution in archive)
                    {
                        var ms = (MapSolution)solution;
                        mso = new MapSearchOptions(map, mso);
                        var evolvableMap = new EvolvableMap(mso, evolutionMutationChance, r, mfo, ms.MapPoints);
                        evolvableMap.CalculateFitness();
                        evolvableMaps.Add(evolvableMap);
                    }

                    solutions.Add(evolvableMaps.OrderByDescending(s => s.Fitness).ToList());

                    baseMapCounter++;
                }

                stringToWrite.AppendLine(string.Format("It took {0} ms to find maps with the highest fitness.", sw.ElapsedMilliseconds));
                sw.Restart();
            }
            else
            {
                stringToWrite.AppendLine(string.Format("Sorting initial population based by highest novelty."));
                foreach (var map in maps)
                {
                    var evolvableMaps = new List <EvolvableMap>();
                    var archive       = listOfArchives[baseMapCounter];

                    var tempArchive = archive.OrderByDescending(s => s.Novelty);

                    foreach (var solution in tempArchive)
                    {
                        var ms = (MapSolution)solution;
                        mso = new MapSearchOptions(map, mso);
                        var evolvableMap = new EvolvableMap(mso, evolutionMutationChance, r, mfo, ms.MapPoints);
                        evolvableMap.CalculateFitness();
                        evolvableMaps.Add(evolvableMap);
                    }

                    solutions.Add(evolvableMaps);

                    baseMapCounter++;
                }

                stringToWrite.AppendLine(string.Format("It took {0} ms to find maps with the highest novelty.", sw.ElapsedMilliseconds));
                sw.Restart();
            }

            // Evolution
            if (runEvo)
            {
                sw.Restart();
                var bestMaps = new List <EvolvableMap>();
                baseMapCounter = 0;
                foreach (var map in maps)
                {
                    sw.Restart();
                    stringToWrite.AppendLine(string.Format("Performing evolution on base map number {0}.", baseMapCounter));
                    mso = new MapSearchOptions(map, mso);
                    var evolver = new Evolver <EvolvableMap>(
                        numberOfEvolutionGenerations,
                        evolutionPopulationSize,
                        numberOfParents,
                        numberOfChildren,
                        evolutionMutationChance,
                        r,
                        new object[] { mso, evolutionMutationChance, r, mfo })
                    {
                        PopulationSelectionStrategy = selectionStrategy,
                        ParentSelectionStrategy     = parentSelectionStrategy,
                        PopulationStrategy          = populationStrategy
                    };

                    evolver.Initialize(solutions[baseMapCounter].Take(evolutionPopulationSize), stringToWrite);
                    evolver.Evolve(stringToWrite);
                    var variationValue = 0;

                    foreach (var individual in evolver.Population)
                    {
                        variationValue++;
                        if (individual.Fitness >= lowestFitnessLevelForPrint)
                        {
                            individual.ConvertedPhenotype.SaveMapToPngFile(string.Format("Evo_Base Map {0}_Map {1}_Fitness {2}", baseMapCounter, variationValue, individual.Fitness), folderName, false);
                        }
                    }

                    stringToWrite.AppendLine(string.Format("It took {0} ms to perform evolution on base map number {1}.", sw.ElapsedMilliseconds, baseMapCounter));
                    stringToWrite.AppendLine();

                    bestMaps.Add(evolver.Population.OrderByDescending(evoMap => evoMap.Fitness).ToList()[0]);
                    MapHelper.SaveGreyscaleNoveltyMap(evolver.Population, string.Format("Evo_Base Map {0} NoveltyMap", baseMapCounter), folderName);

                    baseMapCounter++;
                }

                MapHelper.SaveGreyscaleNoveltyMap(bestMaps, string.Format("Evo_Best Maps NoveltyMap"), folderName);
            }

            // MOEA
            if (runMOEA)
            {
                baseMapCounter = 0;
                var bestMaps = new List <EvolvableMap>();
                foreach (var map in maps)
                {
                    sw.Restart();
                    stringToWrite.AppendLine(string.Format("Performing multi objective evolution for base map number {0}", baseMapCounter));

                    var heightLevels = map.HeightLevels.Clone() as Enums.HeightLevel[, ];
                    var items        = map.MapItems.Clone() as Enums.Item[, ];
                    var baseMap      = new MapPhenotype(heightLevels, items);
                    baseMap.CreateCompleteMap(Enums.Half.Top, Enums.MapFunction.Mirror);
                    baseMap.SaveMapToPngFile(string.Format("Base Map {0}", baseMapCounter), folderName, false);

                    mso = new MapSearchOptions(map, mso);
                    var evolver = new MultiObjectiveEvolver(
                        numberOfMOEAGenerations,
                        moeaPopulationSize,
                        moeaMutationChance,
                        r,
                        mso,
                        mfo);

                    evolver.RunEvolution(stringToWrite, solutions[baseMapCounter].Take(moeaPopulationSize));

                    var variationValue = 0;

                    foreach (var individual in evolver.Population)
                    {
                        variationValue++;
                        if (individual.Fitness >= lowestFitnessLevelForPrint)
                        {
                            individual.ConvertedPhenotype.SaveMapToPngFile(string.Format("MOEA_Base Map {0}_Map {1}_Fitness {2}", baseMapCounter, variationValue, individual.Fitness), folderName, false);
                        }
                    }

                    stringToWrite.AppendLine(string.Format("It took {0} ms to perform multi objective evolution on base map number {1}", sw.ElapsedMilliseconds, baseMapCounter));
                    stringToWrite.AppendLine();

                    bestMaps.Add(evolver.Population.OrderByDescending(evoMap => evoMap.Fitness).ToList()[0]);
                    MapHelper.SaveGreyscaleNoveltyMap(evolver.Population, string.Format("MOEA_Base Map {0} NoveltyMap", baseMapCounter), folderName);

                    baseMapCounter++;
                }

                MapHelper.SaveGreyscaleNoveltyMap(bestMaps, string.Format("MOEA_Best Maps NoveltyMap"), folderName);
            }

            WriteToTextFile(stringToWrite.ToString(), fileToWriteTo, folderName);
        }
예제 #6
0
파일: Program.cs 프로젝트: esfdk/OPMGFS
        /// <summary>
        /// Runs novelty search on a given set of maps with the given settings.
        /// </summary>
        /// <param name="maps"> The maps to run evolution on. </param>
        /// <param name="r"> The random number generator. </param>
        /// <param name="mapSearchOptions"> The map search options. </param>
        /// <param name="noveltySearchOptions"> The novelty search options. </param>
        /// <param name="mapFitnessOptions"> The map fitness options. </param>
        /// <param name="numberOfGenerations"> The number of generations to run. </param>
        /// <param name="folderName"> The folder to save results to in "Images/Finished Maps". </param>
        /// <param name="fileToWriteTo"> The file to write timings and fitness per generation to. </param>
        /// <param name="lowestFitnessLevelForPrint"> The fitness required before a map is printed. </param>
        public static void RunNoveltySearch(
            List <MapPhenotype> maps,
            Random r,
            MapSearchOptions mapSearchOptions         = null,
            NoveltySearchOptions noveltySearchOptions = null,
            MapFitnessOptions mapFitnessOptions       = null,
            int numberOfGenerations           = 10,
            string folderName                 = "MapNovelty",
            string fileToWriteTo              = "NoveltySearchGenerationTimes.txt",
            double lowestFitnessLevelForPrint = double.MinValue)
        {
            var stringToWrite = new StringBuilder();

            var mso = mapSearchOptions ?? new MapSearchOptions(null);
            var mfo = mapFitnessOptions ?? new MapFitnessOptions();
            var nso = noveltySearchOptions ?? new NoveltySearchOptions();

            var sw = new Stopwatch();

            sw.Start();
            var baseMapCounter = 0;

            foreach (var map in maps)
            {
                sw.Restart();
                stringToWrite.AppendLine(string.Format("Performing novelty search on base map number {0}.", baseMapCounter));
                var heightLevels = map.HeightLevels.Clone() as Enums.HeightLevel[, ];
                var items        = map.MapItems.Clone() as Enums.Item[, ];
                var baseMap      = new MapPhenotype(heightLevels, items);
                baseMap.CreateCompleteMap(Enums.Half.Top, Enums.MapFunction.Turn).SaveMapToPngFile(string.Format("Base Map {0}", baseMapCounter), folderName, false);

                mso = new MapSearchOptions(map, mso);
                var searcher = new MapSearcher(r, mso, nso);

                searcher.RunGenerations(numberOfGenerations, stringToWrite);

                var archiveMaps    = new List <MapPhenotype>();
                var variationValue = 0;
                foreach (var solution in searcher.Archive.Archive)
                {
                    var individual = (MapSolution)solution;
                    variationValue++;
                    var fitness = new MapFitness(individual.ConvertedPhenotype, mfo).CalculateFitness();
                    if (fitness >= lowestFitnessLevelForPrint)
                    {
                        individual.ConvertedPhenotype.SaveMapToPngFile(string.Format("Base Map {0}_Map {1}_Fitness {2}", baseMapCounter, variationValue, fitness), folderName, false);
                    }
                    else
                    {
                        Console.WriteLine("fitness too low: " + fitness);
                    }

                    archiveMaps.Add(individual.ConvertedPhenotype);
                }

                stringToWrite.AppendLine(string.Format("It took {0} ms to perform novelty search on base map number {1}.", sw.ElapsedMilliseconds, baseMapCounter));
                stringToWrite.AppendLine();

                MapHelper.SaveGreyscaleNoveltyMap(archiveMaps, string.Format("Base Map {0} NoveltyMap", baseMapCounter), folderName);

                baseMapCounter++;
            }

            WriteToTextFile(stringToWrite.ToString(), fileToWriteTo, folderName);
        }
예제 #7
0
파일: Program.cs 프로젝트: esfdk/OPMGFS
        /// <summary>
        /// Runs MOEA on a set of maps.
        /// </summary>
        /// <param name="maps"> The maps to run evolution on. </param>
        /// <param name="r"> The random number generator. </param>
        /// <param name="mapSearchOptions"> The map search options. </param>
        /// <param name="mapFitnessOptions"> The map fitness options. </param>
        /// <param name="numberOfGenerations"> The number of generations to run. </param>
        /// <param name="populationSize"> The population size. </param>
        /// <param name="mutationChance"> The chance of mutation happening. </param>
        /// <param name="folderName"> The folder to save results to in "Images/Finished Maps". </param>
        /// <param name="fileToWriteTo"> The file to write timings and fitness per generation to. </param>
        /// <param name="lowestFitnessLevelForPrint"> The fitness required before a map is printed. </param>
        public static void RunMultiobjectiveEvolution(
            List <MapPhenotype> maps,
            Random r,
            MapSearchOptions mapSearchOptions   = null,
            MapFitnessOptions mapFitnessOptions = null,
            int numberOfGenerations             = 10,
            int populationSize                = 25,
            double mutationChance             = 0.3,
            string folderName                 = "MapMultiObjectiveEvolution",
            string fileToWriteTo              = "MultiObjectiveEvolutionGenerationTimes.txt",
            double lowestFitnessLevelForPrint = double.MinValue)
        {
            var sb = new StringBuilder();
            var sw = new Stopwatch();

            var mso            = mapSearchOptions ?? new MapSearchOptions(null);
            var mfo            = mapFitnessOptions ?? new MapFitnessOptions();
            var bestMaps       = new List <EvolvableMap>();
            var baseMapCounter = 0;

            foreach (var map in maps)
            {
                sw.Restart();
                sb.AppendLine(string.Format("Starting evolution for base map number {0}", baseMapCounter));

                var heightLevels = map.HeightLevels.Clone() as Enums.HeightLevel[, ];
                var items        = map.MapItems.Clone() as Enums.Item[, ];
                var baseMap      = new MapPhenotype(heightLevels, items);
                baseMap.CreateCompleteMap(Enums.Half.Top, Enums.MapFunction.Turn).SaveMapToPngFile(string.Format("Base Map {0}", baseMapCounter), folderName, false);

                mso = new MapSearchOptions(map, mso);
                var evolver = new MultiObjectiveEvolver(
                    numberOfGenerations,
                    populationSize,
                    mutationChance,
                    r,
                    mso,
                    mfo);

                var bestMap = evolver.RunEvolution(sb);

                var variationValue = 0;

                foreach (var individual in evolver.Population)
                {
                    variationValue++;
                    if (individual.Fitness >= lowestFitnessLevelForPrint)
                    {
                        individual.ConvertedPhenotype.SaveMapToPngFile(string.Format("Base Map {0}_Map {1}_Fitness {2}", baseMapCounter, variationValue, individual.Fitness), folderName, false);
                    }
                }

                sb.AppendLine(string.Format("Evolution for base map number {0} took {1} ms", baseMapCounter, sw.ElapsedMilliseconds));
                sb.AppendLine();

                bestMaps.Add(evolver.Population.OrderByDescending(evoMap => evoMap.Fitness).ToList()[0]);
                MapHelper.SaveGreyscaleNoveltyMap(evolver.Population, string.Format("Base Map {0} NoveltyMap", baseMapCounter), folderName);
                Console.WriteLine("The map fitness values of base map {0} were: {1}", baseMapCounter, bestMap.MapFitnessValues);

                baseMapCounter++;
            }

            MapHelper.SaveGreyscaleNoveltyMap(bestMaps, string.Format(" Best Maps NoveltyMap"), folderName);
            WriteToTextFile(sb.ToString(), fileToWriteTo, folderName);
        }
예제 #8
0
파일: Program.cs 프로젝트: esfdk/OPMGFS
        /// <summary>
        /// Runs evolution with the given settings.
        /// </summary>
        /// <param name="maps"> The maps to run evolution on. </param>
        /// <param name="r"> The random number generator. </param>
        /// <param name="mapSearchOptions"> The map search options. </param>
        /// <param name="mapFitnessOptions"> The map fitness options. </param>
        /// <param name="numberOfGenerations"> The number of generations to run. </param>
        /// <param name="populationSize"> The population size of the evolution. </param>
        /// <param name="numberOfParents"> The number of parents used in the evolution. </param>
        /// <param name="numberOfChildren"> The number of children spawned per generation. </param>
        /// <param name="mutationChance"> The chance of mutation happening. </param>
        /// <param name="selectionStrategy"> The selection strategy. </param>
        /// <param name="parentSelectionStrategy"> The parent selection strategy. </param>
        /// <param name="populationStrategy"> The population strategy. </param>
        /// <param name="folderName"> The folder to save results to in "Images/Finished Maps". </param>
        /// <param name="fileToWriteTo"> The file to write timings and fitness per generation to. </param>
        /// <param name="lowestFitnessLevelForPrint"> The fitness required before a map is printed. </param>
        public static void RunEvolution(
            List <MapPhenotype> maps,
            Random r,
            MapSearchOptions mapSearchOptions   = null,
            MapFitnessOptions mapFitnessOptions = null,
            int numberOfGenerations             = 10,
            int populationSize    = 20,
            int numberOfParents   = 6,
            int numberOfChildren  = 16,
            double mutationChance = 0.3,
            Enums.SelectionStrategy selectionStrategy       = Enums.SelectionStrategy.ChanceBased,
            Enums.SelectionStrategy parentSelectionStrategy = Enums.SelectionStrategy.ChanceBased,
            Enums.PopulationStrategy populationStrategy     = Enums.PopulationStrategy.Mutation,
            string folderName    = "MapEvolution",
            string fileToWriteTo = "EvolutionGenerationTimes.txt",
            double lowestFitnessLevelForPrint = double.MinValue)
        {
            var stringToWrite = new StringBuilder();
            var mso           = mapSearchOptions ?? new MapSearchOptions(null);
            var mfo           = mapFitnessOptions ?? new MapFitnessOptions();
            var bestMaps      = new List <EvolvableMap>();

            var sw = new Stopwatch();

            sw.Start();
            var baseMapCounter = 0;

            foreach (var map in maps)
            {
                sw.Restart();
                stringToWrite.AppendLine(string.Format("Performing evolution on base map number {0}.", baseMapCounter));
                var heightLevels = map.HeightLevels.Clone() as Enums.HeightLevel[, ];
                var items        = map.MapItems.Clone() as Enums.Item[, ];
                var baseMap      = new MapPhenotype(heightLevels, items);
                baseMap.CreateCompleteMap(Enums.Half.Top, Enums.MapFunction.Turn).SaveMapToPngFile(string.Format("Base Map {0}", baseMapCounter), folderName, false);

                mso = new MapSearchOptions(map, mso);
                var evolver = new Evolver <EvolvableMap>(
                    numberOfGenerations,
                    populationSize,
                    numberOfParents,
                    numberOfChildren,
                    mutationChance,
                    r,
                    new object[] { mso, mutationChance, r, mfo })
                {
                    PopulationSelectionStrategy = selectionStrategy,
                    ParentSelectionStrategy     = parentSelectionStrategy,
                    PopulationStrategy          = populationStrategy
                };

                evolver.Initialize(stringToWrite);
                var bestMap        = evolver.Evolve(stringToWrite);
                var variationValue = 0;

                foreach (var individual in evolver.Population)
                {
                    variationValue++;
                    if (individual.Fitness >= lowestFitnessLevelForPrint)
                    {
                        individual.ConvertedPhenotype.SaveMapToPngFile(string.Format("Base Map {0}_Map {1}_Fitness {2}", baseMapCounter, variationValue, individual.Fitness), folderName, false);
                    }
                }

                stringToWrite.AppendLine(string.Format("It took {0} ms to perform evolution on base map number {1}.", sw.ElapsedMilliseconds, baseMapCounter));
                stringToWrite.AppendLine();

                bestMaps.Add(evolver.Population.OrderByDescending(evoMap => evoMap.Fitness).ToList()[0]);
                MapHelper.SaveGreyscaleNoveltyMap(evolver.Population, string.Format("Base Map {0} NoveltyMap", baseMapCounter), folderName);

                Console.WriteLine("The map fitness values of base map {0} were: {1}", baseMapCounter, ((EvolvableMap)bestMap).MapFitnessValues);

                baseMapCounter++;
            }

            MapHelper.SaveGreyscaleNoveltyMap(bestMaps, string.Format(" Best Maps NoveltyMap"), folderName);
            WriteToTextFile(stringToWrite.ToString(), fileToWriteTo, folderName);
        }
예제 #9
0
파일: MapSearcher.cs 프로젝트: esfdk/OPMGFS
        /// <summary>
        /// Initializes a new instance of the <see cref="MapSearcher"/> class.
        /// </summary>
        /// <param name="r">
        /// The random to use in searching.
        /// </param>
        /// <param name="mapSearchOptions">
        /// The map options for this search.
        /// </param>
        /// <param name="noveltySearchOptions">
        /// The novelty Search Options.
        /// </param>
        public MapSearcher(Random r, MapSearchOptions mapSearchOptions, NoveltySearchOptions noveltySearchOptions)
            : base(r, noveltySearchOptions)
        {
            this.MapSearchOptions     = mapSearchOptions;
            this.FeasiblePopulation   = new MapPopulation(true, noveltySearchOptions.FeasiblePopulationSize);
            this.InfeasiblePopulation = new MapPopulation(false, noveltySearchOptions.InfeasiblePopulationSize);
            this.Archive = new MapNovelArchive();

            var numberOfAttempts = 0;

            while (this.FeasiblePopulation.CurrentGeneration.Count < noveltySearchOptions.FeasiblePopulationSize)
            {
                var list = MapConversionHelper.GenerateInitialMapPoints(mapSearchOptions, r);
                var ms   = new MapSolution(this.MapSearchOptions, this.NoveltySearchOptions, list, r);

                if (ms.IsFeasible)
                {
                    this.FeasiblePopulation.CurrentGeneration.Add(ms);
                }
                else if (InfeasiblePopulation.CurrentGeneration.Count < noveltySearchOptions.InfeasiblePopulationSize)
                {
                    this.InfeasiblePopulation.CurrentGeneration.Add(ms);
                }

                if (numberOfAttempts > 1000)
                {
                    break;
                }

                numberOfAttempts++;
            }

            while (this.InfeasiblePopulation.CurrentGeneration.Count < noveltySearchOptions.InfeasiblePopulationSize)
            {
                var list = MapConversionHelper.GenerateInitialMapPoints(mapSearchOptions, r);

                for (var j = 0; j < list.Count; j++)
                {
                    var item = list[j];

                    var distance = r.Next(2) == 1 ? (r.Next(2) == 1 ? (item.Distance + 1.0) : (item.Distance - 1.0)) : item.Distance;
                    var degree   = r.Next(2) == 1 ? (r.Next(2) == 1 ? (item.Degree + 180) : (item.Degree - 180)) : item.Degree;

                    var mp = new MapPoint(distance, degree, item.Type, Enums.WasPlaced.NotAttempted);

                    list[j] = mp;
                }

                var ms = new MapSolution(this.MapSearchOptions, this.NoveltySearchOptions, list, r);
                this.InfeasiblePopulation.CurrentGeneration.Add(ms);
            }

            foreach (var ms in this.FeasiblePopulation.CurrentGeneration)
            {
                var novelty = ms.CalculateNovelty(
                    this.FeasiblePopulation,
                    this.Archive,
                    noveltySearchOptions.NumberOfNeighbours);

                if (novelty >= noveltySearchOptions.MinimumNovelty)
                {
                    this.Archive.Archive.Add(ms);
                }
            }
        }
예제 #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EvolvableMap"/> class.
 /// </summary>
 /// <param name="mapSearchOptions"> The map search options. </param>
 /// <param name="mutationChance"> The mutation chance. </param>
 /// <param name="r"> The random object. </param>
 /// <param name="mapFitnessOptions"> The map fitness options. </param>
 /// <param name="mapPoints"> The map points. </param>
 public EvolvableMap(MapSearchOptions mapSearchOptions, double mutationChance, Random r, MapFitnessOptions mapFitnessOptions, List <MapPoint> mapPoints)
     : this(mapSearchOptions, mutationChance, r, mapFitnessOptions)
 {
     this.MapPoints = mapPoints;
 }