【问题标题】:Generate either 0 or 1 and not in between生成 0 或 1,而不是介于两者之间
【发布时间】:2017-09-17 11:05:09
【问题描述】:
int random(){
    double x = ((double) rand() / (RAND_MAX)); // this i tried but only 0
    return x;
} 

我如何随机生成 0 或 1 供井字游戏玩家玩

【问题讨论】:

  • 如果您有C++11,那么std::bernoulli_distribution 可能对您有用。
  • @Galik 这是一个很棒的答案。请给出答案?
  • 就像rand() % 2一样简单。

标签: c++ random


【解决方案1】:

如果您有C++11,您可以使用新标准<random> 库。特别是std::bernoulli_distribution 分布给出truefalse 结果(默认分别可转换为10)。

// returns true or false
bool randomly_true(double p = 0.5)
{
    thread_local static std::mt19937 mt{std::random_device{}()};
    thread_local static std::bernoulli_distribution d;
    return d(mt, std::bernoulli_distribution::param_type{p});
}

int main()
{
    for(int i = 0; i < 30; ++i)
        std::cout << randomly_true() << '\n';
}

输出:(样本)

0
0
0
1
0
1
1
1
0
1

如果您总是想要10 整数值而不是truefalse 布尔值,您可以通过从函数返回int 来强制转换:

// returns 1 or 0
int randomly_true(double p = 0.5)
{
    thread_local static std::mt19937 mt{std::random_device{}()};
    thread_local static std::bernoulli_distribution d;
    return d(mt, std::bernoulli_distribution::param_type{p});
}

注意:您应该优先使用此库而不是 rand(),因为 rand() 无法保证质量,并且可能实施得很差。

【讨论】:

  • 而且通常你应该使用这个库而不是 C 风格的 rand(),后者因低质量实现而臭名昭著。
  • 值得注意的是,使用 Mersenne Twister 及其 2.5 KiB 的状态加上带有浮点计算的伯努利分布(当你可以只取 MT 输出的任何位时)来决定它是抽动还是tac 这很可笑。保留一些最不起眼的 LCG(或者,甚至更好,保留 XorShift 家族的任何成员)会非常好。难怪他们说软件不断扩展来做同样的事情,浪费了不断增加的硬件资源。
  • @MatteoItalia 在实际应用程序中,您将重复使用相同的随机数生成器来满足所有随机需求,并且分布应该只提取每次调用所需的位数(它们是有状态的)。如果您需要的话,标准库还提供 LCG。
  • 如果您从 RNG 输出中选择一个位,请避免使用最低有效位。一些 RNG 具有非常非随机的 LSB:010101010101... 在返回中间的某个位置选择一点。
猜你喜欢
  • 2020-06-14
  • 2012-04-10
  • 2015-02-20
  • 2021-09-28
  • 2016-01-08
  • 2012-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多