c++ - 使用 uniform_int_distribution 与模数运算有什么优势?

标签 c++ c++11 random stl

根据以下结果,使用 % 运算在两个数字之间生成均匀随机整数几乎比使用 std::uniform_int_distribution 快 3 倍:有什么好的理由使用 std::uniform_int_distribution?

代码:

#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <random>

#include <cstdio>
#include <cstdlib>

using namespace std;

#define N 100000000

int main()
{

clock_t tic,toc;

for(int trials=0; trials<3; trials++)
{
    cout<<"trial: "<<trials<<endl;

    // uniform_int_distribution
    {
        int res = 0;
        mt19937 gen(1);
        uniform_int_distribution<int> dist(0,999);

        tic = clock();
        for(int i=0; i<N; i++)
        {
            int r = dist(gen);
            res += r;
            res %= 1000;
        }
        toc = clock();
        cout << "uniform_int_distribution: "<<(float)(toc-tic)/CLOCKS_PER_SEC << endl;
        cout<<res<<" "<<endl;

    }

    // simple modulus operation
    {
        int res = 0;
        mt19937 gen(1);

        tic = clock();
        for(int i=0; i<N; i++)
        {
            int r = gen()%1000;
            res += r;
            res %= 1000;
        }
        toc = clock();
        cout << "simple modulus operation: "<<(float)(toc-tic)/CLOCKS_PER_SEC << endl;
        cout<<res<<" "<<endl;

    }

    cout<<endl;
}

}

输出:

trial: 0
uniform_int_distribution: 2.90289
538 
simple modulus operation: 1.0232
575 

trial: 1
uniform_int_distribution: 2.86416
538 
simple modulus operation: 1.01866
575 

trial: 2
uniform_int_distribution: 2.94309
538 
simple modulus operation: 1.01809
575 

最佳答案

当您使用模数 (%) 映射例如的范围时,您将得到 统计偏差 rand() 到另一个区间。

例如假设 rand() 统一映射(无偏差)到 [0, 32767] 并且您想映射到 [0,4]rand() % 5。那么值 0、1 和 2 将平均产生 32768 次中的 6554 次,但值 3 和 4 仅产生 6553 次(因此 3 * 6554 + 2 * 6553 = 32768)。

偏差很小 (0.01%),但取决于您的应用程序,这可能是致命的。观看 Stephan T. Lavavej 的演讲“rand() considered harmful”了解更多详情。

关于c++ - 使用 uniform_int_distribution 与模数运算有什么优势?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32860654/

相关文章:

C++ 将 std::vector<Derived>* 转换为 std::vector<Base> ...?

c++ - 使用链表在 C++ 中实现邻接表

c++ - QML TreeView 按级别或自定义委托(delegate)显示节点

c++ - 如何扩展基类的参数包并调用每个基类的成员函数?

c++ 将各种参数传递给父类构造函数(线程c++11)

python - 如何在Python中生成足够 'random'度的多个随机数

java - 需要对循环中的随机数中的数字求和

java - 在循环的限定比较中使用随机参数时,它是调用一次随机化函数还是每次循环运行时调用?

c++ - 如何修复以下 C++ 代码中的 C1202 错误?

c++ - 内存溢出? std::badalloc