bash函数$ RANDOM是否应该具有均匀分布?

pap*_*rin 5 linux bash statistics

我知道bash函数$ RANDOM会在一定范围内生成随机整数,但是这些数字是否应该遵循(或近似)均匀的离散分布?

小智 7

我刚刚打印了$ RANDOM一百万次,将其转换为直方图,并使用数字进行了查看,该图显示了非常正态分布!

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
Run Code Online (Sandbox Code Playgroud)

因此,如果要近似线性分布,请使用$((($ RANDOM%$ MAXIMUM)),并且不要使用大于16383或8192的$ MAXIMUM来保证安全。如果您想要很大的数字,则可以将$ RANDOM%1000多次连接,只要注意前导零即可。

如果您确实想要正态分布,请使用$((($ RANGE * $ RANDOM / 32767 + $ MINIMUM)),请记住,这只是整数数学。


Kei*_*son 5

猛砸文件实际上并没有这么说:

随机的

每次引用此参数时,都会生成一个 0 到 32767 之间的随机整数。为该变量分配一个值作为随机数生成器的种子。

读到这里,我当然会假设它是线性的;恕我直言,它是其他任何东西都没有多大意义。

但是查看 bash 源代码, 的实现$RANDOM旨在产生线性分布(这是来自variable.cbash 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 */
}
Run Code Online (Sandbox Code Playgroud)

正如评论所暗示的那样,如果您想要好的随机数,请使用其他东西。

  • Thomposon:这个名字中的线性这个词来自生成器的函数:X_{n+1}=aX_{n}+c 是一个线性函数。 (2认同)