/// <inheritdoc /> /// <remarks> /// Calls abstract GetNextInstance() to build a tree of nodes until a given number of layouts is generated. /// </remarks> public List <TLayout> Generate(TLayout initialLayout, int count, int chainsCount, LayoutGeneratorFunction <TLayout> layoutGeneratorFunc, IGeneratorContext context) { // Initialization this.initialLayout = initialLayout; rows = new List <NodeRow>(); log = new List <LogEntry>(); nextId = 0; this.layoutGeneratorFunc = layoutGeneratorFunc; var layouts = new List <TLayout>(); BeforeGeneration(); AddZeroLevelNode(); while (layouts.Count < count) { if (CancellationToken.HasValue && CancellationToken.Value.IsCancellationRequested) { break; } 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); layouts.Add(layout); log.Add(new LogEntry(LogType.Final, instance, iterationsToGenerate)); AfterValid(); continue; } // A new instance is created from the generated layout and added to the tree. var nextInstance = new Node(instance, GetLayouts(layout, newDepth), newDepth, iterationsToGenerate, nextId++); instance.AddChild(nextInstance); AddNode(nextInstance, newDepth); log.Add(new LogEntry(LogType.Success, nextInstance, iterationsToGenerate)); } AfterGeneration(); return(layouts); }
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); }