这是获取随机数的好方法吗?如果不是,为什么?

j. *_*doe -3 c++ random

所以我试图创建一个"真正的"随机函数,因为兰德不够随意imo.

您是否认为获得随机数是一种"好"方式?如果不是,为什么?

int realrand() {
  double duration = 0;
  int i = 0;
  std::clock_t start;
  start = std::clock();

  while(duration < 0.001) {
    i++;
    duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;
  }

  int rand = i % 10;

  return rand;
}
Run Code Online (Sandbox Code Playgroud)

Bil*_*nch 7

两件事情.

  1. 您的随机数生成器非常慢.

    计算C++ 11和C样式rng 10000次在我的笔记本电脑上大约需要0.016秒.将代码添加到混合中会将成本提高到10秒!

  2. 您正在创建的随机数的分布很糟糕.

             You        C++11      rand()
    
    0:       9615       9007       9006
    1:       9143       9086       9008
    2:       8650       8929       8958
    3:       7907       9094       9114
    4:       7943       9022       9021
    5:       8098       8968       9005
    6:       8676       8991       8810
    7:       9970       8946       8903
    8:      10061       8908       9094
    9:       9938       9050       9082
    
    Run Code Online (Sandbox Code Playgroud)

    让我们用直方图显示这些数据.请注意,C和C++实现在每个存储桶中具有大约相同数量的元素.另一方面,您的代码显然更喜欢输出0,7,8或9.

上述数据的直方图

这是我用来确定这个的一些代码:

#include <random>
#include <map>

int realrand() {
        double duration = 0;
        int i = 0;
        std::clock_t start;
        start = std::clock();

        while(duration < 0.001) {
                i++;
                duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;
        }

        int rand = i % 10;

        return rand;
}

int cpprand() {
        static std::random_device rd;
        static std::mt19937 rng(rd());
        static std::uniform_int_distribution<> dist(0, 9);
        return dist(rng);
}

int crand() {
        static int once = []() {
                srand(time(NULL));
                return 0;
        }();

        return rand() % 10;
}

int main() {
        std::map<int, int> realrand_distribution;
        std::map<int, int> cpprand_distribution;
        std::map<int, int> crand_distribution;

        for (int i=0; i<10000; ++i) {
                realrand_distribution[realrand()]++;
                cpprand_distribution[cpprand()]++;
                crand_distribution[crand()]++;
        }

        for (int i=0; i<10; ++i) {
                printf("%d: %10d %10d %10d\n", i, realrand_distribution[i], cpprand_distribution[i], crand_distribution[i]);
        }
}
Run Code Online (Sandbox Code Playgroud)

这是我用来生成直方图的代码:

import numpy
import pylab

x = numpy.arange(10)
width = 0.27

rects1 = pylab.bar(x+0*width, [9615, 9143, 8650, 7907, 7943, 8098, 8676, 9970, 10061, 9938], width, color='r')
rects2 = pylab.bar(x+1*width, [9007, 9086, 8929, 9094, 9022, 8968, 8991, 8946, 8908,  9050], width, color='b')
rects3 = pylab.bar(x+2*width, [9006, 9008, 8958, 9114, 9021, 9005, 8810, 8903, 9094,  9082], width, color='g')
pylab.legend([rects1, rects2, rects3], ["You", "C++", "C"])
pylab.show()
Run Code Online (Sandbox Code Playgroud)