首页 > 解决方案 > 为什么我用不同的种子得到相同的数据?

问题描述

出于某种原因, seed=0 和 seed=1 给出了相同的结果,而我希望它会有所不同。

对于不同的结果,一切都按预期工作,问题仅出现在 0 和 1 种子。

这是一个错误还是我不明白什么?

复制代码。我在 gcc 和 g++ 编译器上尝试过。

#include <vector>
#include <random>
#include <stdint.h>

int main()
{
  int32_t length = 100000;
  
  //first generated data 
  uint32_t seed1 = 0;
  std::default_random_engine generator1;
  generator1.seed(seed1);
  std::uniform_int_distribution<int8_t> distribution1(0, 1);

  std::vector<int8_t> sequence1(length);

  for (int32_t i = 0; i < length; i++) {
    sequence1[i] = distribution1(generator1);
  }

  // second generated data
  uint32_t seed2 = 1;
  std::default_random_engine generator2;
  generator2.seed(seed2);
  std::uniform_int_distribution<int8_t> distribution2(0, 1);

  std::vector<int8_t> sequence2(length);

  for (int32_t i = 0; i < length; i++) {
    sequence2[i] = distribution2(generator2);
  }


  //check if data the same
  bool sameData = true;
  for (int32_t i = 0; i < length; i++) {
    if (sequence1[i] != sequence2[i]) {
      sameData = false;
    }
  }
  
  std::cout << sameData; // true, but should be false
}

标签: c++std

解决方案


通常与 gcc 一起提供的 libstdc++ 定义std::default_random_enginestd::linear_congruential_engine<uint_fast32_t, 16807UL, 0UL, 2147483647UL>. 源代码链接:

请注意,此引擎是所谓的“Lewis、Goodman 和 Miller 的经典最小标准 rand0”。该引擎在本文中有所描述:https ://www.researchgate.net/publication/220420979_Random_Number_Generators_Good_Ones_Are_Hard_to_Find 。

在里面,您可以在第 1195 页找到它的算法。请注意该论文中的以下引用:

这个生成器必须通过为种子分配一个 1 到 2147483646 之间的值来初始化。......不幸的是,对于大多数系统,这个版本的 Random 存在致命缺陷

种子值 0 因此甚至不满足这个要求。


推荐阅读