Rama y árbol atado en tikz.

Rama y árbol atado en tikz.

Estoy intentando crear un árbol que muestre la rama y el proceso vinculado para un problema de programación de enteros en tikz. Logré crear un árbol con el primer nivel exactamente de la manera que quiero, pero látex no puede compilar el árbol con el segundo nivel y no estoy seguro. Mi código está muy mal optimizado ya que esta era la única forma en que podía descubrir cómo hacerlo, y el código desordenado significa que es difícil identificar dónde me estoy equivocando.

Si alguien pudiera mostrarme una manera de limpiar el código para que la mayoría de los detalles del nodo estén en la predefinición o mostrarme dónde me estoy equivocando en el segundo árbol, sería genial.

Código para el primer nivel:

\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}

Código para el primer y segundo nivel, que no se compilan:

\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}

¡Gracias de antemano!

Editar: una rama y un árbol vinculado como el que estoy intentando crear

Una rama y un árbol atado como el que estoy intentando crear.

Respuesta1

Yo usaría uno de los paquetes especializados para dibujar árboles. Más específicamente, usaría foresto, en su defecto, tikz-qtree. Si hace esto, podrá especificar árboles de forma muy concisa y sencilla, y asegurarse fácilmente de que tengan un formato coherente.

En el caso de Forest, el paquete también hará gran parte del trabajo de diseño por usted, aunque las etiquetas no se manejan de esta manera, por lo que esta ventaja particular puede no ser de mucho beneficio para árboles de este tipo en particular.

A continuación se muestra un ejemplo que define un branch and boundestilo para Forest. Cuando se aplica a un árbol, sucede lo siguiente:

  • tree node, Sy thickse aplican a todos los nodos del árbol y su contenido se establece en modo matemático;

  • los bordes también lo son thick;

  • se añade un poco de espacio al árbol para espaciar las ramas y los niveles;

  • después de analizar el árbol, el contenido de cada nodo se divide en cada dos puntos: <left label>:<node content>:<right label>:<edge label>;

    • La parte anterior a los primeros dos puntos se convierte en la etiqueta izquierda (en 170). La siguiente parte se establece como contenido del nodo principal (con tree node, en modo matemático, etc.). La tercera parte se establece como la etiqueta derecha (en 10). La parte final se convierte en la etiqueta de la rama: a la izquierda del punto medio para una rama izquierda y a la derecha para una rama derecha.
  • el contenido de las etiquetas de los bordes se puede configurar en modo texto ( text branch labels) o modo matemático ( maths branch labels);

    • Se pueden agregar prefijos y sufijos usando uno de

      • 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>}

  • Se dibuja una línea horizontal debajo de cada hoja del árbol.

Luego podemos especificar cuál creo que es su segundo árbol, ahora editado a la luz de los comentarios para variar las etiquetas de los bordes según el nivel, con

\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}

que obviamente es bastante más conciso y produce

Árbol <code>ramificado y enlazado</code>

No sé cuáles son los criterios para este tipo de árbol, por lo que es posible que sea necesario realizar algunos ajustes para que funcione bien. Por ejemplo, quizás las etiquetas de los bordes no siempre tengan la forma x\leqy x\req, o quizás a veces solo haya uno o más de dos hijos. Sin embargo, esto debería al menos ilustrar el poder potencial de este enfoque.

Código completo:

\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}

Respuesta2

  • errores para el segundo código en su mwe tiene la fuente perdida }despuésedge from parent node
  • solución contikz
  • su código se limpia y se acorta definiendo nuevos estilos para nodos y etiquetas de bordes
  • combinando ambos árboles en su pregunta en uno (similar a lo que hacecfren su respuesta) nos convertimos en:

\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}

ingrese la descripción de la imagen aquí

información relacionada