public ChainBasedGenerator(TLayout initialLayout, IGeneratorPlanner <TLayout, TNode> generatorPlanner, List <Chain <TNode> > chains, ILayoutEvolver <TLayout, TNode> layoutEvolver, ILayoutConverter <TLayout, TOutputLayout> layoutConverter) { this.initialLayout = initialLayout; this.generatorPlanner = generatorPlanner; this.chains = chains; this.layoutEvolver = layoutEvolver; this.layoutConverter = layoutConverter; }
public TLayout Generate(TLayout initialLayout, List <Chain <TNode> > chains, ILayoutEvolver <TLayout, TNode> layoutEvolver) { // Initialization this.initialLayout = initialLayout; this.layoutEvolver = layoutEvolver; this.chains = chains; rows = new List <NodeRow>(); nextId = 0; var chainsCount = chains.Count; var finalLayout = default(TLayout); AddZeroLevelNode(); while (true) { if (CancellationToken.HasValue && CancellationToken.Value.IsCancellationRequested) { break; } // TODO: add some kind of check later //if (context.IterationsCount > 1000000) // break; // Gets next instance to be extended var instance = GetNextInstance(rows); var newDepth = instance.Depth + 1; // The chosen instance must not be already finished if (instance.IsFinished) { throw new InvalidOperationException(); } // Tries to generate a new layout from the instance // var iterationsBefore = context.IterationsCount; var hasLayout = instance.TryGetLayout(out var layout); // var iterationsToGenerate = context.IterationsCount - iterationsBefore; // instance.AddIterations(iterationsToGenerate); // Layout being null means failure and the current iteration is skipped if (!hasLayout) { // log.Add(new LogEntry(LogType.Fail, instance, iterationsToGenerate)); continue; } // Check if the layout has already all the chains added if (newDepth == chainsCount) { OnLayoutGenerated?.Invoke(layout); finalLayout = layout; // log.Add(new LogEntry(LogType.Final, instance, iterationsToGenerate)); break; } // A new instance is created from the generated layout and added to the tree. var nextInstance = new Node(instance, GetLayouts(layout, newDepth), newDepth, 0 /* TODO: iterationsToGenerate */, nextId++); instance.AddChild(nextInstance); AddNode(nextInstance, newDepth); // log.Add(new LogEntry(LogType.Success, nextInstance, iterationsToGenerate)); } return(finalLayout); }
public IList <TOutputLayout> GetLayouts(TMapDescription mapDescription, int numberOfLayouts) { var graph = mapDescription.GetGraph(); if (graph.VerticesCount < 2) { throw new ArgumentException("Given mapDescription must contain at least two nodes.", nameof(mapDescription)); } if (!graphUtils.IsConnected(graph)) { throw new ArgumentException("Given mapDescription must represent a connected graph.", nameof(mapDescription)); } if (!graphUtils.IsPlanar(graph)) { throw new ArgumentException("Given mapDescription must represent a planar graph.", nameof(mapDescription)); } // Create instances and inject the random generator and the cancellation token if possible configurationSpaces = configurationSpacesCreator(mapDescription); TryInjectRandomAndCancellationToken(configurationSpaces); chainDecomposition = chainDecompositionCreator(mapDescription); TryInjectRandomAndCancellationToken(chainDecomposition); initialLayout = initialLayoutCreator(mapDescription); TryInjectRandomAndCancellationToken(initialLayout); generatorPlanner = generatorPlannerCreator(mapDescription); TryInjectRandomAndCancellationToken(generatorPlanner); layoutOperations = layoutOperationsCreator(mapDescription, configurationSpaces); TryInjectRandomAndCancellationToken(layoutOperations); layoutConverter = layoutConverterCreator(mapDescription, configurationSpaces); TryInjectRandomAndCancellationToken(layoutConverter); layoutEvolver = layoutEvolverCreator(mapDescription, layoutOperations); TryInjectRandomAndCancellationToken(layoutEvolver); // Restart stopwatch stopwatch.Restart(); chains = chainDecomposition.GetChains(graph); context = new GeneratorContext(); RegisterEventHandlers(); // TODO: handle number of layouts to be evolved - who should control that? generator or planner? // TODO: handle context.. this is ugly var layouts = generatorPlanner.Generate(initialLayout, numberOfLayouts, chains.Count, (layout, chainNumber, numOfLayouts) => layoutEvolver.Evolve(AddChain(layout, chainNumber), chains[chainNumber], numOfLayouts), context); // Stop stopwatch and prepare benchmark info stopwatch.Stop(); timeTotal = stopwatch.ElapsedMilliseconds; layoutsCount = layouts.Count; // Reset cancellation token if it was already used if (CancellationToken.HasValue && CancellationToken.Value.IsCancellationRequested) { CancellationToken = null; } return(layouts.Select(x => layoutConverter.Convert(x, true)).ToList()); }