[Tex/LaTex] Replicating a simple diagram in Knuth’s book using TikZ

diagramstikz-arrowstikz-pgf

"Factoring by division" algorithm as described in the book *The Art of Computer Programming*, Vol. 2 by Donald Knuth

Despite the many attempts to draw this simple flowchart, I didn't really know how to do the following:

  1. Drawing a start arrow (as the one before A1)

  2. Drawing an end arrow (as the one after A2 and A7)

  3. Having the structure of the flow between nodes of a diamond shape (as in the arrows connecting A2, A3, A4, and A5)

  4. Drawing a "smart" returning arrow that doesn't penetrate other nodes (as in between A6 and A3)

  5. Adjusting the length of the arrow (or the distance between nodes)

  6. Adjusting the vertical distance between nodes

  7. Putting the diagram in the center

Here is my code:

\documentclass{article}
\usepackage{tikz} % For drawing circles around numbers
\usetikzlibrary{shapes,arrows}

\begin{document}
\tikzstyle{decision} = [draw, text width=6.0em, text badly centered, node     distance=3cm, inner sep=0pt, minimum height=2.0em]
\tikzstyle{block} = [rectangle, draw, text centered, rounded corners,     minimum height=2.0em]
\tikzstyle{line} = [draw, -latex']
\tikzstyle{cloud} = [draw, ellipse, node distance=3cm, minimum height=2em]

\begin{center}
\begin{figure}[H]
\begin{tikzpicture}[node distance = 2cm, auto]
    % Place nodes
    \node [decision] (init) {Initialize};
    \node [block, below of=init] (trivial) {$N = 1$?};
    \node [decision, right of=trivial] (divide) {Divide};
    \node [decision, below of=divide] (factorFound) {Factor found};
    \node [block, right of=divide, node distance=3cm] (zeroRem){Zero remainder?};
    \node [block, right of=zeroRem, node distance=3cm] (lowQuot)
          {Low quotient?};
    \node [decision, below of=lowQuot] (prime) {$N$ is prime};
    % Draw edges
    \path [line] (init) -- (trivial);
    \path [line] (trivial) -- node {No}(divide);
    \path [line] (divide) -- (zeroRem);
    \path [line] (zeroRem) -- node {No}(lowQuot);
    \path [line] (zeroRem) -- node {Yes}(factorFound);
    \path [line] (factorFound) -- (trivial);
    \path [line] (lowQuot) -- (prime);
    \path [line] (lowQuot) |- node {No}(divide);
    \end{tikzpicture}
    \label{Figure:TrialDivFlowChart}
    \caption{Trial division as described in [Knuth 2004].}
\end{figure}
\end{center}
\end{document}

Best Answer

You can use positioning library and control the positioning as you wish.

\documentclass{article}
\usepackage{tikz} % For drawing circles around numbers
\usetikzlibrary{shapes,arrows,positioning}

\begin{document}
\tikzset{
decision/.style = {draw, text width=6.0em, text badly centered, node     distance=3cm,  minimum height=2.0em},
block/.style = {rectangle, draw,text width=6.0em, text centered, rounded corners=2ex,     minimum height=2.0em},
line/.style = {draw, -latex'},
cloud/.style = {draw, ellipse, node distance=3cm, minimum height=2em}
}

\begin{figure}[H]
\centering
\begin{tikzpicture}[node distance = 2cm, auto]
    % Place nodes
    \coordinate (a) at (0,0);
    \node [decision,below = .8cm of a]  (init) {A1. Initialize};
    \node [block, below = .8cm of init] (trivial) {A2. $N = 1$?};
    \node [decision, above right = .15cm and .8cm of trivial] (divide) {A3. Divide};
    \node [decision, below  = .8cm of divide] (factorFound) {A5. Factor found};
    \node [block, below right = .15cm and .8cm of divide, node distance=3cm] (zeroRem){A4. Zero remainder?};
    \node [block, right = .8cm of zeroRem, node distance=3cm] (lowQuot)
          {A6. Low quotient?};
    \node [decision, below = .8cm of lowQuot] (prime) {A7. $N$ is prime};
    % Draw edges
    \path [line] (a) -- (init);
    \path [line] (init) -- (trivial);
    \path [line] (trivial.10) -- node[near end,below=.5ex] {No}(divide.180);
    \path [line] (divide.0) -- (zeroRem.170);
    \path [line] (zeroRem) -- node {No}(lowQuot);
    \path [line] (zeroRem.190) -- node {Yes}(factorFound.0);
    \path [line] (factorFound.180) -- (trivial.-10);
    \path [line] (lowQuot) -- (prime);
    \path [line,rounded corners=7ex] (lowQuot) -- ++(0, 2.5cm) node[right, near start] {No} -| (divide.north);
    %\path [line, near start] (lowQuot) edge[bend right, in=-90, out = -90,] node [near start,right] {No} (divide.north);
    \path [line] (trivial.south) -- +(0,-.8cm);
    \path [line] (prime.south) -- +(0,-.8cm);
    \end{tikzpicture}
    \label{Figure:TrialDivFlowChart}
    \caption{Trial division as described in [Knuth 2004].}
\end{figure}
\end{document}

enter image description here