如何重新排列森林树?

如何重新排列森林树?

前

我需要按照与该草图类似的配置来排列上述森林树。

我该如何安排节点,使得“0”边直接指向南方,而“1”边与其成直角并直接指向东方?

我需要的是对于所有具有“0”前缀的节点都是相同的(即 0,00,000,0000)

任何帮助都将非常有帮助,我完全不知所措。

另外,我需要添加分隔水平线和右侧的注释,我猜是用 tikz 来实现的。

后

% not sure about these colours!
\definecolor{c1}{HTML}{FF7F00}
\definecolor{c2}{HTML}{048BA8}
\definecolor{c3}{HTML}{16DB93}
\definecolor{c4}{HTML}{EFEA5A}
\definecolor{c5}{HTML}{F29E4C}
\definecolor{c6}{HTML}{256EFF}
\definecolor{c7}{HTML}{46237A}


\scalebox{1.35}{
\begin{forest}
rt/.style={draw=green,line width=1pt},
peer/.style={draw=blue!60,edge={blue!60,line width=0.7pt}},
peerleaf/.style={edge={blue!60,line width=0.7pt}},
self/.style={draw=blue,fill=blue,edge={blue,line width=1pt}},
selfpeer/.style={draw=blue,line width=1pt,edge={blue,line width=1pt}},
unused/.style={draw=blue!20,edge={blue!20,line width=0.7pt}},
[{},grow=east, rt,for tree={circle,draw, l sep=20pt}
  [{},grow=east,selfpeer,edge label={node[midway,left] {0}}
    [{},grow=east,selfpeer,edge label={node[midway,left] {0}}
      [{},grow=east,selfpeer,edge label={node[midway,left] {0}}
        [{},grow=east,self,edge label={node[midway,left] {0}}]
        [{},grow=east,draw=c3,fill=c3,peerleaf,edge label={node[midway,right] {1}}]
      ]
      [{},grow=east,peer,edge label={node[midway,right] {1}}
        [{},grow=east,draw=c4,fill=c5,peerleaf,edge label={node[midway,left] {0}}]
        [{},grow=east,draw=c4,fill=c4,peerleaf,edge label={node[midway,right] {1}}]
      ]
    ]
    [{},grow=east,peer,edge label={node[midway,right] {1}} 
      [{},grow=east,peer,edge label={node[midway,left] {0}}
        [{},grow=east,draw=c1,fill=c1,peerleaf,edge label={node[midway,left] {0}}]
        [{},grow=east,unused,edge label={node[midway,right] {1}}]
      ]
      [{},grow=east,peer,edge label={node[midway,right] {1}}
        [{},grow=east,unused,edge label={node[midway,left] {0}}]
        [{},grow=east,draw=c2,fill=c2,peerleaf,edge label={node[midway,right] {1}}]
      ]
    ] 
  ]
  [{},grow=east,grow=east,peer,edge label={node[midway,right] {1}}
    [{},grow=east,peer,edge label={node[midway,left] {0}}
      [{},grow=east,peer,edge label={node[midway,left] {0}}
        [{},grow=east,unused,edge label={node[midway,left] {0}}]
        [{},grow=east,draw=c6,fill=c6,peerleaf,edge label={node[midway,right] {1}}]
      ]
      [{},grow=east,peer,edge label={node[midway,right] {1}}
        [{},grow=east,unused,edge label={node[midway,left] {0}}]
        [{},grow=east,draw=c7,fill=c7,peerleaf,edge label={node[midway,right] {1}}]
      ]
    ]
    [{},grow=east,unused,edge label={node[midway,right] {1}} 
      [{},grow=east,unused,edge label={node[midway,left] {0}}
        [{},grow=east,unused,edge label={node[midway,left] {0}}]
        [{},grow=east,unused,edge label={node[midway,right] {1}}]
      ]
      [{},grow=east,unused,edge label={node[midway,right] {1}}
        [{},grow=east,unused,edge label={node[midway,left] {0}}]
        [{},grow=east,unused,edge label={node[midway,right] {1}}]
      ]
    ]
  ] 
]
\end{forest}
}

答案1

谢谢塞巴斯蒂亚诺。

使用游戏包裹:

\documentclass[border=1mm]{standalone}
\usepackage{istgame}

\begin{document}

\begin{istgame}[every node/.style={fill=white,circle,inner sep=0pt,minimum size=5pt}]
\draw (-1,-1.45) --(7.5,-1.45);
\draw (-1,-3.95) --(7.5,-3.95);
\draw (-1,-6.2) --(7.5,-6.2);
%
\setistSolidNodeStyle{10pt}
\setistgrowdirection'{east}
\setistOvalNodeStyle{.8cm}
\xtShowEndPoints[oval node]
%
\xtdistance{25mm}{30mm}
\istrooto(0)<180>{\tiny Root}
\istb<grow=0>[draw=blue]{1}[bl]{}[center]
\istb<grow=-90>[draw=red]{0}[b]{}[center]
 \endist
 %
\xtdistance{20mm}{20mm}
\istrooto(1)(0-1){}
\istb[draw=blue]{1}[bl]{}[center]
\istb{0}[al]{}[center] 
\endist
%
\xtdistance{20mm}{20mm}
\istrooto(2)(1-1){}
\istb{1}[bl]{}[center]
\istb[draw=blue]{0}[al]{}[center] 
\endist
%
 \xtdistance{25mm}{20mm}
\istrooto(3)(0-2)
\istb<grow=14>{1}[bl]{}[center]
\istb<grow=-14>{0}[al]{}[center] 
\istb<grow=-90>[draw=red]{0}[b]{}[center]
 \endist
 %
\xtdistance{20mm}{10mm}
 \istrooto(4)(3-3)
\istb<grow=0>[draw=none]{1}[bl]{}[center]
\istb<grow=-90>[draw=red]{0}[b]{}[center]
 \endist
 %
 \xtTimeLineH[draw=none](0){-8}{0}{root}[font=\small]
 \xtTimeLineH[draw=none](3){-8}{0}{level1}[font=\small]
 \xtTimeLineH[draw=none](4){-8}{0}{level2}[font=\small,yshift=1cm]
 \xtTimeLineH[draw=none](4){-8}{0}{level3}[font=\small,yshift=-1.2cm]
\end{istgame}

\end{document}

输出:

在此处输入图片描述

答案2

我建议用另一种方法绘制你的第一张图片istgame在某些方面,包装与包装类似forest。这里有一个起点,我认为你可以慢慢地画出你的第一幅图。

在此处输入图片描述

\documentclass[a4paper,12pt]{article}
\usepackage{xcolor}
\usepackage{istgame}
\usepackage{amssymb}
\begin{document}
\begin{istgame}\setistSolidNodeStyle[blue]{10pt}
\setistgrowdirection'{east}
\setistOvalNodeStyle{.5cm}
\xtShowEndPoints[oval node]
\istrooto(0){}+{10mm}..{5cm}+
\istb[draw=blue]{\textcolor{blue}{1}}[al]
\istb[draw=blue]{\textcolor{blue}{0}}[bl]
\endist
\xtdistance{20mm}{20mm}
\istrooto(1)(0-1){}
\istb[draw=blue]{\textcolor{blue}{1}}[al]{}[center]
\istb[draw=blue]{\textcolor{blue}{0}}[bl]{}[center] 
\endist
\xtdistance{20mm}{20mm}
\istrooto(2)(0-2){}
\istb[draw=blue]{\textcolor{blue}{1}}[al]{}[center]
\istb[draw=blue]{\textcolor{blue}{0}}[bl]{}[center] 
\xtdistance{20mm}{20mm}
\istrooto(3)(1-1){}
\istb[draw=blue]{\textcolor{blue}{1}}[al]{}[center]
\istb[draw=blue]{\textcolor{blue}{0}}[bl]{}[center] 
\endist
\end{istgame}
\end{document}

在这张图片中,您可以看到圆圈可以用特定的代码来着色。

在此处输入图片描述

答案3

这是一个forest解决方案。它既不通用也不是最佳的,但它有效。请参阅代码中的注释。

\documentclass{standalone}
\usepackage{forest}
\forestset{
  % The idea is to first generate the tree and then rearrange the nodes.  We
  % need to then set various options for the nodes.  For some it makes sense to
  % set them as soon as the tree is generated, for others it is better to wait
  % until after rearrangement. These two keylists make this process
  % conceptually clean.  (The other option would be to use "delay", but
  % prepending is intertwined with delay cycles, so if we just used "delay", we
  % would need to compute how much delay is needed.)
  declare keylist={after generating tree}{},
  declare keylist={after reordering tree}{},
  typeset nodes stage/.style={
    process keylist=after generating tree,
    process keylist=after reordering tree,
    for root'=typeset nodes,
  },
  generate binary tree/.style={% #1 = number of levels
    if={#1>0}{
      append={[,generate binary tree/.process=n{#1-1}]},
      append={[,generate binary tree/.process=n{#1-1}]},
    }{}
  },
  pull left branches to the root/.style={
    % create an invisible root node first
    replace by={[,append,phantom]},
    % after the new root is created, iteratively prepend the first children to it
    delay={
      if n children={0}{}{for 1=pull left branch to the root},
    },
  },
  pull left branch to the root/.style={
    % a temporary name of the node to be pulled to the root
    alias=pull@temp,
    % pull
    for root={prepend={pull@temp}},
    % iterate
    if n children={0}{}{for 1=pull left branch to the root},
  },
  % Computes minimal and maximal x --- this is used both for drawing both the
  % horizontal lines and the level labels.  It must be executed on the phantom
  % root after x and y of all nodes were already computed.
  setup x for horizontal dividing line/.style={
    % {>...} below are argument processor expressions (manual 3.13) equivalent
    % to pgfmath "x() + min_x()" and "x() + max_x()".  ".min" and ".max" are
    % aggregate functions (3.14); here we set them loose on descendants (of the root)
    tempdimc/.min={>O2w2+d{x}{min x}{##1+##2}}{descendants},
    tempdimd/.max={>O2w2+d{x}{max x}{##1+##2}}{descendants},
  },
  horizontal dividing line/.style={
    % "y() + max_y()" for the tree of one of 00...00 nodes
    tempdima/.max={>O2w2+d{y}{max y}{##1+##2}}{tree},
    % "y() + min_y()" for the tree of the upper 00...00 node
    for next={tempdimb/.min={>O2w2+d{y}{min y}{##1+##2}}{tree}},
    % find the middle of these
    tempdima+/.register=tempdimb,
    tempdima:=2,
    % and draw the line: \draw (tempdimc,tempdima) -- (tempdimd,tempdima);
    % tempdimc and tempdimd were set by "setup x ..."
    tikz+/.process=R3w3{tempdima}{tempdimc}{tempdimd}{\draw (##2,##1) -- (##3,##1);},
  },
  level label/.style={
    % put the level label at (tempdimd,y)
    % tempdimd was set by "setup x ..."; y is the y position of the node (an option)
    tikz+/.process=ROw2{tempdimd}{y}{\node[anchor=west,font=\tiny] at (##1,##2) {#1};},
  },
}


\begin{document}
\begin{forest}
  generate binary tree=3,
  after generating tree={
    for tree={
      circle, draw,
      % Redefine the edge to the parent so that it is labelled. The label is
      % computed automatically; n = the child number (1 or 2), by compute
      % "n()-1" using the argument processor.
      edge path'/.process=Ow1+nw1{n}{#1-1}{
        (.child anchor) --
        node[fill=white,font=\noexpand\tiny,inner sep=1pt]{#1}
        (!u.parent anchor);
      },
    },
    pull left branches to the root,
    after reordering tree={
      % By using "for root'", we can set options for the phantom root created
      % when reordering the tree.
      for root'={
        % everything, including the phantom root, grows to the east
        for tree={grow=east},
        % widen the vertical gap between the leftmost nodes a bit
        s sep*=2,
        % Cleanly separate the subtrees of the leftmost nodes.
        for children={fit=band},
        % This stuff can only be done once x and y coordinates are known:
        before drawing tree={
          setup x for horizontal dividing line,
          % we walk through the leftmost nodes, top-down 
          for last={
            % the very top gets a special label, and no horizontal divide
            level label=root,
            for preceding siblings={
              % automatically figure out the level: "n'" is the child number,
              % counting from the last child
              level label/.process=Ow+nw{n'}{#1-1}{level #1},
              horizontal dividing line,
              % the vertical lines and zeros between the leftmost nodes
              % we'll use the "x" coordinate of the node, and "tempdima" is the
              % register holding "y" of the horizontal divide line we had just
              % drawn.
              tikz+/.process=ORw2{x}{tempdima}{
                % line from this node to the upper one (n=next)
                \draw[red] () -- (!n);
                % at (x,tempdima)
                \node[font=\tiny,fill=white,inner sep=1pt] at (#1,#2) {0};
              },
            }
          }
        }
      },
    },
  },
  % This is the starting tree :-)
  []
\end{forest}\hspace{2em}

\end{document}

那个树

答案4

再次尝试使用游戏包裹:

在此处输入图片描述

\documentclass[border=2pt]{standalone}

\usepackage{istgame}

% not sure about these colours!
\definecolor{c1}{HTML}{FF7F00}
\definecolor{c2}{HTML}{048BA8}
\definecolor{c3}{HTML}{16DB93}
\definecolor{c4}{HTML}{EFEA5A}
\definecolor{c5}{HTML}{F29E4C}
\definecolor{c6}{HTML}{256EFF}
\definecolor{c7}{HTML}{46237A}

\begin{document}
    
\begin{istgame}[draw=blue,text=blue,font=\sffamily\scriptsize]
\tikzset{every node/.style={fill=white}} % action labels with white background
\tikzset{every ellipse node/.style={circle,draw=blue,minimum size=2em}}
\tikzset{xx/.style={circle,draw,fill,minimum size=2em}} % for colored terminal nodes
\setistmathTF*000{sffamily}
\setistgrowdirection'{east}
\xtShowEndPoints[oval node]
\def\xdist{50mm}
%% root
\istrooto(A){Root}
  \istb<grow=0,level distance=.4*\xdist>{1}
  \istb<grow=-90,level distance=.7*\xdist>{0}[pos=.7]
  \endist
\xtdistance{.4*\xdist}{.4*\xdist}
\istrooto(Aa)(A-1)
  \istb{1}
  \istb{0}
  \endist
\xtdistance{.4*\xdist}{.2*\xdist}
\istrooto(Ab)(Aa-1)
  \istb{1}
  \istb{0}
  \endist
\istrooto(Ac)(Aa-2)
  \istb{1}
  \istb{0}
  \endist
%% level 1
\istrooto(0)(A-2)
  \istb<grow=0,level distance=.4*\xdist>{1}
  \istb<grow=-90,level distance=.4*\xdist>{0}[pos=.6]
  \endist
\xtdistance{.4*\xdist}{.2*\xdist}
\istrooto(0a)(0-1)
  \istb{1}{c4}[[xx,c4,text=black]center] % c4
  \istb{0}{}[[xx,c3]center]              % c3
  \endist
%% level 2 & level 3
%\xtdistance{.4*\xdist}{.4*\xdist}
\istrooto(00)(0-2)
  \istb<grow=0,level distance=.4*\xdist>{1}{}[[xx,c2]center]    % c2
  \istb<grow=-90,level distance=.35*\xdist>{0}{}[[xx,c1]center] % c1
  \endist
%% level lines
\coordinate(X0)at($(A)!.65!(0)$);
\coordinate(X1)at($(0)!.57!(00)$);
\coordinate(X2)at($(00)!.5!(00-2)$);
\xtTimeLineH'[solid](X0){1}{-8}%{level 1}[r]
\xtTimeLineH'[solid](X1){1}{-8}%{level 2}[r]
\xtTimeLineH'[solid](X2){1}{-8}%{level 3}[r]
%% level texts
\xtTimeLineH'[draw=none](A){1}{-8}{root}[r]
\xtTimeLineH'[draw=none](0){1}{-8}{level 1}[r]
\xtTimeLineH'[draw=none](00){1}{-8}{level 2}[r]
\xtTimeLineH'[draw=none](00-2){1}{-8}{level 3}[r]
\end{istgame}

\end{document}

相关内容