\forloop 内的 \rand 创建相同的值

\forloop 内的 \rand 创建相同的值

我尝试创建一个包含随机条目的表格...通过浏览标签,我在随机数生成器上找到了一些帮助,并尝试使用lcg

令人惊讶的是,我似乎一次又一次地创建相同的随机数,无论我选择什么作为种子......有人知道吗?

5x5 表的代码:

\chgrand[first=0, last=4, counter=kids]
\begin{tabular}{rrrrr}
\forloop{row_number}{1}{\value{row_number} < 6}{%%
    \forloop{col_number}{1}{\value{col_number} < 5}{%%%
       \rand\arabic{kids} & 
    }%%%
    \rand\arabic{kids}
    \\ }%%
\end{tabular}

创建:

4 4 4 4 4
4 4 4 4 4
4 4 4 4 4
4 4 4 4 4
4 4 4 4 4

对我来说看起来并不随机......

我尝试将其更改\rand\rand\rand,所有条目都更改为“3”。因此,我推测每次调用时\rand它都会从相同的种子开始,但我不明白为什么,因为种子是在之前声明的\forloop。或者不是吗?

答案1

问题是你在表格单元格内执行此操作,而 TeX 不太喜欢这样。最好在制作表格之前建立标记列表:

\documentclass{article}
\usepackage{lcg,forloop}
\newtoks\dierckxtoks
\newcounter{row_number}\newcounter{col_number}

\begin{document}

\chgrand[first=0, last=4, counter=kids]
\dierckxtoks={}

\forloop{row_number}{1}{\value{row_number} < 6}{% 
  \forloop{col_number}{1}{\value{col_number} < 5}{%  
     \rand
     \edef\x{\the\dierckxtoks\arabic{kids} &}
     \dierckxtoks\expandafter{\x}%
  }%  
  \rand
  \edef\x{\the\dierckxtoks\arabic{kids} \noexpand\\}
  \dierckxtoks\expandafter{\x}%
}  

\begin{tabular}{rrrrr}
\the\dierckxtoks
\end{tabular}

\end{document}

在此处输入图片描述

另一方面,正如我的第一条评论所示,还有 444444444是一系列随机数。:-)


强制性的expl3解决方案。

\documentclass{article}
\usepackage{lcg}
\newcounter{randnumb}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\randomtabular}{ O{randnumb} m m m m }
% #1 = counter name (optional default randnumb)
% #2 = lowest value
% #3 = highest value
% #4 = rows
% #5 = columns
 {
  \chgrand[first=#2, last=#3, counter=#1]
  \dierckx_random_tabular:nnn {#1}{#4}{#5}
 }
\tl_new:N \l_dierckx_tabular_tl
\cs_new_protected:Npn \dierckx_random_tabular:nnn #1 #2 #3
 {
  \tl_clear:N \l_dierckx_tabular_tl
  \prg_replicate:nn { #2 }
   {
    \prg_replicate:nn { #3 - 1 }
     {
      \rand
      \tl_put_right:Nx \l_dierckx_tabular_tl { \arabic{#1} & }
     }
    \rand
    \tl_put_right:Nx \l_dierckx_tabular_tl { \arabic{#1} }
    \tl_put_right:Nn \l_dierckx_tabular_tl { \\ }
   }
  \begin{tabular}{*{#3}{r}}
  \l_dierckx_tabular_tl
  \end{tabular}
 }
\ExplSyntaxOff

\begin{document}

\randomtabular{0}{9}{6}{4}

\randomtabular[kids]{0}{4}{5}{5}

\end{document}

在此处输入图片描述


使用随机数工具的另一种解决方案pgf

\documentclass{article}
\usepackage{pgf}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\randomtabular}{ m m m m }
% #1 = lowest value
% #2 = highest value
% #3 = rows
% #4 = columns
 {
  \dierckx_random_tabular:nnnn {#1}{#2}{#3}{#4}
 }
\tl_new:N \l__dierckx_tabular_tl
\int_new:N \l__dierckx_random_number_int
\cs_new_protected:Npn \dierckx_random_tabular:nnnn #1 #2 #3 #4
 {
  \tl_clear:N \l_dierckx_tabular_tl
  \prg_replicate:nn { #3 }
   {
    \prg_replicate:nn { #4 - 1 }
     {
      \dierckx_get_rand:nn { #1 } { #2 }
      \tl_put_right:Nx \l_dierckx_tabular_tl { \int_to_arabic:n { \l__dierckx_random_number_int } & }
     }
    \dierckx_get_rand:nn { #1 } { #2 }
    \tl_put_right:Nx \l_dierckx_tabular_tl { \int_to_arabic:n { \l__dierckx_random_number_int } }
    \tl_put_right:Nn \l_dierckx_tabular_tl { \\ }
   }
  \begin{tabular}{*{#3}{r}}
  \l_dierckx_tabular_tl
  \end{tabular}
 }
\cs_new_protected:Npn \dierckx_get_rand:nn #1 #2
 {
  \pgfmathrandominteger{ \l__dierckx_random_number_int } { #1 } { #2 }
 }
\ExplSyntaxOff

\begin{document}

\randomtabular{0}{9}{6}{4}

\bigskip

\randomtabular{0}{4}{5}{5}

\end{document}

不再有可选参数,但它似乎并不是真正必要的。


第一个解决方案的变体expl3是用零填充数字,以使其长度与所选的最高数字相同。

\documentclass{article}
\usepackage{lcg}
\newcounter{randnumb}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\randomtabular}{ O{randnumb} m m m m }
% #1 = counter name (optional default randnumb)
% #2 = lowest value
% #3 = highest value
% #4 = rows
% #5 = columns
 {
  \int_set:Nn \l_dierckx_padto_int { \tl_count:n { #3 } }
  \chgrand[first=#2, last=#3, counter=#1]
  \dierckx_random_tabular:nnn {#1}{#4}{#5}
 }
\tl_new:N \l_dierckx_tabular_tl
\tl_new:N \l_dierckx_temp_tl
\int_new:N \l_dierckx_padto_int

\cs_new_protected:Npn \__dierckx_padnumber:nn #1 #2
 {
  \tl_set:Nx \l_dierckx_temp_tl { \arabic{#1} }
  \tl_set:Nx \l_dierckx_temp_tl
   {
    \prg_replicate:nn { \l_dierckx_padto_int - \tl_count:N \l_dierckx_temp_tl } { 0 }
    \l_dierckx_temp_tl
   }
  \tl_put_right:Nx \l_dierckx_tabular_tl { \l_dierckx_temp_tl #2 }
 }

\cs_new_protected:Npn \dierckx_random_tabular:nnn #1 #2 #3
 {
  \tl_clear:N \l_dierckx_tabular_tl
  \prg_replicate:nn { #2 }
   {
    \prg_replicate:nn { #3 - 1 }
     {
      \rand
      \__dierckx_padnumber:nn { #1 } { & }
     }
    \rand
    \__dierckx_padnumber:nn { #1 } { }
    \tl_put_right:Nn \l_dierckx_tabular_tl { \\ }
   }
  \begin{tabular}{*{#3}{r}}
  \l_dierckx_tabular_tl
  \end{tabular}
 }
\ExplSyntaxOff

\begin{document}

\randomtabular{0}{100000}{6}{4}

\end{document}

在此处输入图片描述

答案2

我找到了一个快速tikz解决方案。您可以使用它\pgfmathsetseed{}来获得可重复的结果。

\documentclass{article}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
    \foreach \x in {1,...,5}{
        \foreach \y in {1,...,5}{
        \pgfmathrandominteger{\a}{0}{4}
            \node at (\x/2,\y/2){\a};
        }
    }
\end{tikzpicture}


\end{document}

结果:

截屏

答案3

这是一个简短的例子。该\tal命令生成一个随机数。该\sekscifret命令使用\tal并生成并写入一个 6 位数字。表格内的循环将这些数字插入列和行中。

\documentclass{article}

\usepackage[english]{babel}
\usepackage{lcg}
\usepackage{forloop}

\newcounter{ct}
\newcounter{ctA}
\newcommand{\tal}{\chgrand[first=0,last=9,counter=randTal]\rand\arabic{randTal}}
\newcommand{\sekscifret}{\forloop{ct}{1}{\value{ct} < 7}{\tal}}

\begin{document}

\begin{tabular}{r r r r}

\forloop{ctA}{1}{\value{ctA} < 7}{

\sekscifret&\sekscifret&\sekscifret&\sekscifret
\\}

\end{tabular}

\end{document}

相关内容