我正在尝试使用森林创建“经典”决策树。我以前从未使用过森林,并且遇到了一些困难。不幸的是,我发现文档并不容易阅读。我找到了一个答案,让我对此有了一点了解(https://tex.stackexchange.com/a/251452/36836)。我对其进行了一些调整和修改。但是,我想进行以下进一步的更改(部分),如下图所示。
- 将节点标签(n_0、n_1 等)移至节点(框/圆圈)上方。
- 让分支从节点的东边开始(这样它们就不会干扰节点标签。
- 使节点(框/圆圈)变小(因为它们不再有内容)。
- 从末端移除三角形,并将结果 o_1、o_2 等直接放在边缘之后(三角形所在的位置)。
- 可能的话,改变顺序使得编号从上方而不是从下方开始,例如 n_1 应该是位于 n_2 和 n_3 之上的节点。
- 将所有设置移至前言中,以便它们应用于所有树(可能将其命名为“决策树”)。
\documentclass{article}
\usepackage{etex,forest}
\usetikzlibrary{shapes,snakes}
\tikzset{
decision/.style={rectangle, minimum height=10pt, minimum width=10pt, draw=black, fill=white, thick, inner sep=0pt},
chance/.style={circle, minimum width=10pt, draw=black, fill=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}
}
\forestset{
declare toks={optimality}{},
sub optimal/.style={
optimality={
node [midway, sloped]
}
},
declare toks={edge label below}{},
}
\begin{document}
\begin{forest}
my label/.style={
edge label={node[midway,above,font=\scriptsize,text width=1.5cm,align=left]{#1}}
},
for tree={
grow=0,
font=\scriptsize,
child anchor=west,
anchor=west,
text ragged,
inner sep=1mm,
edge={thick},
l sep+=15mm,
s sep+=5mm,
if n children=0{
before typesetting nodes={
label/.wrap pgfmath arg={right:#1}{content()},
content={},
leaf-chance,
},
}{},
edge path={
\noexpand\path[\forestoption{edge}]
(!u.parent anchor) -- ([xshift=-15mm].child anchor)\forestove{optimality} -- (.child anchor)\forestoption{edge label below}\forestoption{edge label};
},
}
[$n_0$,decision
[$n_1$,decision,my label={$s_1$, $s_2$}
[$o_1$,chance,my label=$s_1(n_1)$]
[$o_2$,decision,my label=$s_2(n_1)$]
]
[$n_2$,decision,my label={$s_3$, $s_4$}
[$o_3$,decision,my label=$s_3(n_2)$]
[$o_4$,decision,my label=$s_4(n_2)$]
]
[$n_3$,decision,my label={$s_5$, $s_6$}
[$o_5$,decision,my label=$s_5(n_3)$]
[$o_6$,decision,my label=$s_6(n_3)$]
]
]
\end{forest}
\end{document}
答案1
像这样?
编辑: 尝试使树代码稍微短一些
- 从你的 mwe 的序言来看,只有相关的包
forest
- 节点和边标签的样式定义为
for tree
选项 forest
标签样式在环境中移动- 向树形代码添加了注释以简短说明其含义
\documentclass[margin=3mm]{standalone}
\usepackage{forest}
\begin{document}
\begin{forest}
/tikz/every label/.append style={xshift=-1pt,inner sep=1pt,font=\footnotesize},
for tree={
grow'=east,
% node style
line width=0.4pt,
minimum size=2pt,
inner sep=2pt,
if n children=0{}{draw}, % <--- added
% anchors <------- solve basic problem
parent anchor=children,
child anchor=parent,
% distances of nodes
l sep=17mm, % <-- *l*: level distance
s sep=2mm, % <-- *s*: sibling distance between leaves
% edges
edge={draw},
edge path'={
(!u.parent anchor) -- ([xshift=-13mm].child anchor) -- (.child anchor)
},
% labels on edges
delay={
edge label/.wrap value={node[midway, inner sep=1pt,
font=\scriptsize, above]{#1}},
},
}, % end for tree
[ , label=$n_0$
[, label=$n_3$, edge label={$s_5,s_6$}
[$o_6$, edge label={$s_6(n_3)$}]
[$o_5$, edge label={$s_5(n_3)$}]
]
[ , label=$n_2$, edge label={$s_3,s_4$}
[$o_4$, edge label={$s_4(n_2)$}]
[$o_3$, edge label={$s_3(n_2)$}]
]
[ , label=$n_1$, edge label={$s_1,s_2$}
[$o_2$, edge label={$s_2(n_1)$}]
[$o_1$, edge label={$s_1(n_1)$}]
]
]
\end{forest}
\end{document}
答案2
\documentclass{article}
\usepackage{forest}
\forestset{
declare toks={elo}{},
my label/.style={
edge label={node[midway,above,text width=1.7cm,align=left]{#1}}
},
decision tree/.style={
for tree={
grow=east,
minimum size=2pt,
inner sep=2pt,
parent anchor=east,
child anchor=west,
l sep+=20mm,
s sep+=3mm,
edge path'={(!u.parent anchor) -- ([xshift=-18mm].child anchor)\forestove{elo} -- (.child anchor)},
}
}
}
\begin{document}
{\small
\begin{forest} decision tree
[,label=$n_0$,draw
[,label=$n_3$,draw ,my label={$s_5,s_6$}
[$o_6$, my label=$s_6(n_3)$]
[$o_5$, my label=$s_5(n_3)$]
]
[,label=$n_2$,draw, my label={$s_3,s_4$}
[$o_4$, my label=$s_4(n_2)$]
[$o_3$, my label=$s_3(n_2)$]
]
[,label=$n_1$,draw, my label={$s_1,s_2$}
[$o_2$, my label=$s_2(n_1)$]
[$o_1$, my label=$s_1(n_1)$]
]
]
\end{forest}}
\end{document}