Ветвь и связанное дерево в тикзе

Ветвь и связанное дерево в тикзе

Я пытаюсь создать дерево, показывающее процесс ветвей и границ для задачи целочисленного программирования в tikz. Мне удалось создать дерево с первым уровнем именно так, как я хочу, но latex не может скомпилировать дерево со вторым уровнем, и я не уверен. Мой код очень плохо оптимизирован, так как это был единственный способ, которым я мог понять, как это сделать, и из-за запутанного кода сложно определить, где я ошибаюсь.

Если бы кто-нибудь мог показать мне, как очистить код, чтобы большая часть деталей узлов была в предварительном определении, или показать, где я ошибаюсь во втором дереве, это было бы здорово.

Код для первого уровня:

\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или, если это невозможно, 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 имеют источник в mising }после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}

введите описание изображения здесь

Связанный контент