随机布尔值

33

我想在C++中生成一个随机的整数,要么是0,要么是1。目前每次运行这段代码都会收到一个0,不确定问题出在哪里。这里的问题是什么?

#include <ctime>
#include <cstdlib>

srand(time(0));
int randomval = rand() % 2;
cout << randomval << endl;

7
你运行了多少次它? - Seth Carnegie
尝试将最后两行放入循环中并打印多个值。 - John Gordon
这让我想起了一个抛硬币的 iPhone 应用程序。 - Mahesh
1
这个测试用例甚至都不合法,因为你没有函数块。所以你正在运行其他程序。如果我们连看都看不到,我们怎么分析它呢? - Lightness Races in Orbit
8个回答

218

这被称为“倒霉”。再试一次。


3
我在for循环中多次运行了100次。希望你是对的。 - Rich Byden
15
你是否在每次迭代中调用了srand()?那么它应该会保持相同的数字直到下一秒。 - Michael Krelin - hacker
1
@RichByden,你认为在那个循环中time()会改变多少次? - Mark Ransom
2
你说得对,我真的不确定我当时在想什么。 - Rich Byden
5
@0605002,我明白了。这就是名声了;-) - Michael Krelin - hacker
显示剩余9条评论

28

我知道这是一个较旧的问题,但我认为这个答案可以正确回答这个问题。

不要在每次运行代码时重新设置随机数生成器的种子。

通过每次都将它种子设为相同的值,你只会得到相同的“随机”数字。请记住,这是一个伪随机数生成器,所以基于种子值,会生成一个“随机”的数字。因此,如果你每次都使用相同的数字来设置种子值,那么每次你都会得到相同的数字。

解决方法是只在程序执行一次中调用srand(time(NULL))。然后,每次调用rand()时,都会给你不同的数字。


4

理论上,你有50%的机会得到0,还有50%的机会得到1。你可以尝试使用不同的模数进行测试-比如100,看看它是否起作用。我敢确定它会有效。

你只是运行了这段代码几次,还不够。

测试它的另一个想法:

srand(time(0));
for( int i = 0; i < 1000000; ++i )
{
    assert( 0 == ( rand() % 2 ) );
}

11
不要在循环中使用srand!在程序开始时进行一次即可,以后不再需要。 - Lightness Races in Orbit
@UncleBens - 因为 @OP 不相信 rand 函数返回(伪)随机值? - Kiril Kirov

2
bool random() {
    if (rand() % 2 == 0)
        return true;
    else return false;
}

2
为什么要测试然后返回你已经测试过的内容呢?请记住,如果你的if语句只有return true,而else语句只有return false,那么最好直接返回你所测试的内容。例如:return rand() % 2 == 0; - v010dya

2

我想补充一点,当你使用 srand(time(0)); 时,“随机数” 在同一秒内始终相同。当我尝试运行您的程序10000次并按uniq分组时,我发现数字在1秒钟内不会改变。

for i in `seq 1 10000`; do ./a.out; done | uniq -c
    693 0
   3415 1
    675 0
    673 1
    665 0
    674 1
    668 0
    711 1
    694 0
    673 1
    459 0

0

只需调用srand(time(NULL));一次。

然后使用像这样的循环,您将始终以此方式获得0或1。

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

srand(time(NULL));

for (i=0;i<10;i++)
{
    printf("%d\n",rand() % 2);
    i++;
}

return 0;

或许需要添加一些解释说明何时需要调用srand函数。 - Tom

0

尽管您的代码表明您希望它们等可能地接收,但您并没有说明这一点,也许您只是认为否则不可能。如果您想要不同的分布,并且愿意重写您的代码(并使其符合C++11标准),您可以执行以下操作:

    const double chance = 0.3; // this is the chance of getting true, between 0 and 1;
    std::random_device rd;
    std::mt19937 mt(rd());
    std::bernoulli_distribution dist(chance);
    bool result = dist(mt);

如果您需要在循环中执行此操作,请仅重复最后一个语句dist(mt),将所有生成的对象保持不变,而无需重新创建它们。


-2

你没有检查任何东西。请使用:

#include <ctime>
#include <cstdlib>

srand(time(0));
int randomval = rand() % 2 == 0;
cout << randomval << endl;

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