【问题标题】:Semi-random numbers generation in C++ [duplicate]C ++中的半随机数生成[重复]
【发布时间】:2014-04-23 23:23:59
【问题描述】:

假设我有一组数字 x = {0, 0, 0, 0, 1, 2, 2, 3}。有没有办法让我使用 rand() 从这个列表中打印出随机数,以便随着时间的推移生成的数字的比例实际上是集合中数字的原始比例?换言之,0 的比例约为 0.5,1 为 0.125,2 为 0.25,3 为 0.125。

【问题讨论】:

  • 是的,这是可能的。现在出去做吧! :)
  • 你可以使用std::discrete_distribution
  • 将它们放入std::vector 并在其上使用std::shuffle。然后按打乱顺序使用它们。
  • 你要的是一个发行版,去看看en.cppreference.com/w/cpp/numeric/random
  • 只要 N 足够大,任何体面的伪随机数生成器都可以做到这一点。你能说得更具体点吗?

标签: c++ random


【解决方案1】:

您可以通过指定频率来做到这一点:

#include <iostream>
#include <random>

int main()
{
    using namespace std;
    mt19937_64 engine;

    discrete_distribution<int> numbers{4, 1, 2, 1};

    cout << numbers(engine) << endl;
}

【讨论】:

    【解决方案2】:

    快速方法:

    int values[8] = { 0, 0, 0, 0, 1, 2, 2, 3 };
    int randomIndex = rand() % 8; // NOTE: feel free to replace with & 0x7
    int randomValue = values[randomIndex];
    

    注意:提供均匀分布的值的数量应该是 2 的幂(2、4、8、16 等)。如果您需要其他号码,可以使用以下代码:

    int rand_range(int maxValue)
    {
        int mask = 0;
        int tmp = maxValue;
        int r;
    
        while (tmp > 0)
        {
            mask = (mask << 1) | 1;
            tmp= (tmp>> 1);
        }
    
        r = rand() & mask;
        while (r > maxValue)
            r = rand() & mask;
    
        return r;
    }
    
    int values[XXXX] = { 0, 0, 0, 0, 1, 2, 2, 3, ... };
    int randomIndex = rand_range(XXXX-1); // NOTE: -1 as maxValue is inclusive
    int randomValue = values[randomIndex];
    

    【讨论】:

    • 这比discrete_distribution的优势在于你不限于0..n
    • 结果可能有偏差。根据所需的精度,这可能是个问题。
    • @MatthiasB 你的意思是%的用法吗?
    • 是的。据我所知,rand 与模数结合不会生成完全均匀分布的数字范围。
    • @MatthiasB 用于任意除数 - 你是对的,对于 8 - 它将提供均匀分布
    猜你喜欢
    • 2019-03-30
    • 2012-12-17
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 2012-05-27
    相关资源
    最近更新 更多