¿Existe alguna biblioteca para dibujar estructuras de árboles de estado en TikZ?

¿Existe alguna biblioteca para dibujar estructuras de árboles de estado en TikZ?

State tree structure (STS)Los s son un tipo especial de diagramas que pertenecen a state chartla familia s.

Un típico STSpodría representarse de la siguiente manera:

ingrese la descripción de la imagen aquí

El número de ramas, etiquetas estatales y símbolos de cruz o unión podrían formarse en cualquier estructura arbitraria, según lo pretenda el diseñador.

Tal vez tikz-treessería una aproximación, pero según verifiqué, no sentí que fuera capaz de generar algo como la figura, en general.

¿Existe alguna biblioteca especializada para algún tipo de cosas TikZ?

Respuesta1

Aquí hay una versión que define un estilo Bosque, state treepara formatear árboles de este tipo. Las suposiciones, basadas en el ejemplo, son que

  • los niños deben estar distribuidos uniformemente;
  • el primer y último hijo deben estar equidistantes del padre;
  • los bordes deben dibujarse sólo para el primer y último hijo;
  • el contenido de los nodos debe escribirse en modo matemático.

El estilo podrá modificarse si uno o más de estos supuestos requieren enmienda.

Aquí está el código para el árbol, que es una ligera adaptación deignasi:

\begin{forest}
  state tree,
  [x_0
    [x_1
      [x_{11}
        [x_{111}]
        [\dot{\cup}]
        [x_{112}]
      ]
      [\times]
      [x_{12}
        [x_{121}]
        [\dot{\cup}]
        [x_{122}]
      ]
    ]
    [\dot{\cup}]
    [x_2]
    [\dot{\cup}]
    [x_3
      [x_{31}]
      [\dot{\cup}]
      [x_{32}]
      [\dot{\cup}]
      [x_{33}]
    ]
  ]
\end{forest}

state treeestablece el estilo. El resto es automático, por lo que no es necesario no edgeetc.

Esto produce el siguiente resultado:

árbol de estado

Código completo:

\documentclass[border=10pt,multi,tikz]{standalone}
\usepackage{forest}
% ateb: addaswyd o ateb Ignasi: https://tex.stackexchange.com/a/351690/
\forestset{%
  state tree/.style={%
    for tree={
      math content,
      parent anchor=children,
      child anchor=parent,
      tier/.option=level,
      calign=center,
    },
    where={>On>{n children}{2}}{
      for nodewalk={
        filter={children}{>On=!On=!&{n}{1}{n'}{1}}
      }{no edge}
    }{},
    before computing xy={
      where={isodd(n_children)}{
        tempdima/.process={OOOw3+d{!n=1.s}{!n'=1.s}{n children}{(##2-##1)/(##3-1)}},
        tempdimb/.option={!n=1.s},
        for children={
          s/.process={RROw3+d{tempdima}{tempdimb}{n}{##2+(##1*(##3-1))}}
        },
      }{},
    },
  },
}
\begin{document}
\begin{forest}
  state tree,
  [x_0
    [x_1
      [x_{11}
        [x_{111}]
        [\dot{\cup}]
        [x_{112}]
      ]
      [\times]
      [x_{12}
        [x_{121}]
        [\dot{\cup}]
        [x_{122}]
      ]
    ]
    [\dot{\cup}]
    [x_2]
    [\dot{\cup}]
    [x_3
      [x_{31}]
      [\dot{\cup}]
      [x_{32}]
      [\dot{\cup}]
      [x_{33}]
    ]
  ]
\end{forest}
\end{document}

Respuesta2

También podrías probar con forest, aunque no sé distribuir correctamente algunos hijos:

\documentclass [multi=forest, border=2mm]{standalone} 
\usepackage{forest}

\begin{document}
\begin{forest}
for tree={math content}
[x_0
    [x_1 
        [x_{11} 
            [x_{111}] 
            [\dot{\cup}, no edge] 
            [x_{112}]]
        [\times, no edge]
        [x_{12}
            [x_{121}]
            [\dot{\cup}, no edge]
            [x_{122}]]]
    [\dot{\cup}, no edge]
    [x_2, no edge]
    [\dot{\cup}, no edge]
    [x_3
        [x_{31}]
        [\dot{\cup}, no edge]
        [x_{32}, no edge]
        [\dot{\cup}, no edge]
        [x_{33}]]]
\end{forest}

\end{document}

ingrese la descripción de la imagen aquí

Actualización: con la sugerencia de JLDiaz, el resultado se ve mejor, todavía no es perfecto, pero sí mejor.

\documentclass [multi=forest, border=2mm]{standalone} 
\usepackage{forest}

\begin{document}
\begin{forest}
for tree={math content}
[x_0
    [x_1 
        [x_{11} 
            [x_{111}] 
            [\dot{\cup}, no edge] 
            [x_{112}]]
        [\null, no edge]  %<-------------
        [\times, no edge]
        [x_{12}
            [x_{121}]
            [\dot{\cup}, no edge]
            [x_{122}]]]
    [\null, no edge]        %<-------------
    [\dot{\cup}, no edge]
    [x_2, no edge]
    [\dot{\cup}, no edge]
    [x_3
        [x_{31}]
        [\dot{\cup}, no edge]
        [x_{32}, no edge]
        [\dot{\cup}, no edge]
        [x_{33}]]]
\end{forest}

\end{document}

ingrese la descripción de la imagen aquí

Respuesta3

Un primer intento sería el siguiente. No tengo mucha experiencia dibujando árboles, así que podría haber una mejor manera de hacerlo. Sin embargo, el punto clave es la colocación de los nodos entre los niños, y la calcbiblioteca es perfecta para ello:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}

\def\rootname{root}
\newcommand{\stnode}[3]{\node at ($(#1)!0.5!(#2)$) { #3 }}
\newcommand{\stnodec}[3]{\node at ($(#1.center)!0.5!(#2.center)$) { #3 }}
\newcommand{\stnoderootc}[3]{\node at ($(\rootname-#1.center)!0.5!(\rootname-#2.center)$) { #3 }}

\begin{document}
    \begin{tikzpicture}
        [
            level 1/.style = {sibling distance = 3cm},
            level 2/.style = {sibling distance = 2cm}
        ]
        \node (root) { $x_0$ }
            child { node { $x_1$ } 
                child { node { $x_3$ } }
                child { node { $x_4$ } }
            }
            child { node { $x_2$ } 
                child { node { $x_5$ } }
                child { node { $x_6$ } }
            }
        ;
        place the annotation nodes between the children
        \stnode{root-1.center}{root-2.center}{$\times$};
        \stnodec{root-1-1}{root-1-2}{$\times$};
        \stnoderootc{2-1}{2-2}{$\times$};
    \end{tikzpicture}
\end{document}

Puede utilizar una de las tres macros ( \stnode, \stnodec(Center), \stnoderootc(nodo raíz automático, centro)) para colocar los nodos de anotación. El nombre raíz debe redefinirse para representar el nombre real del nodo raíz. Para obtener la máxima flexibilidad, simplemente utilice \stnode.

Los argumentos son n.° 1: primer nodo, n.° 2: segundo nodo, n.° 3: texto del nodo.

El resultado es el siguiente: Resultado

Obviamente, los respectivos nodos deben tener la misma ubicación en Y; seguirá funcionando si este no es el caso, pero se verá extraño.

información relacionada