Я пытался создать деревья решений в формате подрисунка, как показано ниже, но независимо от того, какой интервал я пробовал, в какой-то момент всегда есть перекрывающиеся узлы. В примере ниже у меня есть две копии одного и того же дерева в качестве примера. Как я могу это исправить с помощью пакета tikz? Кроме того, есть ли какой-либо совет, который я мог бы дать для рисования немного больших деревьев с помощью пакета tikz? Это очень расстраивает, потому что я чувствую, что я просто меняю расстояния уровня/родственников случайным образом, чтобы попытаться заставить все работать...
\documentclass{book}
\usepackage{tikz}
\usepackage{amsmath,amssymb,amstext,amsthm}
\usepackage{subcaption}
\begin{document}
\begin{figure}
\centering
\begin{subfigure}[h]{0.475\textwidth}
\centering
\begin{tikzpicture}[scale=0.6, level distance=25mm,
level 1/.style={sibling distance=80mm},
level 2/.style={sibling distance=50mm},
level 3/.style={sibling distance=30mm}]
\node[circle, draw]{$x\smash{_1}$}
child{node[circle, draw]{$x\smash{_2}$}
child{node[circle, draw]{$x\smash{_4}$}
child{node[rectangle, draw]{$x\smash{_1} \gets 1$}}
child{node[rectangle, draw]{$x\smash{_2} \gets 1$}}
}
child{node[circle, draw]{$x\smash{_4}$}
child{node[rectangle, draw]{$x\smash{_1} \gets 1$}}
child{node[rectangle, draw]{$x\smash{_4} \gets 0$}}
}
}
child{node[circle, draw]{$x\smash{_3}$}
child{node[circle, draw]{$x\smash{_2}$}
child{node[rectangle, draw]{$\begin{aligned} x\smash{_1} &\gets 0 \\ x\smash{_3} &\gets 1 \end{aligned}$}}
child{node[rectangle, draw]{$\begin{aligned} x\smash{_1} &\gets 0 \\ x\smash{_2} &\gets 0 \end{aligned}$}}
}
child{node[circle, draw]{$x\smash{_4}$}
child{node[rectangle, draw]{$x\smash{_4} \gets 1$}}
child{node[rectangle, draw]{$x\smash{_3} \gets 0$}}
}
}
;
\end{tikzpicture}
\caption{A Tree}
\end{subfigure}
\begin{subfigure}[h]{0.475\textwidth}
\centering
\begin{tikzpicture}[scale=0.6, level distance=25mm,
level 1/.style={sibling distance=80mm},
level 2/.style={sibling distance=50mm},
level 3/.style={sibling distance=30mm}]
\node[circle, draw]{$x\smash{_1}$}
child{node[circle, draw]{$x\smash{_2}$}
child{node[circle, draw]{$x\smash{_4}$}
child{node[rectangle, draw]{$x\smash{_1} \gets 1$}}
child{node[rectangle, draw]{$x\smash{_2} \gets 1$}}
}
child{node[circle, draw]{$x\smash{_4}$}
child{node[rectangle, draw]{$x\smash{_1} \gets 1$}}
child{node[rectangle, draw]{$x\smash{_4} \gets 0$}}
}
}
child{node[circle, draw]{$x\smash{_3}$}
child{node[circle, draw]{$x\smash{_2}$}
child{node[rectangle, draw]{$\begin{aligned} x\smash{_1} &\gets 0 \\ x\smash{_3} &\gets 1 \end{aligned}$}}
child{node[rectangle, draw]{$\begin{aligned} x\smash{_1} &\gets 0 \\ x\smash{_2} &\gets 0 \end{aligned}$}}
}
child{node[circle, draw]{$x\smash{_4}$}
child{node[rectangle, draw]{$x\smash{_4} \gets 1$}}
child{node[rectangle, draw]{$x\smash{_3} \gets 0$}}
}
}
;
\end{tikzpicture}
\caption{B Tree}
\end{subfigure}
\caption{Caption}
\label{datftt}
\end{figure}
\end{document}
решение1
В конечном счете, существует минимальная ширина деревьев, которая возникает из текста внутри листовых (конечных) узлов. Для обоих деревьев вы можете видеть, что размещение всех x_n <- 1
результатов от конца к концу уже занимает более половины ширины текста. Если вы хотите заставить эти деревья располагаться рядом, у вас будут либо перекрывающиеся деревья (как вы это делаете сейчас), либо перекрывающиеся узлы. Ни один из вариантов не является элегантным...
Эту минимальную ширину можно немного скорректировать, установив меньший размер шрифта для нижних уровней, чтобы они занимали меньше места при размещении рядом. Этого можно добиться с помощью level n/.style={font=\footnotesize}
.
Вы также упоминаете, что вам приходится постоянно использовать метод проб и ошибок для корректировки расстояний между соседями. Причина в том, что стандартный алгоритм построения дерева в TiкZ имеет очень мало предвидения. Он видит, что на следующем уровне есть n
узлы, и размещает их в соответствии с расстоянием между ними, но он понятия не имеет, есть ли у этих узлов еще много узлов под ними, увеличивая эффективную «ширину» узла.
Это можно исправить с помощьюgraph drawing
библиотеку от TiкZ. Он предлагает гораздо больше алгоритмов для автоматического размещения узлов, что упрощает рисование.графики
намного проще. Я включил пример, который показывает, как использовать библиотеку рисования графиков:
\documentclass{book}
\usepackage{tikz}
\usetikzlibrary{
graphs,
graphdrawing,
}
\usegdlibrary{trees}
\usepackage{amsmath,amssymb,amstext,amsthm}
\usepackage{subcaption}
\begin{document}
\begin{figure}
\centering
\begin{subfigure}[b]{\linewidth}
\centering
\tikz \graph [
tree layout,
nodes={
draw,
circle,
},
level 3/.style={
font=\small,
},
level 4/.style={
nodes={
rectangle,
font=\footnotesize,
}
}
] {
"\(x_{}\)"
-> {
"\(x_{1}\)"
-> {
"\(x_{11}\)"
-> {
"\(x_{111}\)",
"\(x_{112}\)"
},
"\(x_{12}\)"
-> {
"\(x_{121}\)",
"\(x_{122}\)"
}
},
"\(x_{2}\)"
-> {
"\(x_{21}\)"
-> {
"\(x_{211}\)",
"\(x_{212}\)"
},
"\(x_{22}\)"
-> {
"\(x_{221}\)",
"\(x_{222}\)"
}
}
}
};
\caption{Tree \(x\)}
\end{subfigure}
\begin{subfigure}[b]{\linewidth}
\centering
\tikz \graph [
tree layout,
nodes={
draw,
circle,
},
level 3/.style={
font=\small,
},
level 4/.style={
nodes={
rectangle,
font=\footnotesize,
}
}
] {
"\(y_{}\)"
-> {
"\(y_{1}\)"
-> {
"\(y_{11}\)"
-> {
"\(y_{111}\)",
"\(y_{112}\)"
},
"\(y_{12}\)"
-> {
"\(y_{121}\)",
"\(y_{122}\)"
}
},
"\(y_{2}\)"
-> {
"\(y_{21}\)"
-> {
"\(y_{211}\)",
"\(y_{212}\)"
},
"\(y_{22}\)"
-> {
"\(y_{221}\)",
"\(y_{222}\)"
}
}
}
};
\caption{Tree \(y\)}
\end{subfigure}
\caption{My awesome captions for trees!}
\label{fig:trees}
\end{figure}
\end{document}
и вывод: