【问题标题】:generating random numbers - srand c++生成随机数 - srand c++
【发布时间】:2011-10-06 07:45:07
【问题描述】:

我在使用 srand 时遇到问题。

我正在尝试生成一个介于 100 到 200 之间的随机数。

数字将不断生成并放置在一个数组中。一旦再次调用该方法,就需要再次生成相同的随机数序列。

因此,我需要一粒种子,无论我尝试什么,似乎都无法让它发挥作用。

我不是在寻找任何人来编写一些代码,而只是向我展示生成此类数字的正确格式。

更新

我有一个火车对象,其中包含一个链表(行表中的每个位置都是一个马车)。

每列车厢的车厢数量需要在100、200区间内随机。

每节车厢的煤量需要在1000、2000区间随机。

我正在尝试实现一个模拟器类,该类将创建一列随机数量的车厢,其中包含随机数量的数据。

希望这更有意义。

苦于如何实现它。

【问题讨论】:

  • 如果再次需要相同的序列,需要再次调用该函数。只需在第一次调用时将其存储在容器中并重复使用即可。
  • 发布您拥有的代码的相关部分,有人应该能够修复任何不工作的地方。

标签: c++ random srand


【解决方案1】:

如果您只想重复任意序列,您可以通过给它相同的参数来使用srand() 设置种子。

例如:

pax$ cat qq.c
#include <iostream>
#include <cstdlib>

int main (void) {
    srand (42);
    for (int i = 0; i < 5; i++) {
        int x = 100 + (rand() % 101);
        std::cout << x << std::endl;
    }
    std::cout << "=====" << std::endl;
    srand (42);
    for (int i = 0; i < 5; i++) {
        int x = 100 + (rand() % 101);
        std::cout << x << std::endl;
    }
    return 0;
}

pax$ g++ -o qq qq.cpp ; ./qq
163
166
148
137
149
=====
163
166
148
137
149

【讨论】:

  • 这不会导致随机分布
  • @sehe,它对于大多数用途来说已经足够接近了,它只是 int 范围的顶端,它会非常轻微地扭曲结果,因为该范围通常不是 101 的精确倍数。在任何情况下案例,这是一个示例,问题与如何重现运行有关,而不是提供完美分布的样本。
【解决方案2】:

试试这个

void srand ( unsigned int seed );

如果种子设置为 1,则生成器将重新初始化为其初始值,并生成与调用 rand 或 srand 之前相同的值。

【讨论】:

    【解决方案3】:

    如前所述,您可以通过用同一种子多次播种来进行散播。

    srand(1234); // magic number
    
    // .... 
    
    srand(1234); // magic number again
    

    rand() 的输出将从之前的相同点重新开始。

    当您使用它时,我建议不要在 rand() 上使用模运算符,因为它不会导致值的均匀分布。相反,您可以使用以下帮助程序来获取整数范围内的随机值:

    int randRange(int M, int N)
    {
         // see http://eternallyconfuzzled.com/arts/jsw_art_rand.aspx
         return M + rand() / ( RAND_MAX / ( N - M ) + 1 );
    }
    
    int nextrand = randRange(100,200);
    

    请参阅链接的article on Eternally Confuzzled(Julienne Walker)了解更多背景信息,以及播种

    C++ 选项

    上面的缺点是生成完全是顺序的(你不能同时有两个随机生成器实例)。既然你是用 C++ 标记的,我们为什么不用它呢!

    你可以使用tr1或者c++0x/c++111uniform_int_distribution

    #include <random>
    #include <functional>
    
    std::uniform_int_distribution<int> distribution(100, 200);
    std::mt19937 engine; // Mersenne twister MT19937
    
    int nextrand  = distribution(engine);
    

    一个直接的优势是您可以让多个引擎同时生成相同的序列(参见示例)。

    您还可以看到,您可以像 engine(1234) 一样为生成器播种,就像使用 srand 一样。 现场查看示例:

    • 带升压的 C++03:https://ideone.com/FC4xm

      #include <boost/random.hpp>
      #include <boost/random/uniform_int.hpp>
      
      int main()
      {
          boost::mt19937 engine1(1234);
          boost::mt19937 engine2(1234);
          boost::uniform_int<> dist(100,200);
      
          for (int i=0; i<20; i++)
          {
               std::cout << dist(engine1) << " is equal to " << dist(engine2) << std::endl;
          }
      }
      

    • C++0x http://ideone.com/467Aj
      还演示了一点语法糖:

      auto generator = std::bind(distribution, engine);
      nextrand = generator(); // more convenient use
      

    1 Boost.Random 如果你使用 C++03

    【讨论】:

    • 我重写了我的答案,因为一个非常好的答案被否决了。我想我卖的信息不够好。我希望我的编辑有所帮助
    猜你喜欢
    • 2011-06-11
    • 1970-01-01
    • 1970-01-01
    • 2015-12-17
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    相关资源
    最近更新 更多