在Linux中。有一个srand()函数,您可以在其中提供种子,并且在后续调用random()函数时它将保证相同的伪随机数序列。
让我们说,我想通过记住这个种子值来存储这个伪随机序列。
此外,假设我想在此伪随机序列中获得第10万个数字。
一种方法是使用srand()提供种子号,然后调用random()10万次,并记住这个数字。
是否有更好的方法可以跳过伪随机列表中的所有99,999个其他数字,并直接获取列表中的第10万个数字。
感谢,
米
答案 0 :(得分:2)
我不确定在任何平台上实施rand
是否有明确的标准;但是,从GNU Scientific Library中选择一个:
- 生成器:gsl_rng_rand
这是BSD rand生成器。它的顺序是
x n + 1 =(a x n + c)mod m
a = 1103515245,c = 12345且m = 2 31 。种子指定初始值x 1 。该发生器的周期为2 31 ,每个发生器使用1个字存储器。
所以要“知道”x n 要求你知道x n-1 。除非有一些明显的模式我缺少,否则你不能在没有计算它之前的所有值的情况下跳转到一个值。 (但每次rand
实施都不一定如此。)
如果我们从x 1 ...
开始它很快失控。这个功能容易减少吗?我认为不是。
(有一个系列的统计短语,其中x n 取决于x n-1 - 有人能提醒我这个词是什么吗?)< /子>
答案 1 :(得分:1)
如果它们在您的系统上可用,则可以使用rand_r
代替rand
&amp; srand
,或initstate
和setstate
使用random
。 rand_r
以unsigned *
为参数,存储其状态。多次调用rand_r
后,保存此无符号整数的值,并在下次将其用作起始值。
对于random()
,请使用initstate
而不是srandom
。保存状态缓冲区的内容以用于要还原的任何状态。要恢复状态,请填写缓冲区并调用setstate
。如果缓冲区已经是当前状态缓冲区,则可以跳过对setstate
的调用。
答案 2 :(得分:1)
这是使用BSD rand()
函数从@ Mark的答案开发的。
rand1()
计算第n个随机数,从seed
开始,经过n次计算。
rand2()
使用快捷方式计算相同内容。它可以一次性升级到2 ^ 24-1步。在内部,它只需要24步。
如果BSD随机数生成器对你来说足够好,那么这就足够了:
#include <stdio.h>
const unsigned int m = (1<<31)-1;
unsigned int a[24] = {
1103515245, 1117952617, 1845919505, 1339940641, 1601471041,
187569281 , 1979738369, 387043841 , 1046979585, 1574914049,
1073647617, 285024257 , 1710899201, 1542750209, 2011758593,
1876033537, 1604583425, 1061683201, 2123366401, 2099249153,
2051014657, 1954545665, 1761607681, 1375731713
};
unsigned int b[24] = {
12345, 1406932606, 1449466924, 1293799192, 1695770928, 1680572000,
422948032, 910563712, 519516928, 530212352, 98880512, 646551552,
940781568, 472276992, 1749860352, 278495232, 556990464, 1113980928,
80478208, 160956416, 321912832, 643825664, 1287651328, 427819008
};
unsigned int rand1(unsigned int seed, unsigned int n)
{
int i;
for (i = 0; i<n; ++i)
{
seed = (1103515245U*seed+12345U) & m;
}
return seed;
}
unsigned int rand2(unsigned int seed, unsigned int n)
{
int i;
for (i = 0; i<24; ++i)
{
if (n & (1<<i))
{
seed = (a[i]*seed+b[i]) & m;
}
}
return seed;
}
int main()
{
printf("%u\n", rand1 (10101, 100000));
printf("%u\n", rand2 (10101, 100000));
}
适应任何线性同余发生器并不难。我用一种具有正确整数类型(Haskell)的语言计算了这些表,但是我可以用C语言中的另一种方式计算它们,只使用几行代码。
答案 3 :(得分:0)
如果您总是想要第100,000件商品,请将其存放以供日后使用。
或者您可以生成序列并存储...并稍后通过索引查询特定元素。