【问题标题】:random numbers not so random随机数不那么随机
【发布时间】:2012-04-24 01:25:37
【问题描述】:

我在一个类中有一个方法如下...

class foo{
   int bar::randomNum10to50(){
      srand (time(NULL));
      int random10to50 = rand()%50+10; 
      return random10to50;
   }
}

但是当我从 main 调用它时(只是为了检查输出,因为我没有从我期望的程序中得到行为)就像这样......

foo create;
for (int i=0; i<20;i++){
    cout<<create.randomNum10to50()<<endl;
}

每次运行时都是完全相同的数字(即,9,9,9,9,9,....;下一次运行:43,43,43,43,......)我不知道不知道出了什么问题。 代码运行得非常快,所以我认为这可能是问题所在,但我不明白为什么它的 20 次迭代之间没有任何差异。任何想法表示赞赏!谢谢!

【问题讨论】:

  • "9,9,9,9,9" 是一个“错字”,对吧?我只是想知道,因为你应该只得到 10 到 50 范围内的结果..

标签: c++ random


【解决方案1】:

你需要调用srand()一次在随机化函数之外。否则,您每次都使用完全相同的时间值重新播种随机数生成器,从而产生相同的初始“随机”值。

【讨论】:

    【解决方案2】:

    您在每次循环迭代时使用相同的种子调用srand(),因为时间实际上并没有时间改变。确保只调用一次,一切正常。

    【讨论】:

      【解决方案3】:

      Cody Gray 已经在这里说明了你做错了什么,但这里有一个使用 &lt;random&gt; 库的示例:

      #include <random>
      
      std::mt19937 make_seeded_engine() {
          std::random_device r;
          std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
          return std::mt19937(seed);
      }
      
      class foo {
         std::mt19937 engine;
      
      public:
         foo() : engine(make_seeded_engine()) {}
      
         int randomNum10to50(){
            return std::uniform_int_distribution<>(10,50)(engine); 
         }
      };
      
      foo create;
      for (int i=0; i<20;i++){
          cout << create.randomNum10to50() << '\n';
      }
      

      请注意,rand()%50 + 10 产生的数字在 10 到 59 之间,而不是 10 到 50 之间。uniform_int_distribution 更好,因为你给它的范围就是你得到的范围,所以你不太可能把它搞砸。同样使用 uniform_int_distribution 可以得到无偏见的结果,而 rand()%50+10 有一些轻微的偏见。


      如果你有一个支持更多 C++11 的编译器,你可以这样做:

      class foo{
         std::mt19937 engine = make_seeded_engine();
      
      public:
         int randomNum10to50(){
            return std::uniform_int_distribution<>(10,50)(engine); 
         }
      };
      

      【讨论】:

      • 不错!谢谢!我可能最终会使用它。好资料!
      • 请注意,您的编译器需要支持 C++11 才能执行此操作,否则您可以使用我相信 &lt;random&gt; 来自的 boost。
      • @AJG85 是的,它使用了一些 C++11,但我小心地将其限制在广泛支持的范围内。早在 4.5 的 VS11 和 gcc 就可以运行它。但我想我会添加一个使用更多 C++11 的版本来稍微清理一下......
      • 实际上从 VC10 开始,但仍然值得注意,因为我知道人们仍在使用 VC6。
      • @AJG85 啊,整洁。我原以为 random_device 直到 11 点才出现。无论如何,VC6 甚至算不上 C++ 编译器。我听说编译任何语言都很快; )
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-01
      • 1970-01-01
      • 2012-04-01
      • 2012-10-04
      • 1970-01-01
      • 2012-01-27
      • 1970-01-01
      相关资源
      最近更新 更多