森林:所有节点在同一层上水平均匀分布

森林:所有节点在同一层上水平均匀分布

在下面的树中,一些节点有多个父节点(从技术上讲,这违反了树的定义)。

具有多个父节点的树

因此,为了在森林包中创建树,我手动添加了从子节点到(其他)父节点的边。但是,由于森林认为每个节点最多属于一个父节点,因此节点现在分布不均匀。

我现在的问题是如何在水平方向上均匀分布每个级别的节点,以便例如底部节点{a,b,c,d} 位于中心。

这是我目前的代码:

\documentclass[12pt]{article}
\usepackage{forest}

\begin{document}
\begin{forest}
  for tree={
    ellipse,
    draw,
    inner sep=1.5pt,
    l*=1.75
  }
  [$\O$
    [$\{a\}$,name=a
      [$\{a{,}b\}$,name=ab
        [$\{a{,}b{,}c\}$,name=abc
          [$\{a{,}b{,}c{,}d\}$,name=abcd ]
        ]
        [$\{a{,}b{,}d\}$,name=abd ]
      ]
      [$\{a{,}c\}$,name=ac
        [$\{a{,}c{,}d\}$,name=acd ]
      ] 
      [$\{a{,}d\}$,name=ad ]
    ]
    [$\{b\}$,name=b
      [$\{b{,}c\}$,name=bc
        [$\{b{,}c{,}d\}$,name=bcd ]      
      ]
      [$\{b{,}d\}$,name=bd ]
    ]
    [$\{c\}$,name=c
      [$\{c{,}d\}$,name=cd ]
    ]
    [$\{d\}$,name=d
    ]
  ]
  \draw (b) edge (ab);
  \draw (c) edge (ac);
  \draw (c) edge (bc);
  \draw (d) edge (ad);
  \draw (d) edge (bd);
  \draw (d) edge (cd);
  \draw (ac) edge (abc);
  \draw (bc) edge (abc);
  \draw (ad) edge (abd);
  \draw (bd) edge (abd);
  \draw (ad) edge (acd);
  \draw (cd) edge (acd);
  \draw (bd) edge (bcd);
  \draw (cd) edge (bcd);
  \draw (abd) edge (abcd);
  \draw (acd) edge (abcd);
  \draw (bcd) edge (abcd);
\end{forest}
\end{document}

在此先感谢您的帮助!

答案1

正如 Lorenzo 和 cfr 指出的那样,使用该forest包似乎不是最简单的方法。相反,我通过手动创建 Hasse 图(再次感谢 Lorenzo)解决了这个问题,类似于这个问题使用TikZ:

节点间距均匀的树

这是我的代码:

\documentclass{article}
\usepackage{tikz}

\usetikzlibrary{shapes}

\begin{document}
\begin{tikzpicture}[scale=0.7,inner sep=2]
 \node[ellipse,draw=black](0) at (-3,10) {$\O$};

 \node[ellipse,draw=black](a) at (-7.5,8) {$\{a\}$};
 \node[ellipse,draw=black](b) at (-4.5,8) {$\{b\}$};
 \node[ellipse,draw=black](c) at (-1.5,8) {$\{c\}$};
 \node[ellipse,draw=black](d) at (1.5,8) {$\{d\}$};

 \node[ellipse,draw=black](ab) at (-10.5,6) {$\{a{,}b\}$};
 \node[ellipse,draw=black](ac) at (-7.5,6) {$\{a{,}c\}$};
 \node[ellipse,draw=black](ad) at (-4.5,6) {$\{a{,}d\}$};
 \node[ellipse,draw=black](bc) at (-1.5,6) {$\{b{,}c\}$};
 \node[ellipse,draw=black](bd) at (1.5,6) {$\{b{,}d\}$};
 \node[ellipse,draw=black](cd) at (4.5,6) {$\{c{,}d\}$};

 \node[ellipse,draw=black](abc) at (-9.75,4) {$\{a{,}b{,}c\}$};
 \node[ellipse,draw=black](abd) at (-5.25,4) {$\{a{,}b{,}d\}$};
 \node[ellipse,draw=black](acd) at (-0.75,4) {$\{a{,}c{,}d\}$};
 \node[ellipse,draw=black](bcd) at (3.75,4) {$\{b{,}c{,}d\}$};

 \node[ellipse,draw=black](abcd) at (-3,2) {$\{a{,}b{,}c{,}d\}$};

 \draw (0) -- (a);
 \draw (0) -- (b);
 \draw (0) -- (c);
 \draw (0) -- (d);
 
 \draw (a) -- (ab);
 \draw (a) -- (ac);
 \draw (a) -- (ad);
 \draw (b) -- (ab);
 \draw (b) -- (bc);
 \draw (b) -- (bd);
 \draw (c) -- (ac);
 \draw (c) -- (bc);
 \draw (c) -- (cd);
 \draw (d) -- (ad);
 \draw (d) -- (bd);
 \draw (d) -- (cd);
 
 \draw (ab) -- (abc);
 \draw (ab) -- (abd);
 \draw (ac) -- (abc);
 \draw (ac) -- (acd);
 \draw (ad) -- (abd);
 \draw (ad) -- (acd);
 \draw (bc) -- (abc);
 \draw (bc) -- (bcd);
 \draw (bd) -- (abd);
 \draw (bd) -- (bcd);
 \draw (cd) -- (acd);
 \draw (cd) -- (bcd);
 
 \draw (abc) -- (abcd);
 \draw (abd) -- (abcd);
 \draw (acd) -- (abcd);
 \draw (bcd) -- (abcd);

\end{tikzpicture}
\end{document}

答案2

我认为 amatrix of math nodes比 更简单(也更快!)forest,因为它试图避免edge与 s 交叉。例如,

\documentclass[tikz,border=10pt]{standalone}
% ateb: https://tex.stackexchange.com/a/714619/
\usetikzlibrary{matrix,shapes.geometric}
\begin{document}
\begin{tikzpicture}
  \matrix (h) [matrix of math nodes,row sep=10mm,column sep=-10pt,nodes={text width=15mm,align=center,inner xsep=0pt,ellipse,draw}]
  {
    &&&&& \O  \\
    & \{a\} && \{b\} &&&& \{c\} && \{d\}  \\
    \{a,b\} && \{a,c\} && \{a,d\} && \{b,c\} && \{b,d\} && \{c,d\} \\
    & \{a,b,c\} && \{a,b,d\} &&&& \{a,c,d\} && \{b,c,d\} \\
    &&&&& \{a,b,c,d\}\\
  };
  \foreach \j in {2,4,8,10}
  {
    \draw  (h-1-6.south) -- (h-2-\j.north);
    \draw  (h-4-\j.south) -- (h-5-6.north);
  }
  \foreach \j in {1,3,5} \draw (h-2-2.south) -- (h-3-\j.north);
  \foreach \j in {5,9,11} \draw (h-2-10.south) -- (h-3-\j.north);
  \foreach \j in {1,7,9} \draw (h-2-4.south) -- (h-3-\j.north);
  \foreach \j in {3,7,11} \draw (h-2-8.south) -- (h-3-\j.north);
  \foreach \j in {1,3,7} \draw (h-4-2.north) -- (h-3-\j.south);
  \foreach \j in {1,5,9} \draw (h-4-4.north) -- (h-3-\j.south);
  \foreach \j in {3,5,11} \draw (h-4-8.north) -- (h-3-\j.south);
  \foreach \j in {11,9,7} \draw (h-4-10.north) -- (h-3-\j.south);
\end{tikzpicture}
\end{document}

[由于 Okular 错误,图像被省略。]

来自社区:

结果

[请注意,我忘记了椭圆,而且“社区”太快了,所以图像没有绘制椭圆,尽管代码确实绘制了!]

相关内容