/// <summary> /// Gets a basic layout generator that should not be used to generated layouts with corridors. /// </summary> /// <typeparam name="TNode"></typeparam> /// <returns></returns> public static ChainBasedGenerator <MapDescription <TNode>, Layout <Configuration <EnergyData>, BasicEnergyData>, int, Configuration <EnergyData>, IMapLayout <TNode> > GetDefaultChainBasedGenerator <TNode>() { var layoutGenerator = new ChainBasedGenerator <MapDescription <TNode>, Layout <Configuration <EnergyData>, BasicEnergyData>, int, Configuration <EnergyData>, IMapLayout <TNode> >(); var chainDecomposition = new BreadthFirstChainDecomposition <int>(new GraphDecomposer <int>()); var configurationSpacesGenerator = new ConfigurationSpacesGenerator(new PolygonOverlap(), DoorHandler.DefaultHandler, new OrthogonalLineIntersection(), new GridPolygonUtils()); var generatorPlanner = new BasicGeneratorPlanner <Layout <Configuration <EnergyData>, BasicEnergyData> >(); layoutGenerator.SetChainDecompositionCreator(mapDescription => chainDecomposition); layoutGenerator.SetConfigurationSpacesCreator(mapDescription => configurationSpacesGenerator.Generate <TNode, Configuration <EnergyData> >(mapDescription)); layoutGenerator.SetInitialLayoutCreator(mapDescription => new Layout <Configuration <EnergyData>, BasicEnergyData>(mapDescription.GetGraph())); layoutGenerator.SetGeneratorPlannerCreator(mapDescription => generatorPlanner); layoutGenerator.SetLayoutConverterCreator((mapDescription, configurationSpaces) => new BasicLayoutConverter <Layout <Configuration <EnergyData>, BasicEnergyData>, TNode, Configuration <EnergyData> >(mapDescription, configurationSpaces, configurationSpacesGenerator.LastIntAliasMapping)); layoutGenerator.SetLayoutEvolverCreator((mapDescription, layoutOperations) => new SimulatedAnnealingEvolver <Layout <Configuration <EnergyData>, BasicEnergyData>, int, Configuration <EnergyData> >(layoutOperations)); layoutGenerator.SetLayoutOperationsCreator((mapDescription, configurationSpaces) => { var layoutOperations = new LayoutOperationsWithConstraints <Layout <Configuration <EnergyData>, BasicEnergyData>, int, Configuration <EnergyData>, IntAlias <GridPolygon>, EnergyData, BasicEnergyData>(configurationSpaces, configurationSpaces.GetAverageSize()); var averageSize = configurationSpaces.GetAverageSize(); layoutOperations.AddNodeConstraint(new BasicContraint <Layout <Configuration <EnergyData>, BasicEnergyData>, int, Configuration <EnergyData>, EnergyData, IntAlias <GridPolygon> >( new FastPolygonOverlap(), averageSize, configurationSpaces )); return(layoutOperations); }); return(layoutGenerator); }
private DungeonGeneratorConfiguration <int> GetChainsConfiguration(NamedMapDescription namedMapDescription) { var chainDecompositionOld = new BreadthFirstChainDecomposition <int>(new ChainDecompositionConfiguration()); var chainDecomposition = new TwoStageChainDecomposition <int>(namedMapDescription.MapDescription, chainDecompositionOld); var configuration = GetOldConfiguration(namedMapDescription); configuration.Chains = chainDecomposition.GetChains(namedMapDescription.MapDescription.GetGraph()); return(configuration); }
/// <summary> /// Gets a generator that can work with corridors. /// </summary> /// <remarks> /// TODO: This is only a temporary solution because we must be able to inject our own corridor nodes creator and this is the easiest way right now. /// </remarks> /// <param name="offsets"></param> /// <param name="canTouch">Whether rooms can touch. Perfomance is decreased when set to false.</param> /// <param name="corridorNodesCreator"></param> /// <returns></returns> public static ChainBasedGenerator <MapDescription <TNode>, Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData>, IMapLayout <TNode> > GetChainBasedGeneratorWithCorridors <TNode>(List <int> offsets, bool canTouch = false, ICorridorNodesCreator <TNode> corridorNodesCreator = null) { var layoutGenerator = new ChainBasedGenerator <MapDescription <TNode>, Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData>, IMapLayout <TNode> >(); var chainDecomposition = new BreadthFirstChainDecomposition <int>(); var configurationSpacesGenerator = new ConfigurationSpacesGenerator(new PolygonOverlap(), DoorHandler.DefaultHandler, new OrthogonalLineIntersection(), new GridPolygonUtils()); var generatorPlanner = new BasicGeneratorPlanner <Layout <Configuration <CorridorsData>, BasicEnergyData> >(); layoutGenerator.SetChainDecompositionCreator(mapDescription => new CorridorsChainDecomposition <int>(mapDescription, chainDecomposition)); layoutGenerator.SetConfigurationSpacesCreator(mapDescription => configurationSpacesGenerator.Generate <TNode, Configuration <CorridorsData> >(mapDescription)); layoutGenerator.SetInitialLayoutCreator(mapDescription => new Layout <Configuration <CorridorsData>, BasicEnergyData>(mapDescription.GetGraph())); layoutGenerator.SetGeneratorPlannerCreator(mapDescription => generatorPlanner); layoutGenerator.SetLayoutConverterCreator((mapDescription, configurationSpaces) => new BasicLayoutConverter <Layout <Configuration <CorridorsData>, BasicEnergyData>, TNode, Configuration <CorridorsData> >(mapDescription, configurationSpaces, configurationSpacesGenerator.LastIntAliasMapping, corridorNodesCreator)); layoutGenerator.SetLayoutEvolverCreator((mapDescription, layoutOperations) => new SimulatedAnnealingEvolver <Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData> >(layoutOperations)); layoutGenerator.SetLayoutOperationsCreator((mapDescription, configurationSpaces) => { var corridorConfigurationSpaces = configurationSpacesGenerator.Generate <TNode, Configuration <CorridorsData> >(mapDescription, offsets); var layoutOperations = new LayoutOperationsWithCorridors <Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData>, IntAlias <GridPolygon>, CorridorsData, BasicEnergyData>(configurationSpaces, mapDescription, corridorConfigurationSpaces, configurationSpaces.GetAverageSize()); var polygonOverlap = new FastPolygonOverlap(); var averageSize = configurationSpaces.GetAverageSize(); layoutOperations.AddNodeConstraint(new BasicContraint <Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData>, CorridorsData, IntAlias <GridPolygon> >( polygonOverlap, averageSize, configurationSpaces )); layoutOperations.AddNodeConstraint(new CorridorConstraints <Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData>, CorridorsData, IntAlias <GridPolygon> >( mapDescription, averageSize, corridorConfigurationSpaces )); if (!canTouch) { layoutOperations.AddNodeConstraint(new TouchingConstraints <Layout <Configuration <CorridorsData>, BasicEnergyData>, int, Configuration <CorridorsData>, CorridorsData, IntAlias <GridPolygon> >( mapDescription, polygonOverlap )); } return(layoutOperations); }); return(layoutGenerator); }
protected override void Run() { var graphs = MapDescriptionLoader.GetGraphs(); var cycleClustersAnalyzer = new CycleClustersAnalyzer <int>(); var nodesInsideCycleAnalyzer = new NodesInsideCycleAnalyzer <int>(); //var benchmarkText = // File.ReadAllText( // @"D:\ProceduralLevelGenerator-data\Random\1583013308_FixedMaxIterationsEvolution_Time_edges_3_3_NewConfigurations - Copy.json"); var benchmarkResult = JsonConvert.DeserializeObject <BenchmarkScenarioResult>(File.ReadAllText( @"D:\ProceduralLevelGenerator-data\Random\1588689334_OldAndNew_edges_3_3\1588689334_OldAndNew_edges_3_3_ChainsAndMaxIterationAndTrees.json")); var correct = 0; var tp = 0; var fp = 0; var fn = 0; var chainDecomposition = new BreadthFirstChainDecomposition <int>(new ChainDecompositionConfiguration() { // PreferSmallCycles = false, }); for (var i = 0; i < graphs.Count; i++) { var namedGraph = graphs[i]; var result = benchmarkResult.BenchmarkResults[2 * i]; var maxCyclesInClusterThreshold = 4; var nodesInsideThreshold = 40; var clustersReport = cycleClustersAnalyzer.GetReport(namedGraph.Graph); var maxClusterIndex = clustersReport.Clusters.MaxBy(x => x.Nodes.Count); var maxClusterSize = clustersReport.Clusters[maxClusterIndex].Nodes.Count; var nodesInsideCycleReport = nodesInsideCycleAnalyzer.GetReport(namedGraph.Graph); Console.Write($"{namedGraph.Name.PadRight(15)}"); Console.Write($"{clustersReport.MaxDensity,4:F}"); if (clustersReport.MaxCyclesInCluster >= maxCyclesInClusterThreshold) { Console.ForegroundColor = ConsoleColor.Red; } Console.Write($"{clustersReport.MaxCyclesInCluster,3}"); Console.ResetColor(); Console.Write($"{maxClusterSize,3}"); if (nodesInsideCycleReport.ProblemsCount >= nodesInsideThreshold) { Console.ForegroundColor = ConsoleColor.Red; } Console.Write($"{nodesInsideCycleReport.ProblemsCount,3}"); Console.ResetColor(); Console.Write($"{result.Runs.Average(x => x.Time),12:F}"); var resultNok = result.Runs.Average(x => x.Time) > 5000; var reportNok = (clustersReport.MaxCyclesInCluster >= maxCyclesInClusterThreshold) || nodesInsideCycleReport.ProblemsCount >= nodesInsideThreshold; if (reportNok && resultNok) { tp++; } if (reportNok && !resultNok) { fp++; Console.Write($"{"fp",3}"); } if (!reportNok && resultNok) { fn++; Console.Write($"{"fn",3}"); } else { Console.Write(" "); } if (reportNok == resultNok) { correct++; } if (i == 95) { var s = 0; } var chains = chainDecomposition.GetChains(namedGraph.Graph); foreach (var chain in chains) { Console.Write($" [{string.Join(",", chain.Nodes)}]"); } Console.WriteLine(); } Console.WriteLine(); Console.WriteLine($"Total acc: {(correct / (double) graphs.Count * 100):F}%"); Console.WriteLine($"Precision: {(tp / (double) (tp + fp) * 100):F}%"); Console.WriteLine($"Recall: {(tp / (double) (tp + fn) * 100):F}%"); }
protected override void CreateConcrete() { chainDecomposition = new BreadthFirstChainDecomposition <int>(); }
protected override void CreateConcrete() { var graphDecomposer = new GraphDecomposer <int>(); chainDecomposition = new BreadthFirstChainDecomposition <int>(graphDecomposer); }