/// <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);
        }
Ejemplo n.º 2
0
        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);
        }