Beispiel #1
0
        public void SetupForArbitraryIteration(List <TreeEvalItem <TTreeNode> > nextEvals)
        {
            // It's possible we started this iteration arbitrarily
            TreeNodePath path   = this.TargetPath;
            TTreeNode    target = this.Target;

            while (nextEvals.Count == 0)
            {
                var parent = target != null?m_traversalParameters.GetParentMethod(target) : null;

                if (parent == null)
                {
                    break;
                }

                path = path.CopyAndRemoveEnd();
                var children = m_traversalParameters.GetChildrenMethod(parent).ToList();
                int index    = children.IndexOf(target);
                if (index + 1 < children.Count)
                {
                    for (int childIndex = index + 1; childIndex < children.Count; ++childIndex)
                    {
                        nextEvals.Add(new TreeEvalItem <TTreeNode>(children[childIndex], path.CopyAndAddToPath(index)));
                    }

                    return;
                }

                target = parent;
            }
        }
Beispiel #2
0
        private TreeEvalItem <TTreeNode> ProcessNextEvaluationsForRBFS(TTreeNode target, TreeNodePath path, int targetDepth)
        {
            if (target == null)
            {
                return(null);
            }

            var parent = m_traversalParameters.GetParentMethod(target);

            if (parent == null)
            {
                return(null);
            }


            TTreeNode nextClosestSibling      = null;
            int       nextClosestSiblingIndex = -1;
            int       childIndex = 0;

            foreach (var sibling in m_traversalParameters.GetChildrenMethod(parent))
            {
                if (sibling == target)
                {
                    break;
                }

                nextClosestSiblingIndex = childIndex++;
                nextClosestSibling      = sibling;
            }

            // No siblings, recurse to the parent/grandparent
            if (nextClosestSibling == null)
            {
                TreeEvalItem <TTreeNode> cousin = this.GetNextRBFSCousin(parent, path.CopyAndRemoveEnd(), targetDepth);
                if (cousin != null)
                {
                    return(cousin);
                }

                // Looks like end of this depth... time to go forward and back to the end
                return(this.GetLastLeafAtDepth(m_traversalParameters.Root, new TreeNodePath(), this.CurrentDepthFromOrigin - 1));
            }


            // There were some siblings, see if we can find our next target
            return(new TreeEvalItem <TTreeNode>(nextClosestSibling, path.CopyAndSwapEndForSibling(nextClosestSiblingIndex)));
        }
Beispiel #3
0
        private TreeEvalItem <TTreeNode> GetNextRBFSCousin(TTreeNode curr, TreeNodePath path, int targetDepth)
        {
            // If we've gotten into an error state, or if we're attempting to go past root
            if (curr == null || curr == m_traversalParameters.Root)
            {
                return(null);
            }

            // Iterate over all siblings and build a stack of siblings for us to evaluate (popping will give us sibling closest to curr, instead of parent's index[0])
            var parent = m_traversalParameters.GetParentMethod(curr);

            if (parent == null)
            {
                return(null);
            }

            var siblingStack = new Stack <IndexTrackedNode>();
            int siblingIndex = 0;

            foreach (var sibling in m_traversalParameters.GetChildrenMethod(parent))
            {
                if (sibling == curr)
                {
                    break;
                }

                siblingStack.Push(new IndexTrackedNode(siblingIndex++, sibling));
            }

            // Evaluate from closest to curr back to index zero, and call GetlastLeafAtDepth, if we find a cousin at the target depth
            //  then that is the next BFS item to search
            while (siblingStack.Count > 0)
            {
                var next = siblingStack.Pop();
                TreeEvalItem <TTreeNode> cousinLeaf = this.GetLastLeafAtDepth(next.Node, path.CopyAndSwapEndForSibling(next.Index), targetDepth);
                if (cousinLeaf != null)
                {
                    return(cousinLeaf);
                }
            }

            // If no cousin is found, than recurse upwards, this will be evaluting parent as curr
            return(this.GetNextRBFSCousin(parent, path.CopyAndRemoveEnd(), targetDepth));
        }