我正在嘗試創建一棵樹,顯示 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
and的形式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中第二個程式碼的錯誤在mising之後有來源edge from parent node
- 解決方案與
tikz
- 透過為節點和邊緣標籤定義新樣式,您的程式碼會清理並變得更短
- 將問題中的兩棵樹合併為一棵(類似於CFR在他的回答中)mwe 變成:
\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}