从范围生成随机整数

新手上路,请多包涵

我需要一个函数,它会在给定范围内生成一个随机整数(包括边界值)。我没有不合理的质量/随机性要求;我有四个要求:

  • 我需要它快。我的项目需要生成数百万(有时甚至是数千万)随机数,而我当前的生成器函数已被证明是一个瓶颈。
  • 我需要它合理统一(使用 rand() 非常好)。
  • 最小-最大范围可以是从 <0, 1> 到 <-32727, 32727> 的任何值。
  • 它必须是可播种的。

我目前有以下 C++ 代码:

 output = min + (rand() * (int)(max - min) / RAND_MAX)

问题是它并不是真正统一的——只有当 rand() = RAND_MAX 时才返回 _最大值_(对于 Visual C++,它是 1/32727)。对于像 <-1, 1> 这样的小范围来说,这是一个主要问题,其中最后一个值几乎从不返回。

所以我拿起笔和纸,想出了以下公式(它建立在 (int)(n + 0.5) 整数舍入技巧的基础上):

在此处输入图像描述

但它仍然没有给我一个均匀的分布。使用 10000 个样本重复运行给我 37:50:13 的值 -1、0. 1 的比率。

有没有更好的公式? (甚至是整个伪随机数生成器函数?)

原文由 Matěj Zábský 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 802
2 个回答

一个快速,比你的更好,但仍然不是正确均匀分布的解决方案是

output = min + (rand() % static_cast<int>(max - min + 1))

除非范围的大小是 2 的幂,否则无论 rand() 的质量如何, 此方法都会产生 有偏差的非均匀分布。有关此方法质量的全面测试,请 阅读此

原文由 Mark B 发布,翻译遵循 CC BY-SA 3.0 许可协议

以下是 沃尔特提出 的想法。我写了一个独立的 C++ 类,它将在闭区间 [low, high] 中生成一个随机整数。它需要 C++11

 #include <random>

// Returns random integer in closed range [low, high].
class UniformRandomInt {

    std::random_device _rd{};
    std::mt19937 _gen{_rd()};
    std::uniform_int_distribution<int> _dist;

    public:

        UniformRandomInt() {
            set(1, 10);
        }
        UniformRandomInt(int low, int high) {
            set(low, high);
        }

        // Set the distribution parameters low and high.
        void set(int low, int high) {
            std::uniform_int_distribution<int>::param_type param(low, high);
            _dist.param(param);
        }

        // Get random integer.
        int get() {
            return _dist(_gen);
        }

};

示例用法:

 UniformRandomInt ur;
ur.set(0, 9); // Get random int in closed range [0, 9].

int value = ur.get()

原文由 stackoverflowuser2010 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏