tikz의 정수 프로그래밍 문제에 대한 분기 및 바인딩 프로세스를 보여주는 트리를 만들려고 합니다. 정확히 내가 원하는 방식으로 첫 번째 수준의 트리를 만들 수 있었지만 라텍스가 두 번째 수준의 트리를 컴파일하지 못했습니다. 이것이 제가 해결할 수 있는 유일한 방법이기 때문에 내 코드가 매우 제대로 최적화되지 않았는지 잘 모르겠습니다. 지저분한 코드는 내가 잘못하고 있는 부분을 정확히 찾아내기 어렵다는 것을 의미합니다.
누구든지 코드를 정리하여 대부분의 노드 세부 정보가 사전 정의에 있도록 하는 방법을 보여주거나 두 번째 트리에서 내가 잘못되는 부분을 보여줄 수 있다면 좋을 것입니다.
첫 번째 수준의 코드:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calc, shapes}
\begin{document}
\begin{figure}
\centering
\begin{tikzpicture}[
scale = 1.5, transform shape, thick,
tree node/.style = {align=center, inner sep=0pt, text centered, font =
\scriptsize},
S/.style = {draw, circle, minimum size = 8mm, top color=white, bottom
color=blue!20},
grow = down, % alignment of characters
level 1/.style = {sibling distance=3cm},
level 2/.style = {sibling distance=4cm},
level 3/.style = {sibling distance=2cm},
level distance = 1.25cm]
\node [S, label={[font = \scriptsize]10:950}, label={[font =
\scriptsize]170:1055.56}] {$S$}
child{node [S, label={[font = \scriptsize]10:950}, label={[font =
\scriptsize]170:1000}] {$S_1$}edge from parent node[above left, font =
\scriptsize] {$x \leq 5$}}
child{node [S, label={[font = \scriptsize]10:950}, label={[font =
\scriptsize]170:1033}]
{$S_2$} edge from parent node[above right, font = \scriptsize] {$x \geq
6$}};
\end{tikzpicture}
\end{figure}
\end{document}
컴파일에 실패한 첫 번째 및 두 번째 수준의 코드:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calc, shapes}
\begin{document}
\begin{figure}
\begin{tikzpicture}[
scale = 1.5, transform shape, thick,
tree node/.style = {align=center, inner sep=0pt, text centered, font =
\scriptsize},
S/.style = {draw, circle, minimum size = 8mm, top color=white, bottom
color=blue!20},
grow = down, % alignment of characters
level 1/.style = {sibling distance=3cm},
level 2/.style = {sibling distance=4cm},
level 3/.style = {sibling distance=2cm},
level distance = 1.25cm]
\node [S, label={[font = \scriptsize]10:950}, label={[font =
\scriptsize]170:1055.56}] {$S$}
child{node [S, label={[font = \scriptsize]10:950}, label={[font =
\scriptsize]170:1000}] {$S_1$} edge from parent node[above left, font =
\scriptsize] {$x \leq 5$}}
child{node [S, label={[font = \scriptsize]10:950}, label={[font =
\scriptsize]170:1033}]
{$S_2$} edge from parent node[above right, font = \scriptsize] {$x
\geq 6$}
child{node [S, label={[font = \scriptsize]10:950}, label={[font
= \scriptsize]170:1033}]
{$S_2,1$} edge from parent node[above right, font = \scriptsize]
{$x \leq 1$}
child{node [S, label={[font = \scriptsize]10:950}, label={[font
= \scriptsize]170:1033}]
{$S_2,2$} edge from parent node[above right, font = \scriptsize]
{$x \geq 2$}};
\end{tikzpicture}
\end{figure}
\end{document}
미리 감사드립니다!
편집: 내가 만들려고 하는 것과 같은 가지 및 경계 트리
답변1
나는 전문적인 나무 그리기 패키지 중 하나를 사용할 것입니다. 좀 더 구체적으로 말하자면, forest
or 를 사용 하고 실패할 경우 tikz-qtree
. 이렇게 하면 트리를 매우 간결하게 지정할 수 있으며 트리의 형식이 일관되게 유지되도록 간단하고 쉽게 확인할 수 있습니다.
Forest의 경우 패키지는 많은 레이아웃 작업을 수행하지만 레이블은 이러한 방식으로 처리되지 않으므로 이 특별한 이점은 이 특정 종류의 나무에 큰 이점이 아닐 수 있습니다.
branch and bound
다음은 Forest의 스타일을 정의하는 예입니다 . 트리에 적용하면 다음과 같은 일이 발생합니다.
tree node
, 트리의 모든 노드에 적용되며 내용은 수학 모드로 설정됩니다S
.thick
가장자리도 마찬가지입니다
thick
.가지와 레벨의 간격을 넓히기 위해 약간의 공간이 나무에 추가됩니다.
트리가 구문 분석된 후 각 노드의 내용은 각 콜론에서 분할됩니다
<left label>:<node content>:<right label>:<edge label>
.- 첫 번째 콜론 앞 부분이 왼쪽 라벨(
170
)이 됩니다. 다음 부분은 기본 노드 콘텐츠로 설정됩니다(tree node
수학 모드 등에서). 세 번째 부분은 오른쪽 라벨(10
)로 설정됩니다. 마지막 부분은 가지의 레이블이 됩니다. 왼쪽 가지의 경우 중간점 왼쪽, 오른쪽 부분의 경우 오른쪽입니다.
- 첫 번째 콜론 앞 부분이 왼쪽 라벨(
모서리 라벨의 내용은 텍스트 모드(
text branch labels
) 또는 수학 모드(maths branch labels
)에서 설정할 수 있습니다.다음 중 하나를 사용하여 접두사와 접미사를 추가할 수 있습니다.
set branch labels={<left branch prefix>}{<left branch suffix>}{<right branch prefix>}{<right branch suffix>}
set maths branch labels={<left branch prefix>}{<left branch suffix>}{<right branch prefix>}{<right branch suffix>}
set text branch labels={<left branch prefix>}{<left branch suffix>}{<right branch prefix>}{<right branch suffix>}
나무의 각 잎 아래에 수평선이 그려집니다.
그런 다음 레벨에 따라 가장자리 레이블을 변경하기 위해 주석을 고려하여 편집된 두 번째 트리를 지정할 수 있습니다.
\begin{forest}
branch and bound,
where level=1{
set branch labels={x\leq}{}{x\geq}{},
}{
if level=2{
set branch labels={}{\geq y}{}{\leq y},
}{},
}
[1055.56:S:950
[1000:S_1:950:5
]
[1033:S_2:950:6
[1033:{S_2,1}:950:1]
[950:{S_2,2}:1033:2]
]
]
\end{forest}
이는 분명히 훨씬 더 간결하고 생산적입니다.
이런 종류의 트리에 대한 기준이 무엇인지 모르므로 제대로 작동하려면 약간의 조정이 필요할 수 있습니다. 예를 들어, 가장자리 레이블이 항상 x\leq
및 형식이 아닐 수도 있고 x\req
, 하위 항목이 한 개만 있거나 두 개 이상인 경우도 있을 수 있습니다. 그러나 이는 최소한 이 접근 방식의 잠재적인 힘을 보여주어야 합니다.
전체 코드:
\documentclass[border=10pt]{standalone}
\usepackage{forest}
\tikzset{
tree node/.style = {align=center, inner sep=0pt, font = \scriptsize},
S/.style = {draw, circle, minimum size = 8mm, top color=white, bottom color=blue!20},
tree node label/.style={font=\scriptsize},
}
\forestset{
declare toks={left branch prefix}{},
declare toks={right branch prefix}{},
declare toks={left branch suffix}{},
declare toks={right branch suffix}{},
tree node left label/.style={
label=170:#1,
},
tree node right label/.style={
label=10:#1,
},
maths branch labels/.style={
branch label/.style={
if n=1{
edge label={node [left, midway] {$\forestoption{left branch prefix}##1\forestoption{left branch suffix}$}},
}{
edge label={node [right, midway] {$\forestoption{right branch prefix}##1\forestoption{right branch suffix}$}},
}
},
},
text branch labels/.style={
branch label/.style={
if n=1{
edge label={node [left, midway] {\foresteoption{left branch prefix}##1\forestoption{left branch suffix}}},
}{
edge label={node [right, midway] {\forestoption{right branch prefix}##1\forestoption{right branch suffix}}},
}
},
},
text branch labels,
set branch labels/.style n args=4{%
left branch prefix={#1},
left branch suffix={#2},
right branch prefix={#3},
right branch suffix={#4},
},
set maths branch labels/.style n args=4{
maths branch labels,
set branch labels={#1}{#2}{#3}{#4},
},
set text branch labels/.style n args=4{
text branch labels,
set branch labels={#1}{#2}{#3}{#4},
},
branch and bound/.style={
/tikz/every label/.append style=tree node label,
maths branch labels,
for tree={
tree node,
S,
math content,
s sep'+=20mm,
l sep'+=5mm,
thick,
edge+={thick},
},
before typesetting nodes={
for tree={
split option={content}{:}{tree node left label,content,tree node right label,branch label},
},
},
where n children=0{
tikz+={
\draw [thick] ([yshift=-10pt, xshift=-2.5pt].south west) -- ([yshift=-10pt, xshift=2.5pt].south east);
}
}{},
},
}
\begin{document}
\begin{forest}
branch and bound,
where level=1{
set branch labels={x\leq}{}{x\geq}{},
}{
if level=2{
set branch labels={}{\geq y}{}{\leq y},
}{},
}
[1055.56:S:950
[1000:S_1:950:5
]
[1033:S_2:950:6
[1033:{S_2,1}:950:1]
[950:{S_2,2}:1033:2]
]
]
\end{forest}
\end{document}
답변2
- MWE의 두 번째 코드에 대한 오류가 발생한
}
후 소스가 누락되었습니다.edge from parent node
- 솔루션
tikz
- 노드 및 가장자리 레이블에 대한 새로운 스타일을 정의하여 코드를 정리하고 더 짧게 만듭니다.
- 질문에 있는 두 트리를 하나로 결합합니다.CFR그의 대답에서) 우리는 다음과 같이 됩니다:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calc, shapes}
\begin{document}
\begin{figure}
\tikzset{thick,
tree node/.style = {align=center, inner sep=0pt, font = \scriptsize},
every label/.append style = {font=\scriptsize},
S/.style = {draw, circle, minimum size = 11mm, inner sep=0pt,
top color=white, bottom color=blue!20},
ENL/.style = {% edge node left
font=\footnotesize, left=1pt},
ENR/.style = {% edge node right
font=\footnotesize, right=1pt},
grow = down,
sibling distance = 2.8cm,
level distance = 3cm
}
\newcommand\LB{% Lower bound
\tikz\draw[very thick] (-0.5,0) -- + (1,0);}
\centering
\begin{tikzpicture}
\node [S, label=10:950, label=170:1055.56] {$S$}
child{node [S, label=10:950, label=170:1000, label=below:\LB] {$S_1$}
edge from parent node[ENL] {$x \leq 5$}}
child{node [S, label=10:950, label=170:1033] {$S_2$}
child{node [S, label=10:950, label=170:1033, label=below:\LB] {$S_2,1$}
edge from parent node[ENL] {$x \geq 6$}}
child{node [S, label=10:950, label=170:1033, label=below:\LB] {$S_2,2$}
edge from parent node[ENR] {$x \leq 1$}}
edge from parent node[ENR] {$x \geq 6$}
};
\end{tikzpicture}
\end{figure}
\end{document}