生成随机数 - C++中的srand函数

3

我在使用srand时遇到了麻烦。

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

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

因此,我需要一个种子,无论我尝试什么,似乎都无法使其正常工作。

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

更新

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

每个火车的车厢数量需要在100到200之间随机。

每个车厢中的煤量需要在1000到2000之间随机。

我正在尝试实现一个模拟器类,它将创建一个具有随机车厢数量和包含随机数据量的火车。

希望这更加清晰明了。

我在如何实现上遇到了困难。


1
如果您需要再次使用相同的序列,何必再次调用该函数呢?在第一次调用时将其存储在容器中并重复使用即可。 - Mahesh
2
发布你所拥有的相关代码部分,有人应该能够修复任何不起作用的部分。 - Mat
3个回答

2
如果你只想重复一个任意的序列,可以使用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
@sehe,对于大多数目的来说,这已经足够接近了,只是 int 范围的顶端会稍微偏移一些结果,因为该范围通常不是 101 的精确倍数。无论如何,那只是一个“示例”,问题与如何重现运行有关,而不是提供完美分布的样本。 - paxdiablo

1
尝试这个。
void srand ( unsigned int seed );

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

1

如前所述,您可以通过使用相同的种子多次对 srand 进行播种。

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);

请参阅Julienne Walker的Eternally Confuzzled文章以获取更多背景信息,也可以了解种子

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);

一个即时的优势是,您可以同时拥有多个引擎生成相同的序列(请参见示例)。

正如您所看到的,您也可以像使用srand一样对生成器进行种子设置,例如:engine(1234)。 在以下网址上查看示例实时效果:

  • C++03 与 boost: 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(); // 更方便的使用
    

1 如果你使用C++03,可以使用Boost.Random库。


我重写了我的答案,因为一个完美的答案得到了负评。我猜我没有很好地传达信息。我希望我的编辑有所帮助。 - sehe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接