private void SetupGenerator() { var mapping = mapDescription.GetMapping(); var chainsGeneric = configuration.Chains; // Create chain decomposition if (chainsGeneric == null) { var chainDecomposition = new TwoStageChainDecomposition <TNode>(mapDescriptionOriginal, new BreadthFirstChainDecomposition <TNode>(configuration.ChainDecompositionConfiguration ?? new ChainDecompositionConfiguration())); chainsGeneric = chainDecomposition.GetChains(mapDescriptionOriginal.GetGraph()); } var chains = chainsGeneric .Select(x => new Chain <int>(x.Nodes.Select(y => mapping[y]).ToList(), x.Number) { IsFromFace = x.IsFromFace }) .ToList(); // Create generator planner var generatorPlanner = new GeneratorPlanner <Layout <Configuration <CorridorsData> >, int>(configuration.SimulatedAnnealingMaxBranching); // Create configuration spaces var configurationSpacesGenerator = new ConfigurationSpacesGenerator( new PolygonOverlap(), DoorHandler.DefaultHandler, new OrthogonalLineIntersection(), new GridPolygonUtils()); var configurationSpaces = configurationSpacesGenerator.GetConfigurationSpaces <Configuration <CorridorsData> >(mapDescription); var corridorConfigurationSpaces = configurationSpaces; var averageSize = configurationSpaces.GetAverageSize(); var polygonOverlap = new FastPolygonOverlap(); // Create generator constraints var stageOneConstraints = new List <INodeConstraint <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData>, CorridorsData> > { new BasicConstraint <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData>, CorridorsData, IntAlias <PolygonGrid2D> >( new FastPolygonOverlap(), averageSize, configurationSpaces ), new CorridorConstraints <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData>, CorridorsData, IntAlias <PolygonGrid2D> >( mapDescription, averageSize, corridorConfigurationSpaces ), }; if (!configuration.RoomsCanTouch) { stageOneConstraints.Add(new TouchingConstraints <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData>, CorridorsData, IntAlias <PolygonGrid2D> >( mapDescription, polygonOverlap )); } var stageOneConstraintsEvaluator = new ConstraintsEvaluator <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData>, IntAlias <PolygonGrid2D>, CorridorsData>(stageOneConstraints); var roomShapesHandler = new RoomShapesHandler <int, Configuration <CorridorsData> >( configurationSpaces, configurationSpaces.GetIntAliasMapping(), mapDescription, configuration.RepeatModeOverride ); // Create layout operations var layoutOperations = new LayoutOperations <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData>, IntAlias <PolygonGrid2D>, CorridorsData>(corridorConfigurationSpaces, configurationSpaces.GetAverageSize(), mapDescription, stageOneConstraintsEvaluator, stageOneConstraintsEvaluator, roomShapesHandler, configuration.ThrowIfRepeatModeNotSatisfied); var initialLayout = new Layout <Configuration <CorridorsData> >(mapDescription.GetGraph()); var layoutConverter = new BasicLayoutConverter <Layout <Configuration <CorridorsData> >, TNode, Configuration <CorridorsData> >(mapDescription, configurationSpaces, configurationSpaces.GetIntAliasMapping()); // Create simulated annealing evolver var layoutEvolver = new SimulatedAnnealingEvolver <Layout <Configuration <CorridorsData> >, int, Configuration <CorridorsData> >(layoutOperations, configuration.SimulatedAnnealingConfiguration, true); // Create the generator itself generator = new ChainBasedGenerator <Layout <Configuration <CorridorsData> >, MapLayout <TNode>, int>(initialLayout, generatorPlanner, chains, layoutEvolver, layoutConverter); // Register event handlers generator.OnRandomInjected += (random) => { ((IRandomInjectable)configurationSpaces).InjectRandomGenerator(random); ((IRandomInjectable)layoutOperations).InjectRandomGenerator(random); ((IRandomInjectable)layoutEvolver).InjectRandomGenerator(random); ((IRandomInjectable)layoutConverter).InjectRandomGenerator(random); }; generator.OnCancellationTokenInjected += (token) => { ((ICancellable)generatorPlanner).SetCancellationToken(token); ((ICancellable)layoutEvolver).SetCancellationToken(token); }; layoutEvolver.OnEvent += (sender, args) => OnSimulatedAnnealingEvent?.Invoke(sender, args); layoutEvolver.OnPerturbed += (sender, layout) => OnPerturbed?.Invoke(layoutConverter.Convert(layout, false)); layoutEvolver.OnPerturbed += (sender, layout) => OnPerturbedInternal?.Invoke(layout); layoutEvolver.OnValid += (sender, layout) => OnPartialValid?.Invoke(layoutConverter.Convert(layout, true)); generatorPlanner.OnLayoutGenerated += layout => OnValid?.Invoke(layoutConverter.Convert(layout, true)); }
/// <summary> /// Benchmark our speed improvements. /// </summary> public static void CompareOldAndNew() { //var mapDescriptions = GetMapDescriptionsSet(new IntVector2(1, 1), false); var mapDescriptions = GetMapDescriptionsForThesis(false); var layoutGenerator = LayoutGeneratorFactory.GetDefaultChainBasedGenerator <int>(); var benchmark = Benchmark.CreateFor(layoutGenerator); layoutGenerator.InjectRandomGenerator(new Random(0)); layoutGenerator.SetLayoutValidityCheck(false); var scenario = BenchmarkScenario.CreateScenarioFor(layoutGenerator); scenario.SetRunsCount(1); // Measure the difference between old and new approaches { var setups = scenario.MakeSetupsGroup(); setups.AddSetup("Old", (generator) => { //generator.SetChainDecompositionCreator(mapDescription => new OriginalChainDecomposition()); generator.SetChainDecompositionCreator(mapDescription => new OldChainDecomposition <int>(new GraphDecomposer <int>())); //generator.SetGeneratorPlannerCreator(mapDescription => new SlowGeneratorPlanner<Layout<Configuration<EnergyData>, BasicEnergyData>>()); //generator.SetLayoutEvolverCreator((mapDescription, layoutOperations) => //{ // var evolver = // new SimulatedAnnealingEvolver<Layout<Configuration<EnergyData>, BasicEnergyData>, int, // Configuration<EnergyData>>(layoutOperations); // evolver.Configure(50, 500); // evolver.SetRandomRestarts(true, SimulatedAnnealingEvolver<Layout<Configuration<EnergyData>, BasicEnergyData>, int, Configuration<EnergyData>>.RestartSuccessPlace.OnAccepted, false, 0.5f); // return evolver; //}); generator.SetGeneratorPlannerCreator(mapDescription => new BasicGeneratorPlanner <Layout <Configuration <EnergyData>, BasicEnergyData> >()); generator.SetLayoutEvolverCreator((mapDescription, layoutOperations) => { var evolver = new SimulatedAnnealingEvolver <Layout <Configuration <EnergyData>, BasicEnergyData>, int, Configuration <EnergyData> >(layoutOperations); return(evolver); }); generator.InjectRandomGenerator(new Random(0)); }); setups.AddSetup("New", (generator) => { generator.SetChainDecompositionCreator(mapDescription => new BreadthFirstChainDecomposition <int>(new GraphDecomposer <int>())); generator.SetGeneratorPlannerCreator(mapDescription => new BasicGeneratorPlanner <Layout <Configuration <EnergyData>, BasicEnergyData> >()); generator.SetLayoutEvolverCreator((mapDescription, layoutOperations) => { var evolver = new SimulatedAnnealingEvolver <Layout <Configuration <EnergyData>, BasicEnergyData>, int, Configuration <EnergyData> >(layoutOperations); return(evolver); }); generator.InjectRandomGenerator(new Random(0)); }); } Benchmark.WithDefaultFiles((sw, dw) => { benchmark.Execute(layoutGenerator, scenario, mapDescriptions, 80, 1, sw, dw); }); }