【问题标题】:Why is rand giving me almost identical (but slightly different) numbers each time为什么 rand 每次都给我几乎相同(但略有不同)的数字
【发布时间】:2020-02-11 18:12:10
【问题描述】:

我写了下面一段代码在c++中生成随机数

#include <stdlib.h>
#include <iostream>
#include <ctime>

#define ARRAY_SIZE 5
#define MAX_VAL ARRAY_SIZE*5+1

int main() {
  srand(time(NULL));

  int arr [ARRAY_SIZE];
  for (int i = 0; i < ARRAY_SIZE; i++) {
    arr[i] = (rand() % MAX_VAL);
  }

  for (int i = 0; i < ARRAY_SIZE; i++) {
    printf ("%d\n", arr[i]);
  }

  return 0;
}

当我运行它时,我每次都会得到几乎相同的数字:

tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
11
16
16
21
16
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
21
11
21
11
6
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
6
6
1
16
6
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
16
1
16
6
21
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
1
21
21
11
21
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
1
21
21
11
21
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
11
16
1
1
11
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
11
16
1
1
11
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
21
1
6
6
1

为什么我的随机数生成器只给我以下值:1、6、11、16 和 21?这对我来说毫无意义。我确保播种它并且数字并不总是以相同的顺序排列,这使得这更加令人困惑。作为旁注,我使用的是 OSX。

【问题讨论】:

  • 这是因为rand() 是垃圾。不要使用它。使用实际有效的C++ random number generators
  • rand() 是垃圾,但这不是原因
  • 停止在新代码中使用srand/rand。使用<random> 标头中提供的现代设施。另见rand() Considered Harmful
  • (rand() % MAX_VAL) 引入了偏见,除非MAX_VAL 可以完美地划分为RAND_MAX
  • @idclev463035818 是的,但#define 也是垃圾,如果可以避免的话,也与 C++ 代码无关。

标签: c++ random random-seed


【解决方案1】:

问题在于MAX_VAL 被定义为ARRAY_SIZE*5+1,而不是(ARRAY_SIZE*5+1)。这意味着您在arr[i] = (rand() % MAX_VAL); 中的使用扩展为:

arr[i] = (rand() % 5 * 5 + 1);

选项并不多(只有 5 种可能性),这就是您看到相同数字的原因。您可以通过将MAX_VAL 的定义括起来或将其设为常量变量来解决此问题:

const unsigned int MAX_VAL = ARRAY_SIZE * 5 + 1;

次要问题是srand(time(NULL)) 的使用。在大多数系统上,如果程序在同一秒内运行,time 将返回相同的值。这意味着快速连续运行程序(在同一秒内)将产生相同的结果。最好使用&lt;random&gt;中的PRNG工具。

【讨论】:

    【解决方案2】:

    这是因为你使用了#define MAX_VAL

    实际计算为rand() % 5 * 5 + 1,也就是说,你先将rand()结果与5取模,然后乘以5,再加1。

    我假设你的意思是写rand () % (5 * 5 + 1) 可以通过以下方式解决:

    #define MAX_VAL (ARRAY_SIZE * 5 + 1)
    

    【讨论】:

      【解决方案3】:

      其他人已经指出了这段代码中的两个主要问题,但值得在这里展示 C++ 的做事方式以进行对比,并摒弃最初破坏这段代码的许多 C 思维。

      此代码的 C++ 版本通过使用 C++ 拥有和 C 缺乏的功能来回避这里的许多问题:

      #include <random>
      #include <vector>
      #include <iostream>
      
      int main() {
        // Define constants instead of using #define, as this avoids interpolation syntax issues
        const size_t array_size = 5;
        const int max = array_size * 5 + 1;
      
        // Use the C++ random number generator facilities
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<> dis(0, max);
      
        // Use a dynamically sized array
        std::vector<int> arr;
      
        for (int i = 0; i < array_size; ++i) {
          arr.push_back(dis(gen));
        }
      
        // Use C++ container iteration to simplify code
        for (const int& i : arr) {
          // Use streams for output
          std::cout << i << std::endl;
        }
      
        return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-11
        • 2020-10-17
        • 2012-03-16
        • 2021-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多