tikz의 가지와 경계 트리

tikz의 가지와 경계 트리

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

나는 전문적인 나무 그리기 패키지 중 하나를 사용할 것입니다. 좀 더 구체적으로 말하자면, forestor 를 사용 하고 실패할 경우 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}

이는 분명히 훨씬 더 간결하고 생산적입니다.

<code>분기 및 경계</code> 트리

이런 종류의 트리에 대한 기준이 무엇인지 모르므로 제대로 작동하려면 약간의 조정이 필요할 수 있습니다. 예를 들어, 가장자리 레이블이 항상 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}

여기에 이미지 설명을 입력하세요

관련 정보