以给定的概率获得真或假

use*_*084 7 c++ random numbers probability

我正在尝试用c ++编写一个函数,它将根据给定的概率返回true或false.因此,例如,如果给定的概率是0.634,那么63.4%的函数将返回true.我尝试了一些不同的东西,但都失败了.有帮助吗?

Joe*_*e Z 14

如果你想在C++ 11中这样做,你可以使用它的各种随机数引擎,结合使用uniform_real_distribution来提供一个好的结果.以下代码演示:

#include <random>

std::knuth_b rand_engine;  // replace knuth_b with one of the engines listed below
std::uniform_real_distribution<> uniform_zero_to_one(0.0, 1.0);

bool random_bool_with_prob( double prob )  // probability between 0.0 and 1.0
{
    return uniform_zero_to_one(rand_engine) >= prob;
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用bernoulli_distribution,直接为您bool提供指定概率.它需要的概率是返回true的概率,所以它正是你需要的:

#include <random>

std::knuth_b rand_engine;  // replace knuth_b with one of the engines listed below

bool random_bool_with_prob( double prob )  // probability between 0.0 and 1.0
{
    std::bernoulli_distribution d(prob);
    return d(rand_engine);
}
Run Code Online (Sandbox Code Playgroud)

如果您的概率是固定的,那么您可以将其移出函数,如下所示:

#include <random>

std::knuth_b rand_engine;  // replace knuth_b with one of the engines listed below
std::bernoulli_distribution random_bool_generator( prob );  // replace "prob" with your probability

bool random_bool()
{
    return random_bool_generator( rand_engine );
}
Run Code Online (Sandbox Code Playgroud)

或者如果你想要更加漂亮,你可以将它们绑在一起:

#include <random>
#include <functional>

std::knuth_b rand_engine;  // replace knuth_b with one of the engines listed below
std::bernoulli_distribution random_bool_generator( prob );  // replace "prob" with your probability

auto random_bool = std::bind( random_bool_generator, rand_engine )

// Now call random_bool() to get your random boolean with the specified probability.
Run Code Online (Sandbox Code Playgroud)

您可以knuth_b使用任何标准引擎进行更换:

  • std::linear_congruential_engine
  • std::mersenne_twister_engine
  • std::subtract_with_carry_engine

或更多,以上的版本,参数化各种方式.我的参考列出了以下内容:

  • std::default_random_engine (实施定义.)
  • std::minstd_rand0
  • std::minstd_rand
  • std::mt19937
  • std::mt19337_64
  • std::ranlux24_base
  • std::ranlux48_base
  • std::ranlux24
  • std::ranlux48
  • std::knuth_b

如果这还不够,有一些标准适配器可以进一步扰乱随机数序列:

  • std::discard_block_engine 它通过每次丢弃给定数量的生成值来适应引擎.
  • std::independent_bits_engine它使引擎适应产生具有指定位数的随机值.(对您的特殊需求并不重要.)
  • std::shuffle_order_engine 它通过排列其生成值的顺序来适应引擎.

第二个列表中的生成器派生自第一个列表中的基本生成器,具有特定参数,适配器或两者.例如,根据我的参考书,knuth_b相当于shuffle_order_engine< linear_congruential_engine< uint32_t, 16807, 0, 2147483647>, 256>.(C++标准库,第二版,Nicolai Josuttis,一篇很棒的参考书.)

您可以在线查找更多信息,包括此简介:http: //en.wikipedia.org/wiki/C++11#Extensible_random_number_facility

这里有更多文档:http: //en.cppreference.com/w/cpp/numeric/random

您可能希望修改rand_engine上面的声明以提供种子.上面的示例使用默认种子.如果您想要一个不同的种子,请参阅cppreference.com了解如何播种它.

  • [`std :: bernoulli_distribution`](http://en.cppreference.com/w/cpp/numeric/random/bernoulli_distribution)将比std :: uniform_real_distribution做得更好. (3认同)

rab*_*sky 5

#include <stdlib.h>
bool prob_true(double p){
    return rand()/(RAND_MAX+1.0) < p;
}
Run Code Online (Sandbox Code Playgroud)

逻辑:

rand()0返回和之间的随机数RAND_MAX(包括两者),每个数字的概率相等。因此,通过将结果除以我们得到和RAND_MAX之间的随机数。这使我们能够选择一个区域 - 在您的示例中为该段的 63.4%,例如从到- 并检查结果是否落在该区域内。0100.634

现在是棘手的部分:我们不想同时得到01!为什么?因为我们希望概率0永远不会为真,所以我们需要<p(而不是<=p) - 这样p=0你就永远不会为真。

但是,如果你也能得到1这样的结果,那么在p=1极小概率的情况下你会得到错误的结果!

这就是为什么不是除以而是MAX_RAND除以MAX_RAND+1.0。另请注意,我添加了1.0而不是1将数字转换为双精度(否则我可能会溢出 if MAX_RAND==INT_MAX

最后,这是一个没有除法的替代实现:

#include <stdlib.h>
bool prob_true(double p){
    return rand() < p * (RAND_MAX+1.0);
}
Run Code Online (Sandbox Code Playgroud)