用C欺骗随机数生成器

3

我想获取1到10之间的随机数。 实际上它是有效的,但当它在循环中时,我并没有真正获得随机数。

int randomNum;
srand ( (unsigned int)time(NULL) );
randomNum = rand() % 10;

我在这里和Google上花了数小时寻找解决方案,但似乎没有人真正解决它(或者我没搜索好)。我们从随机器中获得的价值取决于秒数(不是毫秒或其他编程语言中的某些东西),这就是为什么数字不是随机的原因。
此外,我不想下载C包,因为我在大学实验室运行代码,他们不会允许这样做。
有没有人对这个问题有创造性的解决方案?也许是一些数学函数?

8
在你的程序开头只调用一次srand函数。 - user1944441
你知道你不必传递时间给srand。你可以传递任何你想要的东西 - http://www.c-faq.com/lib/srand.html - user93353
3个回答

5
为了说明Sidoh的答案,我们需要进行以下操作。
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main(int argc, char** argv)
{
    int i;

    srand ( (unsigned int)time(NULL) );

    for (i = 0; i < 100; i++)
    {
        printf("%d ", 1 + (rand() % 10));
    }
    putchar('\n');
    return 0;
}

使用time()函数生成一个种子,针对此种子进行一次性的运算,结果如下:
7 10 2 4 4 4 2 1 7 7 10 4 3 10 2 9 6 9 2 9 7 10 4 1 1 8 2 4 8 1 2
4 2 3 9 5 8 1 7 4 9 8 10 1 8 1 1 5 1 4 5 7 3 9 10 3 6 1 9 3 4 10
8 5 2 7 2 2 9 10 5 9 8 4 1 7 7 2 3 7 5 8 6 10 8 5 4 3 7 2 8 2 1 7
7 5 5 10 6 5 

问题在于 <<<srand((unsigned int)time(NULL));>>> 在循环中。非常感谢,现在它可以工作了。 - Mockingbird
1
仅仅通过修改那种方式从分发的角度来看真的很糟糕。 - Randy Howard
@Randy 你能详细说明一下吗?听到原因会很有趣。 - Dave Newman
1
@DaveNewman 在评论中写太长了,但是这个链接详细地涵盖了这些问题。http://www.azillionmonkeys.com/qed/random.html - Randy Howard
@Randy 谢谢!我个人没有编写需要任何随机数生成器的生产代码,而且我模糊地意识到 rand() 是有问题的,但不知道原因。 - Dave Newman

2
不要多次播种随机数生成器。由于您的代码可能在同一秒钟内运行,每个rand查询使用相同的种子,因此每次都会得到相同的数字。

1

Dave Newman提供了一个非常好的答案。另外,你也可以尝试使用伪随机生成器,例如

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
{
    int a0; // this value will be our requirement
    int mod = 11; //this is the limit (0 - mod-1), here 10
    int a; // this stores the previous value of a0;
    int i; // loop variable
    int mul=25; //multiplicative factor
    int add=3; // additive factor
    int limit=100; // our limit
    srand ( (unsigned int)time(NULL) ); // initialize the seed
    a0 = rand() % mod;
    for(i=0;i<limit;i++)
    {
        printf("%d\t",a0);
        a = a0;
        a0 = (a * mul + add) % mod;
    }
    putchar('\n');
    return 0;
}

输出:
第一次运行:
2       10      4       3       1       8       0       6       7       9       2       10      4       3       1       8       0       6
7       9       2       10      4       3       1       8       0       6       7       9       2       10      4       3       1       8
0       6       7       9       2       10      4       3       1       8       0       6       7       9       2       10      4       3
1       8       0       6       7       9       2       10      4       3       1       8       0       6       7       9       2       10
4       3       1       8       0       6       7       9       2       10      4       3       1       8       0       6       7       9
2       10      4       3       1       8       0       6       7       9

第二个输出:
9       2       10      4       3       1       8       0       6       7       9       2       10      4       3       1       8       0
6       7       9       2       10      4       3       1       8       0       6       7       9       2       10      4       3       1
8       0       6       7       9       2       10      4       3       1       8       0       6       7       9       2       10      4
3       1       8       0       6       7       9       2       10      4       3       1       8       0       6       7       9       2
10      4       3       1       8       0       6       7       9       2       10      4       3       1       8       0       6       7
9       2       10      4       3       1       8       0       6       7


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接