示例#1
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);
        }
示例#2
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);
        }