6

I am trying to draw a dynamic programming matrix. My attempt so far is:

\documentclass[]{article}
\begin{document}
\begin{tabular}{c||c|ccccc|cccccccccc}
    &&1&1&1&1&1&0&0&0&0&0&0&0&0&0&0\\\hline\hline
    &0&1&2&3&4&5&6&7&8&9&10&11&12&13&14&15\\\hline
    0&1&1&2&3&4&5&5&6&7&8&9&10&11&12&13&14\\
    0&2&2&2&3&4&5&5&5&6&7&8&9&10&11&12&13\\
    0&3&3&3&3&4&5&5&5&5&6&7&8&9&10&11&12\\\hline
    1&4&3&3&3&3&4&5&6&6&6&7&8&9&10&11&12\\
    1&5&4&3&3&3&3&4&5&6&7&7&8&9&10&11&12\\
    1&6&5&4&3&3&3&4&5&6&7&8&8&9&10&11&12\\
    1&7&6&5&4&3&3&4&5&6&7&8&9&9&10&11&12\\
    1&8&7&6&5&4&3&4&5&6&7&8&9&10&10&11&12\\\hline
    0&9&8&7&6&5&4&3&4&5&6&7&8&9&10&10&11\\
    0&10&9&8&7&6&5&4&3&4&5&6&7&8&9&10&10\\
    0&11&10&9&8&7&6&5&4&3&4&5&6&7&8&9&10\\
    0&12&11&10&9&8&7&6&5&4&3&4&5&6&7&8&9\\
\end{tabular}
\end{document}

I would now like to add two things:

  • Arrows between the numbers to show a shortest path from the top left to the bottom right.
  • I would like to shade some of the blocks in red (the ones where the symbols are different).

I tried to do this in tikz (with a different table) but it didn't go very well.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\usepackage{pdflscape}
\begin{document}
    \tikzset{ 
        table/.style={
            matrix of nodes,
            row sep=-\pgflinewidth,
            column sep=-\pgflinewidth,
            nodes={rectangle,text width=1.5em,align=center},
            text depth=0.3125ex,
            text height=0.625ex,
            nodes in empty cells
        },
        row 1/.style={nodes={fill=green!10,text depth=0.4ex,text height=2ex}},
        row 6/.style={nodes={text depth=0.4ex,text height=2ex}},
        column 1/.style={nodes={fill=green!10}},
    }
    \begin{landscape}
        \begin{tikzpicture}
        %\begin{tabular}{c||c|cccccccccc|cccccc|ccccccccc}
        \matrix (mat) [table]{
            &&0&0&0&0&0&0&0&0&0&0&1&1&1&1&1&1&0&0&0&0&0&0&0&0&0\\
            &0&1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&18&19&20&21&22&23&24&25\\
            1&1&|[fill=red!20]|1&|[fill=red!20]|2&|[fill=red!20]|3&|[fill=red!20]|4&|[fill=red!20]|5&|[fill=red!20]|6&|[fill=red!20]|7&|[fill=red!20]|8&|[fill=red!20]|9&|[fill=red!20]|10&10&11&12&13&14&15&|[fill=red!20]|16&|[fill=red!20]|17&|[fill=red!20]|18&|[fill=red!20]|19&|[fill=red!20]|20&|[fill=red!20]|21&|[fill=red!20]|22&|[fill=red!20]|23&|[fill=red!20]|24\\
            1&2&|[fill=red!20]|2&|[fill=red!20]|2&|[fill=red!20]|3&|[fill=red!20]|4&|[fill=red!20]|5&|[fill=red!20]|6&|[fill=red!20]|7&|[fill=red!20]|8&|[fill=red!20]|9&|[fill=red!20]|10&10&10&11&12&13&14&|[fill=red!20]|15&|[fill=red!20]|16&|[fill=red!20]|17&|[fill=red!20]|18&|[fill=red!20]|19&|[fill=red!20]|20&|[fill=red!20]|21&|[fill=red!20]|22&|[fill=red!20]|23\\
            1&3&|[fill=red!20]|3&|[fill=red!20]|3&|[fill=red!20]|3&|[fill=red!20]|4&|[fill=red!20]|5&|[fill=red!20]|6&|[fill=red!20]|7&|[fill=red!20]|8&|[fill=red!20]|9&|[fill=red!20]|10&10&10&10&11&12&13&|[fill=red!20]|14&|[fill=red!20]|15&|[fill=red!20]|16&|[fill=red!20]|17&|[fill=red!20]|18&|[fill=red!20]|19&|[fill=red!20]|20&|[fill=red!20]|21&|[fill=red!20]|22\\
            1&4&|[fill=red!20]|4&|[fill=red!20]|4&|[fill=red!20]|4&|[fill=red!20]|4&|[fill=red!20]|5&|[fill=red!20]|6&|[fill=red!20]|7&|[fill=red!20]|8&|[fill=red!20]|9&|[fill=red!20]|10&10&10&10&10&11&12&|[fill=red!20]|13&|[fill=red!20]|14&|[fill=red!20]|15&|[fill=red!20]|16&|[fill=red!20]|17&|[fill=red!20]|18&|[fill=red!20]|19&|[fill=red!20]|20&|[fill=red!20]|21\\
            0&5&4&4&4&4&4&5&6&7&8&9&|[fill=red!20]|10&|[fill=red!20]|11&|[fill=red!20]|11&|[fill=red!20]|11&|[fill=red!20]|11&|[fill=red!20]|12&12&13&14&15&16&17&18&19&20\\
            0&6&5&4&4&4&4&4&5&6&7&8&|[fill=red!20]|9&|[fill=red!20]|10&|[fill=red!20]|11&|[fill=red!20]|12&|[fill=red!20]|12&|[fill=red!20]|12&12&12&13&14&15&16&17&18&19\\
            0&7&6&5&4&4&4&4&4&5&6&7&|[fill=red!20]|8&|[fill=red!20]|9&|[fill=red!20]|10&|[fill=red!20]|11&|[fill=red!20]|12&|[fill=red!20]|13&12&12&12&13&14&15&16&17&18\\
            1&8&|[fill=red!20]|7&|[fill=red!20]|6&|[fill=red!20]|5&|[fill=red!20]|5&|[fill=red!20]|5&|[fill=red!20]|5&|[fill=red!20]|5&|[fill=red!20]|5&|[fill=red!20]|6&|[fill=red!20]|7&7&8&9&10&11&12&|[fill=red!20]|13&|[fill=red!20]|13&|[fill=red!20]|13&|[fill=red!20]|13&|[fill=red!20]|14&|[fill=red!20]|15&|[fill=red!20]|16&|[fill=red!20]|17&|[fill=red!20]|18\\
            %\end{tabular}
        };
        \foreach \x in {2,6,9}
        {
            \draw 
            ([xshift=-.125\pgflinewidth,yshift=3]mat-\x-1.south west) --   
            ([xshift=-.125\pgflinewidth,yshift=3]mat-\x-27.south east);
        }
    \begin{scope}[shorten >=7pt,shorten <= 7pt]
    \draw[->]  (mat-2-2.center) -- (mat-2-3.center);
    \draw[->]  (mat-2-3.center) -- (mat-2-4.center);
    \draw[->]  (mat-2-4.center) -- (mat-3-5.center);
    \draw[->]  (mat-3-5.center) -- (mat-4-6.center);
    \draw[->]  (mat-4-6.center) -- (mat-5-7.center);
    \draw[->]  (mat-5-7.center) -- (mat-6-8.center);
    \draw[->]  (mat-6-8.center) -- (mat-7-9.center);
    \draw[->]  (mat-7-9.center) -- (mat-8-10.center);
    \draw[->]  (mat-8-10.center) -- (mat-9-11.center);
    \draw[->]  (mat-9-11.center) -- (mat-10-12.center);

    \end{scope}

        \end{tikzpicture}
    \end{landscape}
\end{document}

This suffers from a few problems.

  • There is a strange space between two of the lines in the matrix.
  • The shading is shifted so it does not fill a block properly.
  • The arrows don't appear to be all lined up properly.
  • The LaTeX source is very wordy.

Any help much appreciated.

  • The «strange space between two of the lines in the matrix» is due to the special style command for row 6; what is the goal of this special style? – JPG Mar 15 '19 at 17:41
  • @JPG Oh that's just a bug and shouldn't be there! Thank you. – donald Mar 15 '19 at 18:02
6

Here are come correction:

  • removing row 6 style
  • removing text depth and setting text height to 1.1ex in order to avoid shifts between the fill and the content of the cells
  • shading areas with a 20% opacity rectangle above the matrix instead of filling each cell.

    \documentclass{standalone}
    \usepackage{tikz}
    \usetikzlibrary{matrix}
    \begin{document}
    \tikzset{ 
        table/.style={
            matrix of nodes,
            row sep=-\pgflinewidth,
            column sep=-\pgflinewidth,
            nodes={rectangle,text width=1.5em,align=center},
            text height=1.1ex,
            nodes in empty cells,
        },
        row 1/.style={nodes={fill=green!10}},
        column 1/.style={nodes={fill=green!10}}
    }
    
    \begin{tikzpicture}
            \matrix (mat) [table]{
            &&0&0&0&0&0&0&0&0&0&0&1&1&1&1&1&1&0&0&0&0&0&0&0&0&0\\
            &0&1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&18&19&20&21&22&23&24&25\\
            1&1&1&2&3&4&5&6&7&8&9&10&10&11&12&13&14&15&16&17&18&19&20&21&22&23&24\\
            1&2&2&2&3&4&5&6&7&8&9&10&10&10&11&12&13&14&15&16&17&18&19&20&21&22&23\\
            1&3&3&3&3&4&5&6&7&8&9&10&10&10&10&11&12&13&14&15&16&17&18&19&20&21&22\\
            1&4&4&4&4&4&5&6&7&8&9&10&10&10&10&10&11&12&13&14&15&16&17&18&19&20&21\\
            0&5&4&4&4&4&4&5&6&7&8&9&10&11&11&11&11&12&12&13&14&15&16&17&18&19&20\\
            0&6&5&4&4&4&4&4&5&6&7&8&9&10&11&12&12&12&12&12&13&14&15&16&17&18&19\\
            0&7&6&5&4&4&4&4&4&5&6&7&8&9&10&11&12&13&12&12&12&13&14&15&16&17&18\\
            1&8&7&6&5&5&5&5&5&5&6&7&7&8&9&10&11&12&13&13&13&13&14&15&16&17&18\\
        };
        \fill[red,opacity=0.2] (mat-3-3.north west) rectangle (mat-6-12.south east);
        \fill[red,opacity=0.2] (mat-7-13.north west) rectangle (mat-9-18.south east);
        \fill[red,opacity=0.2] (mat-3-19.north west) rectangle (mat-6-27.south east);
        \fill[red,opacity=0.2] (mat-10-3.north west) rectangle (mat-10-12.south east);
        \fill[red,opacity=0.2] (mat-10-19.north west) rectangle (mat-10-27.south east);
        \foreach \x in {2,6,9}
        {
            \draw 
            ([xshift=-.125\pgflinewidth]mat-\x-1.south west) --   
            ([xshift=-.125\pgflinewidth]mat-\x-27.south east);
        }
    \begin{scope}[shorten >=7pt,shorten <= 7pt]
    \draw[->]  (mat-2-2.center) -- (mat-2-3.center);
    \draw[->]  (mat-2-3.center) -- (mat-2-4.center);
    \draw[->]  (mat-2-4.center) -- (mat-3-5.center);
    \draw[->]  (mat-3-5.center) -- (mat-4-6.center);
    \draw[->]  (mat-4-6.center) -- (mat-5-7.center);
    \draw[->]  (mat-5-7.center) -- (mat-6-8.center);
    \draw[->]  (mat-6-8.center) -- (mat-7-9.center);
    \draw[->]  (mat-7-9.center) -- (mat-8-10.center);
    \draw[->]  (mat-8-10.center) -- (mat-9-11.center);
    \draw[->]  (mat-9-11.center) -- (mat-10-12.center);
    
    \end{scope}
    
        \end{tikzpicture}
    \end{document}
    

enter image description here

Edit

Coloring blocks of a matrix by filling a 20% opaque rectangle above it was a solution that did not satisfy me. I wanted to block-assign styles to cell, but tikz doesn't have options for that. After working from the answers to this question, I managed to do it: the filinred option defines styles for a block of cells through 2 loops (defined with /.list), and then the list of blocks is defined at the beginning of the matrix with format (top,left to bottom,right):

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
    \tikzset{ 
        table/.style={
            matrix of nodes,
            row sep=-\pgflinewidth,
            column sep=-\pgflinewidth,
            nodes={rectangle,text width=1.5em,align=center},
            text height=1.1ex,
            nodes in empty cells,
        },
        row 1/.style={nodes={fill=green!10}},
        column 1/.style={nodes={fill=green!10}},
        fillinred/.style args = {(#1,#2 to #3,#4)}{
            blockrows/.style={
                block/.style={
                    row ##1 column ####1/.style={nodes={fill=red!20}}
                },
                block/.list={#2,...,#4}
            },
            blockrows/.list={#1,...,#3}
        } 
    }

        \begin{tikzpicture}
            \matrix (mat) [table,fillinred/.list={(3,3 to 6,12),(10,3 to 10,12),(7,13 to 9,18),(3,19 to 6,27),(10,19 to 10,27)}]{
            &&0&0&0&0&0&0&0&0&0&0&1&1&1&1&1&1&0&0&0&0&0&0&0&0&0\\
            &0&1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&18&19&20&21&22&23&24&25\\
            1&1&1&2&3&4&5&6&7&8&9&10&10&11&12&13&14&15&16&17&18&19&20&21&22&23&24\\
            1&2&2&2&3&4&5&6&7&8&9&10&10&10&11&12&13&14&15&16&17&18&19&20&21&22&23\\
            1&3&3&3&3&4&5&6&7&8&9&10&10&10&10&11&12&13&14&15&16&17&18&19&20&21&22\\
            1&4&4&4&4&4&5&6&7&8&9&10&10&10&10&10&11&12&13&14&15&16&17&18&19&20&21\\
            0&5&4&4&4&4&4&5&6&7&8&9&10&11&11&11&11&12&12&13&14&15&16&17&18&19&20\\
            0&6&5&4&4&4&4&4&5&6&7&8&9&10&11&12&12&12&12&12&13&14&15&16&17&18&19\\
            0&7&6&5&4&4&4&4&4&5&6&7&8&9&10&11&12&13&12&12&12&13&14&15&16&17&18\\
            1&8&7&6&5&5&5&5&5&5&6&7&7&8&9&10&11&12&13&13&13&13&14&15&16&17&18\\
        };
        \foreach \x in {2,6,9}
        {
            \draw 
            ([xshift=-.125\pgflinewidth]mat-\x-1.south west) --   
            ([xshift=-.125\pgflinewidth]mat-\x-27.south east);
        }
        \begin{scope}[shorten >=7pt,shorten <= 7pt]
            \draw[->]  (mat-2-2.center) -- (mat-2-3.center);
            \draw[->]  (mat-2-3.center) -- (mat-2-4.center);
            \draw[->]  (mat-2-4.center) -- (mat-3-5.center);
            \draw[->]  (mat-3-5.center) -- (mat-4-6.center);
            \draw[->]  (mat-4-6.center) -- (mat-5-7.center);
            \draw[->]  (mat-5-7.center) -- (mat-6-8.center);
            \draw[->]  (mat-6-8.center) -- (mat-7-9.center);
            \draw[->]  (mat-7-9.center) -- (mat-8-10.center);
            \draw[->]  (mat-8-10.center) -- (mat-9-11.center);
            \draw[->]  (mat-9-11.center) -- (mat-10-12.center);
        \end{scope}

    \end{tikzpicture}
\end{document}
| improve this answer | |
  • Thank you so much. Should I add yshifts to get the horizontal lines exactly in the middle between two rows of numbers? – donald Mar 17 '19 at 10:52
  • Yes, as you want. – JPG Mar 18 '19 at 8:31

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.