如何获得一个随机非零整数?

如何获得一个随机非零整数?

我想\a生成一个介于 -5 和 5 之间的随机非零整数。

一种方法是列出从 -5 到 5 的所有整数(不包括零),然后从该列表中随机抽取。这没问题,但如果我想要\a一个介于 -500 和 500 之间的非零整数,那么这种方法就不太适用了。

是否可以对以下代码进行更简单的调整以专门排除\a=0 的可能性?

\documentclass{article}

\usepackage{ifthen}
\usepackage{pgf}
 \pgfmathsetseed{\number\pdfrandomseed}

\newcommand{\InitVariables}
{\pgfmathsetmacro{\a}{int(random(0,10)-5)}}

\begin{document}

\InitVariables

\a

\end{document}

答案1

在 1 和 X 之间选择一个随机数(从而避免 0),并根据均匀分布将其与 1 或 -1 相乘(从而获得一个符号):

enter image description here

\documentclass{article}

\usepackage{tikz}
\pgfmathsetseed{\number\pdfrandomseed}

\newcommand{\InitVariables}{%
  \pgfmathsetmacro{\a}{int(ifthenelse(rand > 0, 1, -1)*random(1,5))}%
}

\begin{document}

\foreach \x in {1,...,100}{\InitVariables$\a$ }

\end{document}

答案2

第一次计算仅选择所需的随机值数量。不含 0 的包含范围 [-5, 5] 有 10 个值。

\pgfmathsetmacro{\a}{random(0,9)-5}% range [-5, 4]

这样,负值就处于正确的范围内了。非负值增加一,将范围从 [0, 4] 移动到 [1, 5]。

\pgfmathsetmacro{\a}{int(ifthenelse(\a<0, \a, \a + 1)}%

完整示例:

\documentclass{article}
\usepackage{pgf}
\usepackage{pgffor}
\pgfmathsetseed{\number\pdfrandomseed}

\newcommand{\InitVariables}{%
  \pgfmathsetmacro{\a}{random(0,9)-5}%
  \pgfmathsetmacro{\a}{int(ifthenelse(\a<0, \a, \a + 1)}%
}

\begin{document}

\noindent
\foreach \i in {0, ..., 200} {%
  \InitVariables
  \a\space
}

\end{document}

Result

以最小值和最大值作为宏的版本:

\documentclass{article}

\usepackage{pgf}
\usepackage{pgffor}
\pgfmathsetseed{\number\pdfrandomseed}

\newcommand*{\RandomMinimum}{-300}
\newcommand*{\RandomMaximum}{700}

\newcommand*{\InitVariables}{%
  \pgfmathsetmacro{\a}{%
     \RandomMinimum + random(0, int(\RandomMaximum - int(\RandomMinimum)))
  }%
  \pgfmathtruncatemacro{\a}{ifthenelse(\a<0, \a, \a + 1}%
}

\begin{document}

\noindent
\foreach \i in {0, ..., 200} {%
  \InitVariables
  \a\space
}

\end{document}

Result

答案3

生成一个介于 0 和 2 之间的数字X –1,然后对其进行归一化:如果小于X, 减去X,否则减去X并加 1。

\documentclass{article}

\newcommand{\randomdef}[2]{%
  \edef#1{%
    \expandafter\randomdefnormalize\pdfuniformdeviate\numexpr#2*2\relax\foo{#2}%
  }%
}
\def\randomdefnormalize#1\foo#2{%
  \ifnum#1<#2
    \the\numexpr#1-#2\relax
  \else
    \the\numexpr#1-#2+1\relax
  \fi
}

\begin{document}

\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$

\end{document}

enter image description here

当然,PGF 功能也可以实现同样的效果。

带有xparseexpl3;还有一个接口可以扩展获取所需间隔内的数字。这里我使用了一种不同的策略:在间隔内生成随机数 –XX –1;如果是正数,则加 1。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\randomdef}{mm}
 {
  \wcla_random_def:Nn #1 { #2 }
 }
\DeclareExpandableDocumentCommand{\randomget}{m}
 {
  \wcla_random_get:n { #1 }
 }
\cs_new_protected:Nn \wcla_random_def:Nn
 {
  \cs_set:Npx #1 { \wcla_random_get:n { #2 } }
 }
\cs_new:Nn \wcla_random_get:n
 {
  \__wcla_random_get:f { \fp_eval:n { randint(-#1,#1-1) } }
 }
\cs_new:Nn \__wcla_random_get:n
 {
  \int_compare:nTF { #1 < 0 } { #1 } { \fp_eval:n { #1+1 } }
 }
\cs_generate_variant:Nn \__wcla_random_get:n { f }
\ExplSyntaxOff

\begin{document}

\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$,\space
\randomdef{\arandom}{5}$\arandom$,\space\randomdef{\arandom}{5}$\arandom$

$\randomget{5}$, $\randomget{5}$, $\randomget{5}$, $\randomget{5}$,
$\randomget{5}$, $\randomget{5}$, $\randomget{5}$, $\randomget{5}$,
$\randomget{5}$, $\randomget{5}$, $\randomget{5}$, $\randomget{5}$,
$\randomget{5}$, $\randomget{5}$, $\randomget{5}$, $\randomget{5}$

\end{document}

enter image description here

答案4

也许是的递归定义\InitVariables

\documentclass{article}
\usepackage{ifthen}
\usepackage{tikz}
\pgfmathsetseed{\number\pdfrandomseed}

\newcommand{\InitVariables}
{\pgfmathsetmacro{\a}{int(random(1,10)-5)}%
\ifnum\a=0%
\InitVariables%
\fi}

\begin{document}

\foreach \x in {1,...,100}{\InitVariables\a}

\end{document}

循环运行 1000 次,并添加!。周围没有零:

enter image description here

相关内容