[Tex/LaTex] Tikz fit variable number of nodes

fittikz-pgf

I would like to draw a rectangle or ellipse over some nodes I am drawing with tikz.

I know how to do that if the number of nodes is fixed: I just enumerate them.

I was wondering if there is a way to do that if I have a variable number of nodes?

Currently I use something like this:

     \node[draw,dotted,fit=(V1) (V2)] {};

But I have multiple nodes that I would like to fit in, and their number is given by a variable. Is there a work around this?
Ideally I would like something like this, that enumerates trough all nodes

\node[draw,dotted,fit=(V1) .. (V\numvis)] {};

Because of the layout of my nodes I can actually just use:

\node[draw,dotted,fit=(V1) (V\numvis)] {};

But I am interested in the more general way, so that I have something in case I change layouts.

Thanks!

Here is the complete working code:

\documentclass[11pt, twoside]{article}
\usepackage{tikz}
\usetikzlibrary{fit,matrix,chains,positioning,decorations.pathreplacing,arrows}


\begin{document}
\begin{figure}[h]
\centering
\def\layersep{2cm} % Gap between visible & hidden units
\def\numvis{8} % Number if visible units
\def\numhid{5} % Number of hidden units
\def\numhidsnd{5}
\def\numhidthrd{4}
\begin{tikzpicture}[
    node distance=\layersep,
    line/.style={shorten >=2pt,shorten <=2pt,>=stealth},
    downarrow/.style={<-,shorten >=2pt,shorten <=2pt,>=stealth, thick,},
    uparrow/.style={->,shorten >=2pt,shorten <=2pt,>=stealth, thick, color=red},
    doublearrow/.style={<->,shorten >=2pt,shorten <=2pt,>=stealth, thick},
    surround/.style={draw=blue, thick, dotted, rounded corners},
    ]
    \tikzstyle{neuron}=[circle,fill=black!25,minimum size=21pt,inner sep=0pt];
    \tikzstyle{visible neuron}=[neuron];
    \tikzstyle{hidden neuron}=[neuron];
    \tikzstyle{annot}=[text width=10em];

    % Iterate over visible units
    \foreach \name / \y in {1,...,\numvis}
        \node[visible neuron] (V\name) at (\y,0) {};

    % Iterate over hidden units
    \foreach \name / \y in {1,...,\numhid}
        % Calculate the appropriate offset for the hidden unit based on the
        % number of visible units.
        \pgfmathparse{\y + (\numvis - \numhid) * 0.5}
        \node[hidden neuron] (H\name) at (\pgfmathresult, \layersep) {};

     \foreach \name / \y in {1,...,\numhidsnd}
        % Calculate the appropriate offset for the hidden unit based on the
        % number of visible units.
        \pgfmathparse{\y + (\numhid - \numhidsnd) * 0.5}
        \node[hidden neuron] (H2\name) at (\pgfmathresult + 1.5, 2 * \layersep) {};

    \foreach \name / \y in {1,...,\numhidthrd}
        % Calculate the appropriate offset for the hidden unit based on the
        % number of visible units.
        \pgfmathparse{\y + (\numhidsnd - \numhidthrd) * 0.5}
        \node[hidden neuron] (H3\name) at (\pgfmathresult + 1.5, 3 * \layersep) {};

      \node[surround, dotted,fit=(V1)  (V\numvis)] (allvis) {};
      \node[surround, fit=(H1)  (H\numhid)] (allhid) {};
      \node[surround, fit=(H21)  (H2\numhidsnd)] (allhid2) {};
      \node[surround, fit=(H31)  (H3\numhidthrd)] (allhid3) {};

      \draw[uparrow] (allvis) -- (allhid);
      \draw[uparrow] (allhid) -- (allhid2);
      \draw[downarrow] (allvis) -- (allhid);
      \draw[downarrow] (allhid) -- (allhid2);

      \draw[doublearrow] (allhid2) -- (allhid3);

      \node[annot,left of=V1, node distance=1.5cm] (hl) {Visible layer};
      \node[annot,  above of=hl] (a) {Hidden layer};
      \node[annot, above of=a] (b){Hidden layer};
      \node[annot, above of=b] (c) {Hidden layer};

\end{tikzpicture}
\caption{Generative versus recognition weights in a DBN.}
\label{fig:rbm}
\end{figure}

\end{document}

Best Answer

With the foreach syntax, you can easely discribe the nodes you want to fit:

`\foreach \i in {1,...,5,9,\start,...,\end}

for example. \start and \end and some other are dynamicaly calculated.

enter image description here

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}

\begin{document}
\begin{tikzpicture}

\foreach \i in {1,...,25} {%
    \pgfmathsetmacro{\RandX}{(rand*5 + 1) - 2.5} ;
    \pgfmathsetmacro{\RandY}{(rand*5 + 1) - 2.5} ;
    \node (V\i) at (\RandX,\RandY) {\i} ;
    }

\xdef\Loop{}
\foreach \n in {1,2,4} {\xdef\Loop{\Loop(V\n)} }

\node[draw=red,fit=\Loop] {};

\end{tikzpicture}
\end{document}