Countability of the rationals: a pictorial diagram

As Qrrbrbirlbel commented, you can use the \matrix command. The matrix of math nodes option from the matrix library will save you some typing by automatically turning on math mode in each cell. When you name a matrix (m), you can use the syntax (m-i-j) to refer to the cell in row i and column j of that matrix. To connect nodes, simply draw the edges after the matrix is set up.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}

\begin{tikzpicture}
\matrix(m)[matrix of math nodes,column sep=1cm,row sep=1cm]{
    s_{11} & s_{12} & s_{13} & s_{14} & \cdots \\
    s_{21} & s_{22} & s_{23} & s_{24} & \cdots \\
    s_{31} & s_{32} & s_{33} & s_{34} & \cdots \\
    s_{41} & s_{42} & s_{43} & \cdots \\
};

\draw[->]
         (m-1-1)edge(m-1-2)
         (m-1-2)edge(m-2-1)
         (m-2-1)edge(m-3-1)
         (m-3-1)edge(m-2-2)
         (m-2-2)edge(m-1-3)
         (m-1-3)edge(m-1-4)
         (m-1-4)edge(m-2-3)
         (m-2-3)edge(m-3-2)
         (m-3-2)edge(m-4-1);
\end{tikzpicture}

\end{document}

enter image description here


Here is a solution that draws the edges automatically; no need to specify them one by one!

You can make the graph as big as you wish: simply specify the number of nodes you want by changing the value of positive integer \N.

Note: Failure to load the babel package with the english option will generate errors. See tikz-uml sequence diagram "Extra \or" error for more details.

Edit: See also Qrrbrbirlbel's "chains" solution, which is similar to mine in spirit.


enter image description here


enter image description here


\documentclass{article}
\usepackage[english]{babel}
\usepackage{etoolbox}
\usepackage{pgfplots}
\usetikzlibrary{arrows}
\begin{document}
\begin{tikzpicture}%
[
    ->,
    >=stealth',
    scale=2,
    auto,
  thick,
  main node/.style=%
  {
%   circle,
%   fill=blue!20,
%   draw,
    font=\sffamily\Large\bfseries,
  }
]
\pgfmathtruncatemacro\N{10}
\pgfmathtruncatemacro\i{1}
\pgfmathtruncatemacro\j{1}

\node[main node] at (\j,-\i) (n1) {$S_{\i\j}$};

\pgfplotsforeachungrouped \current in {1,2,...,\N-1}%
{
    \pgfmathtruncatemacro\next{\current+1}
    \ifnum\i=1% (first row)
        \ifnumodd{\j}%
        {   % Go East
            \pgfmathtruncatemacro\j{\j+1}
        }{% Go South West
            \pgfmathtruncatemacro\i{\i+1}
            \pgfmathtruncatemacro\j{\j-1}
        }
    \else% 
        \ifnum\j=1% (first column)
            \ifnumodd{\i}%
            { % Go North East
                \pgfmathtruncatemacro\i{\i-1}
                \pgfmathtruncatemacro\j{\j+1}
            }{% Go South
                \pgfmathtruncatemacro\i{\i+1}
            }
        \else
            \pgfmathtruncatemacro{\ijsum}{\i+\j}
            \ifnumodd{\ijsum}%
            { % Go South West
                \pgfmathtruncatemacro\i{\i+1}
                \pgfmathtruncatemacro\j{\j-1}
            }{% Go North East
                \pgfmathtruncatemacro\i{\i-1}
                \pgfmathtruncatemacro\j{\j+1}
            }
        \fi
    \fi
    \node[main node] at (\j,-\i) (n\next) {$S_{\i\j}$};
    \draw (n\current) -- (n\next);
}
\end{tikzpicture}
\end{document}

Matrix

It seems that a TikZ \matrix is the easiest approach here.

Combined with the execute at empty cell which fills the matrix automatically and the continous edges to style, you can create this diagram very fast.

Though, the arrows follow a pattern which can be automated, too:
This is done with the keys matrix connector urr (up-right, right) and matrix connector ldd (left-down, down) which initial a search algorithm that relies on named nodes in the matrix.

Code

\documentclass[tikz,convert=false]{standalone}
\usetikzlibrary{matrix}
\makeatletter
\tikzset{
  @continous edges to/.style={insert path={edge (#1) (#1)}},
  continous edges to/.style={@continous edges to/.list={#1}},
  matrix connector urr/.code args={#1-#2-#3}{%
    \pgfutil@ifundefined{pgf@sh@ns@#1-\the\numexpr#2-1\relax-\the\numexpr#3+1\relax}{%
      \pgfutil@ifundefined{pgf@sh@ns@#1-#2-\the\numexpr#3+1\relax}{}{
        \tikzset{insert path={(#1-#2-#3) edge (#1-#2-\the\numexpr#3+1\relax)},
                 matrix connector ldd/.expanded={#1-#2-\the\numexpr#3+1\relax}}%
      }%
    }{%
      \tikzset{insert path={(#1-#2-#3) edge (#1-\the\numexpr#2-1\relax-\the\numexpr#3+1\relax)},
               matrix connector urr/.expanded={#1-\the\numexpr#2-1\relax-\the\numexpr#3+1\relax}}%
    }
  },
  matrix connector ldd/.code args={#1-#2-#3}{%
    \pgfutil@ifundefined{pgf@sh@ns@#1-\the\numexpr#2+1\relax-\the\numexpr#3-1\relax}{%
      \pgfutil@ifundefined{pgf@sh@ns@#1-\the\numexpr#2+1\relax-#3}{}{%
        \tikzset{insert path={(#1-#2-#3) edge (#1-\the\numexpr#2+1\relax-#3)},
                 matrix connector urr/.expanded={#1-\the\numexpr#2+1\relax-#3}}%
      }%
    }{%
      \tikzset{insert path={(#1-#2-#3) edge (#1-\the\numexpr#2+1\relax-\the\numexpr#3-1\relax)},
               matrix connector ldd/.expanded={#1-\the\numexpr#2+1\relax-\the\numexpr#3-1\relax}}%
    }
  },
}
\makeatother
\begin{document}
\begin{tikzpicture}
\matrix (m) [
  matrix of nodes,
  nodes={
    shape=circle,
    inner sep=+.1667em,% half the default value
  },
  execute at empty cell={\node {$S_{\the\pgfmatrixcurrentrow\the\pgfmatrixcurrentcolumn}$};},
  row sep=2em,
  column sep=2em
] {
  & & & \\
  & & & \\
  & & & \\
  & & & \\
};
\path[->, ultra thick, matrix connector urr={m-1-1}];
\path[->,white, shorten >=2\pgflinewidth] (m-1-1) [continous edges to={m-1-2, m-2-1, m-3-1, m-2-2, m-1-3, m-1-4, m-2-3, m-3-2, m-4-1}];
\end{tikzpicture}
\end{document}

Output

enter image description here

Chains

An alternative approach, similar to Jubobs' answer, can be implemented with the chains library where one can use the placement options of the positioning library (i.e. on grid, node distance) for greater control. It is only used to place the nodes that are connected.

Code

\documentclass[tikz,convert=false]{standalone}
\usetikzlibrary{chains}
\newcommand*{\subscript}[3][]{%
    \ifodd#2
      \the\numexpr#2+1-#3\relax#1#3%
    \else
      #3#1\the\numexpr#2+1-#3\relax
    \fi}
\tikzset{
  zigzag/.code 2 args={%
    \ifnum#1>1
      \ifodd#1
        \ifnum#2=1
          \def\position{below}%
        \else
          \def\position{above right}%
        \fi
      \else
        \ifnum#2=1
          \def\position{right}%
        \else
          \def\position{below left}%
        \fi
      \fi
      \tikzset{\position=of \tikzchainprevious}
    \fi
  },
  zigzag*/.code={%
    \edef\llevel{\number\tikzchaincount}%
    \pgfmathloop
      \edef\testllevel{\the\numexpr\llevel-\pgfmathcounter\relax}%
      \ifnum1>\testllevel\relax
        \let\level\pgfmathcounter
      \else
        \let\llevel\testllevel
    \repeatpgfmathloop
    \tikzset{zigzag=\level\llevel}%
  }
}
%
\tikzset{
  every label/.append style={inner sep=+0pt, outer sep=+0pt, font=\tiny},
  label position=above left,
  every join/.append style={-latex},
}
\begin{document}
\begin{tikzpicture}[
  start chain=ch going {zigzag=\level\llevel},
  node distance=.75cm and 1cm,
  every on chain/.append style={
    join, label={(\number\tikzchaincount)}}]
\foreach \level in {1,...,4}
  \foreach \llevel in {1,...,\level}
    \node[on chain=ch] {$S_{\subscript[,]\level\llevel}$};
\end{tikzpicture}
\begin{tikzpicture}[
  on grid, node distance=1cm and 1.5cm, start chain=ch placed zigzag*,
  every on chain/.append style={
    circle, inner sep=+.1667em, text depth=+0pt, text height=+1.5ex,
    join, label/.expanded={(\noexpand\subscript[/]{\level}{\llevel})}}]
\foreach \cnt in {a,...,f} \node[on chain=ch] {\cnt};
\foreach \cnt in {G,...,M} \node[on chain=ch] {\cnt};
\end{tikzpicture}
\end{document}

Output

enter image description here

enter image description here