改进使用 TikZ/森林绘制的决策树

改进使用 TikZ/森林绘制的决策树

我正在尝试在 TeX 中创建决策树,目前使用的是 forest 包,该包在底层使用了 TikZ。TikZ 对我来说是黑魔法,因此 forest 包也是如此,但我找到了一个非常有用的代码片段,我正在尝试适应我的需求这里

以下是我需要帮助的决策树的示例:

\documentclass{article}
\usepackage{forest}
\tikzset{
    decision/.style={rectangle, minimum height=10pt, minimum width=10pt, draw=black, fill=green!30!white, thick, inner sep=0pt},
    chance/.style={circle, minimum width=10pt, draw=black, fill=red!30!white, thick, inner sep=0pt},
    leaf-chance/.style={isosceles triangle, minimum width=10pt, draw=black, thick, fill=white, inner sep=0pt, shape border rotate=180, outer sep=-\pgflinewidth}
}
\begin{document}
    \begin{forest}
       my edge label/.style={
         edge label = { node[auto, pos=1, anchor=north east, font=\scriptsize]{#1} }
       },
       my node label/.style={
         label = {\small{#1}}
       },
       for tree = {
         text ragged,
         grow         = 0,
         child anchor = west,
         anchor       = west,
         inner sep    = 1mm,
         edge         = { thick, draw = blue, rounded corners = 2pt },
         s sep+       = 5mm,
         l sep+       = 20mm,
         if n children = 0 {
           before typesetting nodes = {
             label/.wrap pgfmath arg = { [align = right, text width = 35pt] right:#1}{ content() },
             content                 = {},
             leaf-chance,
           },
         }{},
         edge path = {
           \noexpand\path[\forestoption{edge}]
           (!u.parent anchor) -- ([xshift=-22.5mm].child anchor) --  (.child anchor)\forestoption{edge label};
         }
       }
        [, decision, label = Price,
          [,decision, my node label = Amount ordered, my edge label = 8 \textdollar
            [,chance, my node label = Demand, my edge label = 1.000
              [,decision, my node label = Order more?, my edge label = {2.000, $p = 0,4$}
                [2.000, my edge label = No, tier = outcome]
                [4.000, my edge label = Yes, tier = outcome]
              ]
              [2.000, my edge label = {1.000, $p = 0,6$}, tier = outcome]
            ]
            [,chance, my node label=Demand, my edge label = 2.000
              [$-$1.000, my edge label = {1.000, $p = 0,6$}, tier = outcome]
              [7.000, my edge label = {2.000, $p = 0,4$}, tier = outcome]
            ]
          ]
          [,decision, my node label = Amount ordered, my edge label = 7 \textdollar
            [,chance, my node label = Demand, my edge label = 1.000
              [,decision, my node label = Order more?, my edge label = {2.000, $p = 0,7$}
                [1.000, my edge label = No, tier = outcome]
                [2.000, my edge label = Yes, tier = outcome]
              ]
              [1.000, my edge label = {1.000, $p = 0,3$}, tier = outcome]
            ]
            [,chance, my node label=Demand, my edge label = 2.000
              [$-$2.000, my edge label = {1.000, $p = 0,3$}, tier = outcome]
              [5.000, my edge label = {2.000, $p = 0,7$}, tier = outcome]
            ]
          ]
        ]
    \end{forest}
\end{document}

这将生成以下树:

Example output

这是一个好的开始,但并不完美。我想做的是:

  1. 移动节点标签,使它们不与边冲突;
  2. 使边在与父节点固定距离处弯曲,而不是在与子节点固定距离处弯曲;并且
  3. 每个边可以选择两个标签,以分离随机机会的结果(例如需求 1000 与 2000)和相应的概率。

我尝试过几次,但最终一无所获;我对 TikZ 一点也不了解,感觉就像在黑暗中盲目摸索。任何帮助、提示、指示等都将不胜感激 --- 我也不拘泥于使用森林,所以如果有更好的软件包来创建决策树,请务必告诉我。

谢谢你!

答案1

谢谢你的澄清!那这个怎么样?现在my edge label有两个参数,一个是上面的文本,另一个是下面的文本。

\documentclass{article}
\usepackage{forest}
\tikzset{
    decision/.style={rectangle, minimum height=10pt, minimum width=10pt,
    draw=black, fill=green!30!white, thick, inner sep=0pt},
    chance/.style={circle, minimum width=10pt, draw=black, fill=red!30!white, thick, inner sep=0pt},
    leaf-chance/.style={isosceles triangle, minimum width=10pt, draw=black, thick, fill=white, inner sep=0pt, shape border rotate=180, outer sep=-\pgflinewidth}
}
\begin{document}
    \begin{forest}
       my edge label/.style n args={2}{
         edge label = { node[auto, pos=1, anchor=east,align=right,text
         depth=0.25ex,text height=1ex,yshift=-1ex,
         font=\scriptsize]{#1\\#2}},
       },
       my node label/.style={
         label={[font=\small]right:#1}
       },
       for tree = {
         text ragged,
         grow         = 0,
         child anchor = west,
         anchor       = west,
         inner sep    = 1mm,
         edge         = { thick, draw = blue, rounded corners = 2pt },
         s sep+       = 5mm,
         l sep+       = 20mm,
         if n children = 0 {
           before typesetting nodes = {
             label/.wrap pgfmath arg = { [align = right, text width = 35pt] right:#1}{ content() },
             content                 = {},
             leaf-chance,
           },
         }{},
         edge path = {
           \noexpand\path[\forestoption{edge}]
           (!u.parent anchor) -- ([xshift=5mm]!u.parent anchor |- .child anchor) --  (.child anchor)\forestoption{edge label};
         }
       }
        [, decision, label =right: Price,
          [,decision, my node label =Amount ordered, my edge label={8
          \textdollar}{}
            [,chance, my node label = Demand, my edge label={1.000}{}
              [,decision, my node label=Order more?, my edge label={2.000}{$p = 0,4$}
                [2.000, my edge label={No}{}, tier = outcome]
                [4.000, my edge label={Yes}{}, tier = outcome]
              ]
              [2.000, my edge label={1.000}{$p = 0,6$}, tier = outcome]
            ]
            [,chance, my node label=Demand, my edge label={2.000}{}
              [$-$1.000, my edge label={1.000}{$p = 0,6$}, tier = outcome]
              [7.000, my edge label={2.000}{$p = 0,4$}, tier = outcome]
            ]
          ]
          [,decision, my node label=Amount ordered, my edge label={7
          \textdollar}{}
            [,chance, my node label=Demand, my edge label={1.000}{}
              [,decision, my node label=Order more?, my edge label={2.000}{$p = 0,7$}
                [1.000, my edge label={No}{}, tier = outcome]
                [2.000, my edge label={Yes}{}, tier = outcome]
              ]
              [1.000, my edge label={1.000}{$p = 0,3$}, tier = outcome]
            ]
            [,chance, my node label=Demand, my edge label={2.000}{}
              [$-$2.000, my edge label={1.000}{$p = 0,3$}, tier = outcome]
              [5.000, my edge label={2.000}{$p = 0,7$}, tier = outcome]
            ]
          ]
        ]
    \end{forest}
\end{document}

enter image description here

相关内容