我知道 bash 函数 $RANDOM 在一个范围内生成随机整数,但是,这些数字是否应该遵循(或近似)均匀离散分布?
问问题
2385 次
2 回答
7
我只是打印了 $RANDOM 一百万次,把它变成了一个直方图,然后用 gnumeric 来查看它,图表显示了一个非常正态的分布!
for n in `seq 1 1000000`; do echo $RANDOM ; done > random.txt
gawk '{b=int($1/100);a[b]++};END{for (n in a) {print n","a[n]}}' random.txt > hist.csv
gnumeric hist.csv
因此,如果您想要近似线性分布,请使用 $(( $RANDOM % $MAXIMUM )) 并且不要将其与大于 16383 或 8192 的 $MAXIMUM 一起使用以确保安全。如果您想要非常大的数字,您可以多次连接 $RANDOM % 1000 ,只要您注意前导零。
如果您确实想要正态分布,请使用 $(( $RANGE * $RANDOM / 32767 + $MINIMUM)),并记住这只是整数数学。
于 2013-09-20T20:19:28.763 回答
5
Bash 文档实际上并没有这么说:
随机的
每次引用此参数时,都会生成一个介于 0 和 32767 之间的随机整数。为该变量分配一个值会为随机数生成器提供种子。
读到这一点,我当然会假设它是线性的。恕我直言,它是其他任何东西都没有多大意义。
但是查看 bash 源代码, 的实现$RANDOM
旨在产生线性分布(这是来自variable.c
bash 4.2源代码):
/* The random number seed. You can change this by setting RANDOM. */
static unsigned long rseed = 1;
static int last_random_value;
static int seeded_subshell = 0;
/* A linear congruential random number generator based on the example
one in the ANSI C standard. This one isn't very good, but a more
complicated one is overkill. */
/* Returns a pseudo-random number between 0 and 32767. */
static int
brand ()
{
/* From "Random number generators: good ones are hard to find",
Park and Miller, Communications of the ACM, vol. 31, no. 10,
October 1988, p. 1195. filtered through FreeBSD */
long h, l;
/* Can't seed with 0. */
if (rseed == 0)
rseed = 123459876;
h = rseed / 127773;
l = rseed % 127773;
rseed = 16807 * l - 2836 * h;
#if 0
if (rseed < 0)
rseed += 0x7fffffff;
#endif
return ((unsigned int)(rseed & 32767)); /* was % 32768 */
}
正如评论所暗示的,如果您想要好的随机数,请使用其他东西。
于 2013-04-11T02:04:07.937 回答