有没有办法从 TikZ 中的数组中提取随机样本?
例如,如果\def\myarray{{1, "two", 2+1, "IV", "cinq", "sechs", sin(\i*5)*14}}
定义一个数组,那么可能是一个随机的长度为 3 的样本"sechs", 2+1, "IV"
。
理想情况下,应该能够指定样本大小,以及是否必须进行替换抽样。
我正在寻找类似于sample
以下功能的东西R
:https://stat.ethz.ch/R-manual/R-devel/library/base/html/sample.html。
答案1
有一些不错的工具前列腺素用于播放随机序列的包,特别是命令\pgfmathrandomitem
可以完全按照您的要求执行。
更详细地说,MWE:
\documentclass{article}
\usepackage{pgf}
\pgfmathsetseed{\number\time}% set a "random" seed based on time
\pgfmathdeclarerandomlist{myarray}{{1}{two}{2+1}{IV}{cinq}{sechs}{sin(\i*5)*14}}
\begin{document}
\pgfmathrandomitem\myitem{myarray}\myitem
\pgfmathrandomitem\myitem{myarray}\myitem
\pgfmathrandomitem\myitem{myarray}\myitem
\pgfmathrandomitem\myitem{myarray}\myitem
\end{document}
生成:
一个警告:这将给出一个随机列表重复。如果你想避免重复,请参阅如何在 LaTeX 中生成避免重复的随机问题列表?。
编辑(添加无重复的随机序列)
正如我上面所说,为了生成不重复的随机序列,我们可以利用 Mark Wibrow 的代码如何在 LaTeX 中生成避免重复的随机问题列表?下面的代码将所有内容包装成一对宏:
\DefineRandomSequence
用于定义或设置我们要随机选择的序列。默认情况下,这将允许您生成此序列的随机元素重复但有 *-form,,\DefineRandomSequence*
可以生成随机元素无重复。\myitem
打印列表中的随机元素。如果生成的序列没有重复,则如果没有更多元素可供选择,则会返回错误。
为了定义*形式,\DefineRandomSequence
我使用\NewDocumentCommand
了解析包裹。
完整代码如下:
\documentclass{article}
\usepackage{pgf}
\usepackage{pgffor}% needed only for the examples
\usepackage{xparse}
% \DefineRandomSequence{<sequence>}: random elements with repeats
% \DefineRandomSequence*{<sequence>}: random elements without repeats
\NewDocumentCommand\DefineRandomSequence{sm}{%
\pgfmathsetseed{\number\time}% set a "random" seed based on time
\pgfmathdeclarerandomlist{myrandomlist}{#2}
\IfBooleanTF{#1}{\let\pgfsequencegenerator\pgfmathrandomitemwithoutreplacement}
{\let\pgfsequencegenerator\pgfmathrandomitem}
}
% \myitem: print random element of sequence
\newcommand\myitem{\pgfsequencegenerator\randomitem{myrandomlist}\randomitem}
\makeatletter
% Mark Wibrow: https://tex.stackexchange.com/questions/113987/how-do-i-generate-in-latex-a-list-of-random-questions-avoiding-repetitions
\def\pgfmathrandomitemwithoutreplacement#1#2{%
\pgfmath@ifundefined{pgfmath@randomlist@#2}{\pgfmath@error{Unknown random list `#2'}}{%
\edef\pgfmath@randomlistlength{\csname pgfmath@randomlist@#2\endcsname}%
\ifnum\pgfmath@randomlistlength>0\relax%
\pgfmathrandominteger{\pgfmath@randomtemp}{1}{\pgfmath@randomlistlength}%
\def\pgfmath@marshal{\def#1}%
\expandafter\expandafter\expandafter\pgfmath@marshal\expandafter\expandafter\expandafter{\csname pgfmath@randomlist@#2@\pgfmath@randomtemp\endcsname}%
% Now prune.
\c@pgfmath@counta=\pgfmath@randomtemp\relax%
\c@pgfmath@countb=\c@pgfmath@counta%
\advance\c@pgfmath@countb by1\relax%
\pgfmathloop%
\ifnum\c@pgfmath@counta=\pgfmath@randomlistlength\relax%
\else%
\def\pgfmath@marshal{\expandafter\global\expandafter\let\csname pgfmath@randomlist@#2@\the\c@pgfmath@counta\endcsname=}%
\expandafter\pgfmath@marshal\csname pgfmath@randomlist@#2@\the\c@pgfmath@countb\endcsname%
\advance\c@pgfmath@counta by1\relax%
\advance\c@pgfmath@countb by1\relax%
\repeatpgfmathloop%
\advance\c@pgfmath@counta by-1\relax%
\expandafter\xdef\csname pgfmath@randomlist@#2\endcsname{\the\c@pgfmath@counta}%
\else%
\pgfmath@error{Random list `#2' is empty}%
\fi%
}}
\makeatother
\begin{document}
With repeats:
\DefineRandomSequence{{1}{two}{2+1}{IV}{cinq}{sechs}{sin(\i*5)*14}}
\foreach \x in {1,...,5} { \myitem\space }
Without repeats:
\DefineRandomSequence*{{1}{two}{2+1}{IV}{cinq}{sechs}{sin(\i*5)*14}}
\foreach \x in {1,...,5} { \myitem\space }
\end{document}
输出结果如下: