Beispiel #1
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="node"></param>
 public TreePlot(MCTSNodeStruct node)
 {
     rawRoot = node;
     //Stopwatch sw = Stopwatch.StartNew();
     (root, treeInfo) = DrawTreeNode.Layout(node);
     //Console.WriteLine("Layout time in ms:");
     //Console.WriteLine(sw.ElapsedMilliseconds);
     canvasHeight           *= superSample;
     canvasWidth            *= superSample;
     pointRadius            *= superSample;
     edgeWidth              *= superSample;
     leftMargin             *= superSample;
     rightMargin            *= superSample;
     topMargin              *= superSample;
     bottomMargin           *= superSample;
     rightHistogramWidth    *= superSample;
     bottomHistogramHeight  *= superSample;
     horisontalSpacing      *= superSample;
     verticalSpacing        *= superSample;
     titleMargin            *= superSample;
     tickFontSize           *= superSample;
     histogramTitleFontSize *= superSample;
     plotAreaHeight          = canvasHeight - topMargin - bottomMargin - bottomHistogramHeight - verticalSpacing - titleMargin;
     plotAreaWidth           = canvasWidth - leftMargin - rightMargin - rightHistogramWidth - 2 * horisontalSpacing;
     image = new Bitmap(canvasWidth / superSample, canvasHeight / superSample);
     Plot();
 }
Beispiel #2
0
        internal DrawTreeNode(DrawTreeNode parent, MCTSNodeStruct node, int depth, int siblingIndex, ref int identifier)
        {
            X           = -1.0f;
            Y           = (float)depth;
            id          = identifier;
            BranchIndex = parent is null ? -1 : parent.BranchIndex != -1 ? parent.BranchIndex : siblingIndex;
            identifier++;
            Children = new List <DrawTreeNode>();
            int childIndex = 0;

            // Sort children based on N so that heaviest subtree is always drawn leftmost.
            foreach (MCTSNodeStruct child in (from ind in Enumerable.Range(0, node.NumChildrenExpanded) select node.ChildAtIndexRef(ind)).OrderBy(c => - c.N))
            {
                Children.Add(new DrawTreeNode(this, child, depth + 1, childIndex, ref identifier));
                childIndex++;
            }

            Parent            = parent;
            mod               = 0.0f;
            change            = 0.0f;
            shift             = 0.0f;
            ancestor          = this;
            lmostSibling      = null;
            this.siblingIndex = siblingIndex;
            thread            = null;
        }
Beispiel #3
0
 internal DrawTreeNode LeftmostSibling()
 {
     if (lmostSibling is null && siblingIndex != 0)
     {
         lmostSibling = Parent.Children[0];
     }
     return(lmostSibling);
 }
Beispiel #4
0
        /// <summary>
        /// Calculate tree layout.
        /// </summary>
        internal static (DrawTreeNode, DrawTreeInfo) Layout(MCTSNodeStruct root)
        {
            DrawTreeInfo treeInfo = new DrawTreeInfo();
            int          id       = 0;
            DrawTreeNode drawRoot = new DrawTreeNode(null, root, 0, 0, ref id);

            drawRoot.FirstWalk();
            float      min           = drawRoot.SecondWalk(0.0f, float.MaxValue);
            float      maxX          = float.MinValue;
            float      maxDepth      = float.MinValue;
            List <int> nodesPerDepth = new List <int>();

            // Shift whole tree so that min x is 0.
            drawRoot.ThirdWalk(-min, treeInfo);
            return(drawRoot, treeInfo);
        }
Beispiel #5
0
        /// <summary>
        /// First tree walk (bottom-up) of Buckheim's layout algorithm.
        /// </summary>
        internal void FirstWalk()
        {
            if (Children.Count == 0)
            {
                X = siblingIndex != 0 ? LeftSibling().X + 1.0f : 0.0f;
            }
            else
            {
                DrawTreeNode defaultAncestor = Children[0];
                foreach (DrawTreeNode child in Children)
                {
                    child.FirstWalk();
                    defaultAncestor = child.Apportion(defaultAncestor);
                }

                ExecuteShifts();
                float        midPoint = (Children[0].X + Children[^ 1].X) / 2;
Beispiel #6
0
        /// <summary>
        /// Draw edges and nodes of the search tree.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="gfx"></param>
        /// <param name="penEdge"></param>
        /// <param name="brushRoot"></param>
        /// <param name="brushEven"></param>
        /// <param name="brushOdd"></param>
        internal void DrawTree(DrawTreeNode node, Graphics gfx, Pen penEdge, SolidBrush brushRoot, SolidBrush brushEven, SolidBrush brushOdd)
        {
            float      x;
            float      y;
            SolidBrush brush = node.BranchIndex == -1 ? brushRoot : node.BranchIndex % 2 == 0 ? brushEven : brushOdd;

            (x, y) = CanvasXY(node.X, node.Y);
            if (!(node.Parent is null))
            {
                float xParent;
                float yParent;
                (xParent, yParent) = CanvasXY(node.Parent.X, node.Parent.Y);
                gfx.DrawLine(penEdge, x, y, xParent, yParent);
            }
            foreach (DrawTreeNode child in node.Children)
            {
                DrawTree(child, gfx, penEdge, brushRoot, brushEven, brushOdd);
            }
            DrawNode(x, y, gfx, brush);
        }