我正在尝试在 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}
这将生成以下树:
这是一个好的开始,但并不完美。我想做的是:
- 移动节点标签,使它们不与边冲突;
- 使边在与父节点固定距离处弯曲,而不是在与子节点固定距离处弯曲;并且
- 每个边可以选择两个标签,以分离随机机会的结果(例如需求 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}