7

I am currently trying to split an edge in an automaton in tikz. What I already have is this: enter image description here

I would like to get somethink like this (not in red, just to highlight): enter image description here The idea is to have a probabilistic automaton. If the automaton gets the input D, it changes with probability 2/3 to state q1 and with probability 1/3 it remains in state q3. That it why I would like to have one outgoing edge from q3 with input D, the edge should split after a while as you can see in the picture. How can I achieve that?

Here is my code (I needed some if the other tikzlibraries for other parts of my original code, so don't get confused):

\documentclass[a4paper, 12pt, parskip=half+]{scrreprt}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{pgffor}
\usetikzlibrary{automata,shapes.multipart} % Import library for 
     drawing automata
\usetikzlibrary{calc, trees} %For graphics
\usetikzlibrary{positioning} % ...positioning nodes
\usetikzlibrary{arrows,shapes} % ...customizing arrows
\usetikzlibrary{patterns,decorations.pathreplacing}
\tikzset{node distance=2.5cm, %Minimum distance between nodes
   every state/.style={minimum size=0pt, fill=gray!10, circle split, 
   align=center}, %properties for each state
   initial text={}, %No label on start state
   final/.style=accepting,
   every picture/.style={>=stealth'},
   brace/.style={decorate,decoration=brace}, semithick}

\begin{document}
\begin{figure}
  \centering
    \begin{tikzpicture}[{node distance=1.5cm, ,shorten >=1pt,%Minimum 
      distance between nodes
      every state/.style={minimum size=0pt, inner sep=1pt, 
      fill=gray!10, circle, align=center}, %properties for each state
      initial text={}, %No label on start arrow
      final/.style=accepting,
      every picture/.style={>=stealth'},
      brace/.style={decorate,decoration=brace}, semithick,
      every loop/.style={min distance=5mm,looseness=5}}]
   \node[state,initial] (q1) {$q_i^1$ \\ -------- \\ A}; 
   \node[state] (q2) [right=of q1] {$q_i^2$ \\ -------- \\ B}; 
   \node[state] (q3) [right=of q2] {$q_i^3$ \\ -------- \\ B}; 
   \draw[->] (q1) to[loop above] node [above] {\texttt{C}} (q1);
   \draw[->] (q1) edge node [above] {\texttt{D}} (q2);
   \draw[->] (q2) edge node [above] {\texttt{D}} (q3);
   \draw[->] (q3) to[loop above] node [above] {\texttt{C}} (q3); 
 \end{tikzpicture}
\end{figure}
\end{document}

Sorry, I just realised that the state I meant was named q2 in the picture. I'm sorry for that. I mean the state named q3 in the code if it was not clear (I changed it in the code). I am thankful for any help I get. You can also find nice examples of what I would like to get in this articles (page 4, figures 2 and 3)

7

It is rather easy to do that with decorations.markings. Below the same thing is achieved by a style.

\documentclass[a4paper, 12pt, parskip=half+]{scrreprt}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{pgffor}
\usetikzlibrary{automata,shapes.multipart} % Import library for drawing automata
\usetikzlibrary{calc, trees} %For graphics
\usetikzlibrary{positioning} % ...positioning nodes
\usetikzlibrary{arrows,shapes} % ...customizing arrows
\usetikzlibrary{patterns,decorations.pathreplacing,decorations.markings}
\tikzset{node distance=2.5cm, %Minimum distance between nodes
   every state/.style={minimum size=0pt, fill=gray!10, circle split, 
   align=center}, %properties for each state
   initial text={}, %No label on start state
   final/.style=accepting,
   every picture/.style={>=stealth'},
   brace/.style={decorate,decoration=brace}, semithick}

\begin{document}
\begin{figure}
  \centering
    \begin{tikzpicture}[{node distance=1.5cm, ,shorten >=1pt,%Minimum 
      distance between nodes
      every state/.style={minimum size=0pt, inner sep=1pt, 
      fill=gray!10, circle, align=center}, %properties for each state
      initial text={}, %No label on start arrow
      final/.style=accepting,
      every picture/.style={>=stealth'},
      brace/.style={decorate,decoration=brace}, semithick,
      every loop/.style={min distance=5mm,looseness=5}}]
   \node[state,initial] (q1) {$q_i^1$ \\ -------- \\ A}; 
   \node[state] (q2) [right=of q1] {$q_i^2$ \\ -------- \\ B}; 
   \node[state] (q3) [right=of q2] {$q_i^3$ \\ -------- \\ B}; 
   \draw[->] (q1) to[loop above] node [above] {\texttt{C}} (q1);
   \draw[->] (q1) edge node [above] {\texttt{D}} (q2);
   \draw[->] (q2) edge node [above] {\texttt{D}} (q3);
   \draw[->] (q3) to[loop above] node [above] {\texttt{C}} (q3); 
   \draw[->,postaction={decorate,decoration={markings,
   mark=at position 0.25 with {\draw[->] (0pt,0pt) to[bend left] 
   coordinate[midway](aux) (q3);
   \pgftransformreset
   \node[above=2pt of aux]{$1/3$};}}}] (q3) to[out=135,in=45] 
   node[midway,above]{$2/3$}  (q1);
 \end{tikzpicture}
\end{figure}
\end{document}

enter image description here

Here is the same thing with a style

split connection=at <pos of splitting point> with ratio <label> to <additional target>

and an example in the code

\documentclass[a4paper, 12pt, parskip=half+]{scrreprt}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{pgffor}
\usetikzlibrary{automata,shapes.multipart} % Import library for drawing automata
\usetikzlibrary{calc, trees} %For graphics
\usetikzlibrary{positioning} % ...positioning nodes
\usetikzlibrary{arrows,shapes} % ...customizing arrows
\usetikzlibrary{patterns,decorations.pathreplacing,decorations.markings}
\tikzset{node distance=2.5cm, %Minimum distance between nodes
   every state/.style={minimum size=0pt, fill=gray!10, circle split, 
   align=center}, %properties for each state
   initial text={}, %No label on start state
   final/.style=accepting,
   every picture/.style={>=stealth'},
   brace/.style={decorate,decoration=brace}, semithick}

\begin{document}
\begin{figure}
  \centering
    \begin{tikzpicture}[node distance=1.5cm, shorten >=1pt,%Minimum 
      distance between nodes
      every state/.style={minimum size=0pt, inner sep=1pt, 
      fill=gray!10, circle, align=center}, %properties for each state
      initial text={}, %No label on start arrow
      final/.style=accepting,
      every picture/.style={>=stealth'},
      brace/.style={decorate,decoration=brace}, semithick,
      every loop/.style={min distance=5mm,looseness=5},
      split connection/.style args={at #1 with ratio #2 to #3}{postaction={decorate,decoration={markings,
   mark=at position #1 with {\draw[->] (0pt,0pt) to[bend left] 
   coordinate[midway](aux) (#3);
   \pgftransformreset
   \node[above=2pt of aux]{$#2$};}}}}
   ]
   \node[state,initial] (q1) {$q_i^1$ \\ -------- \\ A}; 
   \node[state] (q2) [right=of q1] {$q_i^2$ \\ -------- \\ B}; 
   \node[state] (q3) [right=of q2] {$q_i^3$ \\ -------- \\ B}; 
   \draw[->] (q1) to[loop above] node [above] {\texttt{C}} (q1);
   \draw[->] (q1) edge node [above] {\texttt{D}} (q2);
   \draw[->] (q2) edge node [above] {\texttt{D}} (q3);
   \draw[->] (q3) to[loop above] node [above] {\texttt{C}} (q3); 
   \draw[->,split connection=at 0.25 with ratio $1/3$ to q3] (q3) to[out=135,in=45] 
   node[midway,above]{$2/3$}   node[midway,below]{\texttt{D}} (q1);
 \end{tikzpicture}
\end{figure}
\end{document}

enter image description here

  • Wow, that looks nice! Thank you so much. Do you also know how to add the label "D" at that part of the edge where there was still only one edge (the lower part of the edge)? – Unicorn Sep 13 '18 at 14:56
  • 1
    @Unicorn Sure, just replace node[midway,below]{\texttt{D}} by node[pos=0.125,below]{\texttt{D}}. One could also make this part of the style, but the style would then become a bit bulky because it would have tons of parameters. If you tell me which version (style or no style) you like better, I could clean up. – user121799 Sep 13 '18 at 14:58
  • I first implemented the no style version, but now I'm using the style version. Works perfectly fine, no need to spend more time. They both saved my day. Perhaps another question, it is not of great importance, but so that I understand the tikz automata stuff better (I am following the approach of "learning" by doing or, to my shame, letting other people do it.) It may look better if the self-pointing edge in state q3 bends from right to left and not from left to right. It should still loop over the state, not under it. How can this be achieved? (i.e. as in q1, but mirrored vertically) – Unicorn Sep 13 '18 at 17:57
  • 1
    @Unicorn That's very simple. Just add a style my loop above/.style={out=75,in=105,loop}, e.g. to the options of the tikzpicture or add \tikzset{my loop above/.style={out=75,in=105,loop}}, and then use my loop above instead of loop above. (That's a strange site on which a unicorn talks to a marmot. ;-) – user121799 Sep 13 '18 at 18:03
  • 1
    Well, you know, anything is possible on the Internet. Perfect, exactly what I was hoping for (took the style). Once you know how to do it, everything is simple. But if you have no idea, the solution is farther away than the universe. Maybe I should really start learning it. Thanks again! – Unicorn Sep 13 '18 at 18:18
5

An option using ..controls +(direction:module) and +(direction:module).. line because nodes in a path node[pos=0_to_1_value] does not work for bend or to[in.., out], using nodes in a path allows to put a node in ceirtain positions in this case at 0.12 for the D label using node[pos=0.12,below]... for the 2/3 label node[pos=0.8]... and to split the arrow an empty node node[pos=0.25](temp){}, temp is the node_name, and then drawing an arrow from temp.center to (q3) usign controls again to put a node in a path with the label 1/3...

RESULT:

enter image description here

MWE:

\documentclass[tikz,border=15pt]{standalone}
\usepackage[utf8]{inputenc}
\usetikzlibrary{automata,shapes.multipart} % Import library for drawing automata
\usetikzlibrary{calc, trees} %For graphics
\usetikzlibrary{positioning} % ...positioning nodes
\usetikzlibrary{arrows.meta,shapes} % ...customizing arrows
\usetikzlibrary{patterns,decorations.pathreplacing}
%Fonts MAnagement
\usepackage[scaled]{helvet} % For Sans Family
\usepackage{sansmath}
\sansmath 

\begin{document}
    \begin{tikzpicture}[
        %Environment Config
        node distance=1.5cm,
        shorten >=1pt,%Minimum distance between nodes
        semithick,
        font=\sffamily,
        >={Stealth},
        %Environment Styles
        every state/.style={
            minimum size=0pt,
            inner sep=1pt,
            fill=gray!10,
            circle,
            align=center
        }, %properties for each state
        initial text={}, %No label on start arrow
        final/.style={accepting},
        brace/.style={
            decorate,
            decoration=brace
        }, 
        every loop/.style={
            min distance=5mm,
            looseness=5}
    ]
    \node[state,initial] (q1) {$q_i^1$ \\ -------- \\ A}; 
    \node[state] (q2) [right=of q1] {$q_i^2$ \\ -------- \\ B}; 
    \node[state] (q3) [right=of q2] {$q_i^3$ \\ -------- \\ B}; 
    \draw[->] (q1) to[loop above] node [above] {\texttt{C}} (q1);
    \draw[->] (q1) edge node [above] {D} (q2);
    \draw[->] (q2) edge node [above] {D} (q3);
    \draw[->] (q3) to[loop above] node [above] {\texttt{C}} (q3);
    \draw[->] (q3) .. controls +(140:2.5) and +(40:2.5) .. (q1)
        node[pos=0.12,below]{D}
        node[pos=0.8,above]{\scriptsize $2/3$}
        node[pos=0.25](temp){};
    \draw[->] (temp.center) .. controls +(15:1) and +(120:1) .. (q3) node[pos=0.5,above]{\scriptsize $1/3$};
    \end{tikzpicture}
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.