Escribí LaTeX para un autómata que se parece a esto:
Como puede ver, la 'b' en la flecha de q1 a q3 está ubicada más abajo que la 'a, b, c' en la flecha de q3 a q2.
Además, la 'b' en el borde de q2 a q3 está ubicada más abajo que la 'a, c' en la flecha de q3 a q1.
Me gustaría tener ambos dúos de nodos bien alineados, es decir, en la misma línea de base. Sin embargo, no es necesario que los cuatro estén en la misma línea.
Me parece que mi código debería hacer esto por sí solo, pero de alguna manera no funciona. ¿Por qué?
Aquí está mi código. Marqué los dos dúos de nodos con comentarios:
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{automata,arrows,calc,positioning}
\begin{document}
\begin{tikzpicture}[->,node distance=25mm]
\node[state,initial,accepting] (q0) {$q_0$};
\node[state,right=of q0] (q1) {$q_1$};
\node[state,right=of q1] (q2) {$q_2$};
\node[state,below=of $(q1)!0.5!(q2)$] (q3) {$q_3$};
\node[state,accepting,right=of q2] (q4) {$q_4$};
\draw (q0) edge[loop above] node[above] {a, b} (q0);
\draw (q0) -- node[above] {b, c} ++ (q1);
\draw (q1) edge[loop above] node[above] {a, c} (q1);
\draw (q1) edge[bend left] node[above] {a, b, c} (q2);
\draw (q2) -- node[below] {a, c} ++ (q1);
\draw (q2) edge[bend left] node[right] {b} (q3); % ! duo B
\draw (q3) -- node[above left] {a, b, c} ++ (q2); % ! duo A
\draw (q3) edge[bend left] node[left] {a, c} (q1); % ! duo B
\draw (q1) -- node[above right] {b} ++ (q3); % ! duo A
\draw (q2) edge[loop above] node[above] {a, b, c} (q2);
\draw (q2) -- node[above] {c} ++ (q4);
\draw (q1) edge[out=60,in=120] node[above] {c} (q4);
\end{tikzpicture}
\end{document}
Respuesta1
Agregue \strut
o defina text depth
esos nodos. También he cambiado above left
hacia left
y above right
hacia right
apropiadamente.
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{automata,arrows,calc,positioning}
\begin{document}
\begin{tikzpicture}[->,node distance=25mm]
\node[state,initial,accepting] (q0) {$q_0$};
\node[state,right=of q0] (q1) {$q_1$};
\node[state,right=of q1] (q2) {$q_2$};
\node[state,below=of $(q1)!0.5!(q2)$] (q3) {$q_3$};
\node[state,accepting,right=of q2] (q4) {$q_4$};
\draw (q0) edge[loop above] node[above] {a, b} (q0);
\draw (q0) -- node[above] {b, c} ++ (q1);
\draw (q1) edge[loop above] node[above] {a, c} (q1);
\draw (q1) edge[bend left] node[above] {a, b, c} (q2);
\draw (q2) -- node[below] {a, c} ++ (q1);
\draw (q2) edge[bend left] node[right] {\strut b} (q3); % ! duo B
\draw (q3) -- node[left] {\strut a, b, c} ++ (q2); % ! duo A
\draw (q3) edge[bend left] node[left] {\strut a, c} (q1); % ! duo B
\draw (q1) -- node[right] {\strut b} ++ (q3); % ! duo A
\draw (q2) edge[loop above] node[above] {a, b, c} (q2);
\draw (q2) -- node[above] {c} ++ (q4);
\draw (q1) edge[out=60,in=120] node[above] {c} (q4);
\end{tikzpicture}
\end{document}
Respuesta2
Como primer paso, agregaría las opciones text height=1ex, text depth=0pt
en la tikzpicture
opción s para forzar que todas las etiquetas tengan el mismo tamaño (vertical).
Habiendo hecho esto, los problemas
Como puede ver, la 'b' en la flecha de q1 a q3 está ubicada más abajo que la 'a, b, c' en la flecha de q3 a q2.
Además, la 'b' en el borde de q2 a q3 está ubicada más abajo que la 'a, c' en la flecha de q3 a q1.
se arreglan mágicamente.
Una solución alternativa y exótica es nombrar el nodo importante, decir el que tiene a,b,c
y definir b
el lugar en términos de la ubicación del nodo importante. Eso es:
\draw (q1) -- node[shift={(label-abc.west)}, xshift=-3.5mm] {b} ++ (q3);
El código completo:
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{automata,arrows,calc,positioning}
\begin{document}
\begin{tikzpicture}[->,node distance=25mm, text height=1ex, text depth=0pt]
\node[state,initial,accepting] (q0) {$q_0$};
\node[state,right=of q0] (q1) {$q_1$};
\node[state,right=of q1] (q2) {$q_2$};
\node[state,below=of $(q1)!0.5!(q2)$] (q3) {$q_3$};
\node[state,accepting,right=of q2] (q4) {$q_4$};
\draw (q0) edge[loop above] node[above] {a, b} (q0);
\draw (q0) -- node[above] {b, c} ++ (q1);
\draw (q1) edge[loop above] node[above] {a, c} (q1);
\draw (q1) edge[bend left] node[above] {a, b, c} (q2);
\draw (q2) -- node[below] {a, c} ++ (q1);
\draw (q2) edge[bend left] node[right] {b} (q3); % ! duo B
\draw (q3) -- node[above left](label-abc) {a, b, c} ++ (q2); % ! duo A
\draw (q3) edge[bend left] node[left] {a, c} (q1); % ! duo B
\draw (q1) -- node[shift={(label-abc.west)}, xshift=-3.5mm] {b} ++ (q3); % ! duo A
\draw (q2) edge[loop above] node[above] {a, b, c} (q2);
\draw (q2) -- node[above] {c} ++ (q4);
\draw (q1) edge[out=60,in=120] node[above] {c} (q4);
\end{tikzpicture}
\end{document}
Nota: haber configurado ambos text height
y text depth
es de gran ayuda en caso de letras comopag,q,gramoetcétera.
Por ejemplo:
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{automata,arrows,calc,positioning,fit}
\begin{document}
\begin{tikzpicture}[->,node distance=25mm, text height=1ex, text depth=0pt]
\node[state,initial,accepting] (q0) {$q_0$};
\node[state,right=of q0] (q1) {$q_1$};
\node[state,right=of q1] (q2) {$q_2$};
\node[state,below=of $(q1)!0.5!(q2)$] (q3) {$q_3$};
\node[state,accepting,right=of q2] (q4) {$q_4$};
\draw (q0) edge[loop above] node[above] {a, b} (q0);
\draw (q0) -- node[above] {b, c} ++ (q1);
\draw (q1) edge[loop above] node[above] {a, c} (q1);
\draw (q1) edge[bend left] node[above] {a, b, c} (q2);
\draw (q2) -- node[below] {a, c} ++ (q1);
\draw (q2) edge[bend left] node[right] (label-g) {g} (q3); % ! duo B
\draw (q3) -- node[draw,above left](label-abc) {a, b, c} ++ (q2); % ! duo A
\draw (q3) edge[bend left] node[left] (label-ac) {a, c} (q1); % ! duo B
\draw (q1) -- node[draw,above right] {q} ++ (q3); % ! duo A
\draw (q2) edge[loop above] node[above] {a, b, c} (q2);
\draw (q2) -- node[above] {c} ++ (q4);
\draw (q1) edge[out=60,in=120] node[above] {c} (q4);
\node[draw,fit=(label-g)(label-ac)]{};
\draw (label-ac.base)--(label-g.base);
\end{tikzpicture}
\end{document}
El resultado:
Respuesta3
en su mayoría fuera de tema, para ejercitar cómo acortar el código del diagrama :-). También se da alguna explicación adicional y se propone utilizar tikz
"comillas" de biblioteca.
Como se indica en otras respuestas, debe definir espacios para comas en las etiquetas de sus bordes. esto se puede hacer de dos maneras:
- como se propusoClaudio Fiandrino: determinar
text height=1ex
y establecertext depth=0pt
. Esta es la causa de que las letrasb
y las comas toquen el borde superior e inferior del nodo respectivamente. - según lo propuesto @user11232: uso de puntal en el contenido del nodo de cada etiqueta de borde inclinado, lo que hace que esos nodos tengan la misma altura y profundidad
en mwe abajo sigo aClaudio Fiandrinoenfoque, sin embargo, el tamaño del nodo se define de manera diferente y, en mi opinión, más correctamente. para etiquetas de borde se utilizan edge quotes
:
\documentclass[tikz, border=3mm]{standalone}
\usetikzlibrary{arrows.meta, automata,
calc,
positioning,
quotes}
\begin{document}
\begin{tikzpicture}[-Straight Barb,
node distance = 25mm,
auto = left,
every edge quotes/.style = {inner sep=1pt, % that labels are closer to edges
text height=1.5ex, % equal height,
text depth=2pt, % space for commas
% however this depth is not sufficient for letters as p,q, ...
% for them is better 0.25ex or slightly more
font=\small} % smaller letters, gives a nicer result
]
\node (q0) [state,initial,accepting] {$q_0$};
\node (q1) [state,right=of q0] {$q_1$};
\node (q2) [state,right=of q1] {$q_2$};
\node (q3) [state,below=of $(q1)!0.5!(q2)$] {$q_3$};
\node (q4) [state,accepting,right=of q2] {$q_4$};
%
\draw (q0) edge[loop above, "{a, b}"] ()
(q0) edge["{b, c}"] (q1)
(q1) edge[loop above, "{a, c}"] ()
(q1) edge[bend left, "{a, b, c}"] (q2)
(q2) edge["{a, c}"] (q1)
(q2) edge[loop above, "{a, b, c}"] ()
(q2) edge[bend left, "b"] (q3) % ! duo B
(q2) edge["c"] (q4)
(q3) edge["{a, b, c}"] (q2) % ! duo A
(q3) edge[bend left, "{a, c}"] (q1) % ! duo B
(q1) edge["b"] (q3) % ! duo A
(q1) edge[out=60,in=120, "c"] (q4);
\end{tikzpicture}
\end{document}